| Summary: | [client] Controlled cursor movement for content assist | ||||||
|---|---|---|---|---|---|---|---|
| Product: | [ECD] Orion | Reporter: | Karol Gusak <karol> | ||||
| Component: | Editor | Assignee: | Mark Macdonald <mamacdon> | ||||
| Status: | RESOLVED FIXED | QA Contact: | |||||
| Severity: | enhancement | ||||||
| Priority: | P3 | CC: | bokowski, eclipse.felipe, mamacdon | ||||
| Version: | 0.2 | ||||||
| Target Milestone: | 0.3 M1 | ||||||
| Hardware: | PC | ||||||
| OS: | Linux | ||||||
| Whiteboard: | |||||||
| Attachments: |
|
||||||
|
Description
Karol Gusak
+1! Karol, would you be able to draft an API for this (or even prototype an implementation)? (In reply to comment #1) Yes, I plan to give it a try as soon as I need it for PHP content assist feature (however syntax highlighting and code validation are first on my list). I did some research about this feature recently. From what I was able to learn, the feature of controlled caret movement, as I call it, is called Linked Mode in desktop Eclipse and is implemented in org.eclipse.jface.text. There are two important classes. First, LinkedPositionGroup, which holds the information about group's offset and length (IRegion). There may be many regions stored in one group, which are then linked - a change in one region is automatically applied by the editor to other regions (it is used for refactoring in Eclipse). The second class is LinkedModeModel, which holds the LinkedPositionGroups. It allows to constrain the caret's position in the document and the editor uses information from this class to switch between groups on TAB key. To configure the Linked Mode for method's parameters' autocompletion, one need to instantiate as many LinkedPositionGroups containing one region (offset and length) each as there are parameters in the method. Then all these groups need to be added to a LinkedModeModel. And finally the object of LinkedModeModel is used by the editor, when it switches to Linked Mode. In this mode cursor "jumps" between LinkedPositionGroups on clicking TAB key. Typing any string replaces the content of the position group. Other events like moving the cursor outside of the group (using mouse or keyboard) turn the Linked Mode off. Also in the Linked Mode the position groups should be visually highlighted in the editor. From the perspective of content-assist functionality, the contentAssist.js would need to be modified. Currently it just expects an array of string completions from a plugin connected to its extension point. However it should also expect (for each completion) an optional array of parameters, each containing a parameter's name at least, so the offset and length can be computed. Then the contentAssist.js will be able to configure the Linked Mode using the classes described above. I'm going to try to provide a prototype implementation of described functionality. From what I know implementing the Linked Mode support in the editor would require many modifications in textView.js. I doubt I can come up with anything useful as it's the very core part of the Orion, but I'll experiment with it next week. (In reply to comment #3) > I'm going to try to provide a prototype implementation of described > functionality. From what I know implementing the Linked Mode support in the > editor would require many modifications in textView.js. I doubt I can come up > with anything useful as it's the very core part of the Orion, but I'll > experiment with it next week. I would implement linked mode in editorFeatures.js, on top of the API in textModel.js - no need to change textView.js. Take this with a grain of salt though - I haven't implemented it so I could be completely wrong. (In reply to comment #4) > I would implement linked mode in editorFeatures.js, on top of the API in > textModel.js - no need to change textView.js. Take this with a grain of salt > though - I haven't implemented it so I could be completely wrong. Thank you for this helpful notice! It was very true. I managed to prepare some prototype for the Linked Mode functionality discussed in this ticket. Anyone can test it on my oriondemo installation: http://bit.ly/pFoK0v (login: demo, pass: orion) When you trigger the content assist and choose one of the proposals (please use enter and not mouse-click), and if it's a method with parameters, the Linked Mode is activated. First parameter is automatically selected and you can traverse through the parameters using TAB key (it's cyclic). Clicking ENTER or ESC (or typing anywhere outside of the parameters' positions) will escape the Linked Mode. I'm attaching a patch to this ticket. It modifies editorFeatures.js (more precisely the SourceCodeActions) - the basic Linked Mode functionality - and contentAssist.js - the usage of it. I've placed pretty extensive comments in the patch with details, so I think it's not needed to repeat much of it here. The object's structure for configuring Linked Mode is modeled after LinkedModeModel from desktop Eclipse, but of course simplified. In general I tried to place everything in editorFeatures.js as opposed to contentAssist.js. But because the enter action for content assist is handled in editorFeatures.js, and the mouse-click action in contentAssist.js, the Linked Mode is not being set up for the latter (as editorFeatures.js uses contentAssist.js already, I didn't want to add the opposite dependency). Created attachment 199375 [details]
A patch to add simple Linked Mode for Orion editor
(In reply to comment #5) I tried it out on your server. Very cool! Karol, can you confirm that you wrote all the code in the patch? We need to do this for legal reasons. You can post a comment here saying something like: > "I wrote all this code and have the rights to contribute it to Eclipse under the eclipse.org web site terms of use." There are a few things I'm going to change: 1. Shift+Tab should cycle backwards between positions when in Linked Mode. 2. "parametersPositions" in the proposal data structure can probably be renamed to "positions", for consistency with the Linked Mode model. 3. Mouse and Enter should behave the same, as you pointed out. (For this I'm going to refactor ContentAssist to just present and accept a proposal. The code in editorFeatures will handle applying the proposal (and potentially triggering Linked Mode, etc). This puts most of the logic in one place, and makes ContentAssist agnostic about the details of the Linked Mode position groups.) Item #2 will require a change to your content assist contributor (parametersPositions -> positions) but the rest should not. I'm glad my patch will come in handy :-). I wrote all this code and have the rights to contribute it to Eclipse under the eclipse.org web site terms of use. Please also note that in desktop Eclipse the cycling works differently, i.e. it also includes the caret exit position while cycling (I just didn't want to unnecessarily mess this prototype implementation). When I read the patch I noticed that when the editor is in linked mode it consumes "enter", "escape", and other keys. Maybe it makes more sense to implement linked mode using the "mode" framework from Susan ? See Bug 348823 http://git.eclipse.org/c/orion/org.eclipse.orion.client.git/commit/?id=b50a2d03f15c1decf5dc6845d4e2d06f7c242830 As Felipe suggested in Comment #10, I've refactored it into a full-blown mode. Also added enter() to the mode API, so I could separate out ContentAssist's Enter handling (accept proposal) from SourceCodeActions' Enter handling (auto-indent). |