I'd like to customise the way that Select/UnselectWordAtCaret work. In Clojure, Extend Selection is really great but it would be very useful to be able to extend the selection laterally to sibling forms too. The Clojure environment for Eclipse, CounterClockwise, supports this and it's really useful. The way this works there is that Alt-Up extends the selection as in IntelliJ, Alt-Left/Right extend it laterally, and Alt-Down undoes the last selection expansion. I'd like to mimic this behaviour for Clojure.
My plan is to add EditorActionHandlers for Select/UnselectWordAtCaret with priority first. These will delegate as normal when not editing Clojure. I'll also add new actions for ExtendSelectionLeft/Right. After these actions (extend left/right will use custom code, SelectWordAtCaret will delegate to the existing action) I'll push the new selections on a stack and store it somewhere. My UnselectWordAtCaret will simply pop the stack and return the selections to a previous state. I'll also add a SelectionListener, and invalidate the cache if the selection has been removed via editing, cutting or whatever.
- Does this seem like a valid way to achieve this?
- If so, where should I store the stack - on the editor? I'm guessing that the editor makes more sense than doing it on the PsiFile.
- In the listener, should I invalidate the stack when the number of new selections is zero, or just when it's less than the number of old selections?
- Are there any edge cases around multiple cursors I should be aware of here?
- My stack will have a collection of selection TextRanges, one per caret - should I use the Caret instance to associate the selections with a particular Caret, and check if it's valid before restoring the selection? They don't seem to have any sort of ID.
Thanks for any advice!