zedapp / zed

Rethinking code editing.
http://zedapp.org
MIT License
2.22k stars 162 forks source link

Easymotion for Zed #477

Open farnoy opened 9 years ago

farnoy commented 9 years ago

Going away from vim, I think the one thing I miss is easymotion. Can we get something like this as a plugin? How hard would it be to implement such motions with optional gui support (for inputting the letter maybe)?

zefhemel commented 9 years ago

I think it wouldn't be trivial, but everything is possible. How do you have in mind this would work in the context of Zed which doesn't have the number prefix for commands?

farnoy commented 9 years ago

Maybe you press something like Ctrl+Q, an input menu rolls from the top (like the go-to, find, or anything), then you press a character you want to jump to and as soon as you do the input clears, highlights these characters on the screen and you write the code (again, no need to press Enter).

What do you mean about number prefixes? I don't think anyone uses easymotion like that.

farnoy commented 9 years ago

I tried doing it as an extension using zpm, but have failed.

Basically, I need to to obtain the current text that's visible and do some magic with the cursor, Ace has APIs for it (http://ace.c9.io/#nav=api&api=editor), so I tried exporting more API through my fork of Zed, but for some reason chrome does not refresh my local, unpacked extension.

The easiest thing would be to allow access to Editor/EditorSession from Ace, but requirejs from extensions fail when requesting ace code and I guess this is intended as it would be too permissive.

I'll try again tomorrow or sometime, but I'd love to get some advice/help on this.

nightwing commented 9 years ago

You could create this as an extension to Ace using approach similar to https://github.com/ajaxorg/ace/blob/master/lib/ace/search_highlight.js#L56 for drawing markers. Then Zed extension will only need to load Ace extension and enable it.

zefhemel commented 9 years ago

What @nightwing says is probably the best option, indeed.

farnoy commented 9 years ago

Finally got around to it. I managed to spawn a dialog of sorts and jump to the first occurrence. Now highlighting and the second "jump-to" step. Would like to get some feedback on this as I reused some code from other extensions and am unsure if this is the way to go.

https://github.com/farnoy/ace/blob/7335ad79ec3698abffeae0d52c864388ddcf05e2/lib/ace/ext/easymotion.js

farnoy commented 9 years ago

Also when I exit my dialog and refocus the editor the input gets forwarded from when it was blurred.

nightwing commented 9 years ago

I think overlay_page won't work well for this since it will cause problems with focus, better option is to add keyboardHandler

easymotionHandler = function(data, hashId, key, keyCode) {
    var editor = data.editor;
    if (keyCode == -1) return;    
    if (key.length > 1) {
      if (key == "space") key = " ";
      if (key[0] == "n") key = key.replace("numpad", "");
    }
    if ((hashId === 0 || hashId === 4) && key.length == 1) 
        return {command: "null", passEvent: true}; // wait until input event
     console.log(hashId, key)
     if (hashId == -1)  {
         // main part: handle user typed character here!
         return {command: "null"}
     } else {
         // some other key: exit easymotion mode
         easymotionCleanup()
         return {command: "null"}
     }
}

// in easymotionSetup do
editor.keyBinding.addKeyboardHandler(easymotionHandler)
editor.on("mousedown", easymotionCleanup)

// in easymotionCleanup
editor.keyBinding.removeKeyboardHandler(easymotionHandler)
editor.off("mousedown", easymotionCleanup)
farnoy commented 9 years ago

Thanks for the tip @nightwing, it works better now and I'm able to do a highlight similar to the "search" one now. I think I saw a way to provide a custom render function for the marker which is what I need next.

farnoy commented 9 years ago

Actually, is it okay if I modify this function to allow for an extra parameter: content and use it for innerText of the new tag?