Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Option to have more Vim key bindings in code editor #715

Closed
fozcodes opened this issue Nov 25, 2021 · 24 comments
Closed

Option to have more Vim key bindings in code editor #715

fozcodes opened this issue Nov 25, 2021 · 24 comments

Comments

@fozcodes
Copy link

Hey all,

I was wondering if there's any appetite for adding an option to have deeper Vim-like key bindings when editing. I personally have a lot of Vim muscle memory when typing into something that looks like a console. I find myself trying to navigate with my H,J,K,L or using things like Shift+I but that doesn't currently exist so I just make a mess 😄 .

I found this Monaco plugin: monaco-vim. I added it to a branch locally to test out and it works pretty well. This is just basically hard-coded though, so not a flexible implementation. Would anyone else be interested in having an option to enable this when using Livebook? If so, I could take a crack at a POC. There's certainly some discussion to be had around where the toggle would live and how to implement it properly. As well as some testing and consideration of edge cases (which I'm sure I'll discover as I use it more).

Either way, thanks to the team for Livebook. I love it. Such a superior and flexible product compared to Jupyter IMHO. ❤️

@josevalim
Copy link
Contributor

Hi @fozcodes! We have recently added a user configuration section in the settings page. So I would say we can have this as long as:

  1. it is opt-in in the settings page
  2. we only download monaco-vim if enabled in said page

WDYT @jonatanklosko?

@jonatanklosko
Copy link
Member

Hey! Sounds all good to me :) The only thing to figure out is to make sure that pressing Esc exits Vim insert mode first and only then Livebook insert mode.

Note: we need to wait for #640, so that we have the updated settings page.

@Benjamin-Philip
Copy link
Contributor

I think we should offer other key bindings, at least within monaco. Starting with Emacs.

We could then have some way of changing from CUA to Emacs or vim.

@josevalim
Copy link
Contributor

Honestly, if we are going in the direction we need to support Emacs, Vim, etc. Then I would rather support none because of the complexity that can arise from all different options. So this is going back in the shelf for now. Thanks!

@hoetmaaiers
Copy link

Did enough time pass by to think again about vim / emacs support?

The demo provided by Monaco-vim has a checkbox for vim or emacs mode. To me this is would be more than enough. Would this be seen as a potential complexity risk?

@josevalim
Copy link
Contributor

I think the biggest concern is the complexity in maintaining all different options and how certain key combinations would interact with Livebook. For example, Monaco-vim mentions CodeMirror and the CodeMirror home page says this:

Note: The CodeMirror vim bindings do not have an active maintainer. That means that if you report bugs in it, they are likely to go unanswered. It also means that if you want to help, you are very welcome to look at the open issues and see which ones you can solve.

We just don't want to end-up on the same situation.

@hoetmaaiers
Copy link

I understand the complexity between certain key combinations interacting with Livebook and others being vim shortcuts. Somehow the only shortcut from Livebook that I care about is the "evaluate" shortcut. But here comes the personal preference part which makes adding extra key shortcuts and preference related things hard I guess...

Thanks anyway for the quick response.

@FreedomBen
Copy link

I ended up here looking for a way to vim key bindings as well, but I understand not wanting to use a library that isn't maintained.

Something that would go a long way to ease the pain though, is a refresh shortcut or something in LiveBook that tells it to reload the current livebook from file. This way I can have a .livemd file open in vim locally for heavy edits, and when I want to try out changes I can Ctrl+r (or whatever) and the browser will reload from file.

I suspect that livebook currently expects nobody else to be changing those files because as far as I can tell it never re-reads the file. I just serializes the file to disk when a save event happens. If the file has been modified since, it gets overwritten with the current contents of the buffer.

Is this something we can consider? I'm happy to explain more, and open a new issue that describe the proposal a bit better.

@josevalim
Copy link
Contributor

I think reloading from file can be very problematic because it means two sources of truth. The only way to handle it properly is by then discarding all notebook state and I don’t think that’s helpful either.

@FreedomBen
Copy link

Yeah based on a very surface-level evaluation, that's exactly what would need to do (throw away notebook state and load from disk). I think it would be hard and error prone to try and figure out what the user wants. A key combination and/or button to "close and reopen from disk" that throws away all state and reloads would still be very useful for my case. I know if I edit the file that I need to close and reopen it, but it takes a number of steps because I have to close the session, open it again by navigating to the correct file, and then configuring the runtime to use mix (as it defaults to "Elixir standalone"). A one click/one keypress reload and reconnect to previously selected runtime would make a big difference. It doesn't look like it will be very easy to do though based on the way livebook is built.

Something that might be easier though, would it be hard to add the runtime info to the livemd file, similar to how we add <!-- livebook:{"persist_outputs":true} --> to save that setting? If we added something like:

<!-- livebook:{"runtime_settings":{"mix_standalone":"/path/to/project"}} --> 

A list of possible values to match the current settings might be:

<!-- livebook:{"runtime_settings":"embedded"} --> 
<!-- livebook:{"runtime_settings":"elixir_standalone"} --> 
<!-- livebook:{"runtime_settings":{"mix_standalone":"/path/to/project"}} --> 
<!-- livebook:{"runtime_settings":{"attached_node":{"name":"somename","cookie":"somecookie"}} --> 

That would be a nice feature in general and would also remove some of the pain with a use case like mine, because then I only have to close -> reopen, rather than close -> reopen -> reconfigure runtime

@jonatanklosko
Copy link
Member

@FreedomBen you can configure the default runtime when starting Livebook, either livebook server --default-runtime mix:/path/to/project or LIVEBOOK_DEFAULT_RUNTIME=mix:/path/to/project :)

Also, we changed the CLI a bit recently, so on Livebook main you can do livebook server /path/to/notebook.livemd and it opens, so one trick would be modifying the file, starting Livebook like that to open the file, kill Livebook and edit again. Still a workaround, but if you want to do this, I'm just throwing more options :)

FTR this is related #42, we may explore it at some point, but not a priority right now.

@FreedomBen
Copy link

Thanks @jonatanklosko ! That's quite helpful (the default runtime, the new CLI option, and the note to #42 which is def a dup of what I'm saying :-)

@logicmason
Copy link

FWIW, I only use editors with vim bindings because I suffered RSI problems in my wrist and index fingers several years back and vim + dramatically curtailing mouse/trackpad usage was a key part of the recovery.

If there are no vim (or similar modal) bindings, I'm pretty much shut out from LiveBook on a regular basis and that's disappointing.

@goto-engineering
Copy link

Would also really appreciate a way to get vim bindings in there. Maybe make it so I can install a plugin and it's my own responsibility, so you don't have to manage any complexity?
Spent 2 hours in Livebook yesterday and loved it, but typing in there is just... not as good as vim.

@josevalim
Copy link
Contributor

For those looking into this, I have seen this extension recommended for those who want (neo)vim in the browser: https://github.com/glacambre/firenvim

@Benjamin-Philip
Copy link
Contributor

I wonder if monaco has some settings.json equivalent like VS Code, or an init.el/ .vimrc equivalent similar to Emacs/Vim.
Maybe we could an implement one? That way we could support a lot of personalisation without requesting PRs on Livebook.

We could also optionally support the ace editor which already has vi and emacs keybindings built in.

@drselump14
Copy link
Contributor

drselump14 commented Jan 15, 2023

For those looking into this, I have seen this extension recommended for those who want (neo)vim in the browser: https://github.com/glacambre/firenvim

I tried this, but unfortunately, it's not working.
I found this issue in the Firenvim repo which mentions that the CSP prevents the script injection. See my updated comment below

glacambre/firenvim#1413

@drselump14
Copy link
Contributor

After some digging, it seems that exposing the global window.monaco object through webpack solves the issue.
I submitted the patch here #1642

@arijoon
Copy link

arijoon commented Jan 31, 2023

I wonder if we can implement the Liveview's UI as an editor extension, similar to Jupiter notebooks in vscode or intellij. Since lack of vim support is a deal breaker for me as well and the main reason I've not played with Livebook.

@josevalim
Copy link
Contributor

@arijoon you should be able to use firenvim above from Livebook v0.8.1.

@logicmason
Copy link

Despite being a VIM user (due to repetitive stress injuries) I'm not that familiar with firenvim (or similar browser extensions), but it's definitely not what I was looking for.

If Livebook aims to be accessible, it should just have first-class VIM bindings.

@arijoon
Copy link

arijoon commented Jan 31, 2023

Despite being a VIM user (due to repetitive stress injuries) I'm not that familiar with firenvim (or similar browser extensions), but it's definitely not what I was looking for.

If Livebook aims to be accessible, it should just have first-class VIM bindings.

firenvim seems to be rendering a vim window on a <textarea> so you can edit as normal and then save. Its not the best since you can't have easy shortcuts to move to different cells but its better than nothing. The ideal solution will either have to be a more modular UI for liveview so we can develop vim extensions, or Liveview UI in our editor instead of the browser. Personally I prefer the latter, I use Jupyter notebooks only in intellij and vscode (both of which have amazing vim emulations) and never in the browser

@josevalim
Copy link
Contributor

josevalim commented Jan 31, 2023

If someone is willing to investigate, we will be glad to consider exposing more hooks to make this a possibility. For example, we already expose monaco, so it should be possible for someone to hook into that and plug monaco-vim in. But keep in mind everything is open source and work made available for free for the community, and we are few with limited time, so please don't expect it to necessarily come from us. Therefore, if you believe vim support is essential to make Livebook accessible, contributions to provide necessary hooks is very welcome.

I will go ahead and lock the issue. PR #1642 is a great example of how we can expose bits here and there if necessary and we are open to similar PRs.

@livebook-dev livebook-dev locked as resolved and limited conversation to collaborators Jan 31, 2023
@josevalim
Copy link
Contributor

Sorry @arijoon, I didn't see your reply. Both routes should be good for us. I assume to run it inside editor, it runs like a regular web browser but perhaps with some hooks to plug the editor into the code cells? If folks want to explore this route, we will also be glad to learn what needs to be exposed to make it a possibility.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants