Giter VIP home page Giter VIP logo

Comments (25)

jordwalke avatar jordwalke commented on May 10, 2024 2

Long-term, my vision for this project is to make modal editing through neovim more friendly and attractive to users of VSCode/Atom/etc,

Where do I sign?

from oni.

bryphe avatar bryphe commented on May 10, 2024 1

Good point. I believe there would be an efficient way to invoke VimScript commands over the msgpack RPC API, and there's already an entry point via the neovim/node-client. Need to validate the latency though beforehand and make sure that it is actually efficient. Regarding efficiency, eventually it'd be nice to run some input benchmarks, like this article... There is definitely more typing latency in Oni than GVim at the moment for me at the moment, but that's sort of a tangent.

I like the idea of spitting out regular VimScript from json - things like inoremap/noremap could be emitted, so there wouldn't be any additional latency, and it would be relatively straightforward to implement. It gives us both the benefits of built-in performance and portability so that the config can still move freely. It also maps well to configuration options - moving some options like linenumbers, colorscheme, etc from init.vim to a configuration.json could be implemented in the exact same way.

This sounds like the direction we should move forward in - really gives us the best of both worlds.

This is great feedback, thanks for thinking about this!

from oni.

Bretley avatar Bretley commented on May 10, 2024 1

@extr0py 👍

That makes my life a bit easier when it comes to the vim <-> oni communication.

from oni.

jasonszhao avatar jasonszhao commented on May 10, 2024 1

Another consequence of the current architecture is that the accelerator option in Electron menus doesn't work.

I was playing with the source, and I was disappointed that adding the accelerator line doesn't do anything (this is modified from Menu.js):

{
    label: 'Undo',
    accelerator: 'CmdOrCtrl+Z',
    click: (item, focusedWindow) => executeVimCommand("u")
}

from oni.

keforbes avatar keforbes commented on May 10, 2024 1

@jasonszhao, I think that's a consequence of #223, due to the discussion in #216.

from oni.

bryphe avatar bryphe commented on May 10, 2024

Good question, it's just hard coded in a poor way right now. My initial thinking was to have a ~/.oni/keybindings.json, and create commands for these, like 'oni.menu.nextItem' with JSON bindings, and get to the point where 99% of the mappings could be done in the json file.

It does have the downside of having two places for bindings, and being foreign to power users. To bridge the gap, there are a few options I was thinking about:

  • Add a way to execute commands from VimScript, like: OniCommand("oni.menu.nextItem") that could be part of key mappings
  • Add some information about the UI state in VimScript, sort of like how pumvisible() works

Long-term, my vision for this project is to make modal editing through neovim more friendly and attractive to users of VSCode/Atom/etc, without having to dive into creating a _vimrc/init.vim... but still retaining much of the flexibility.

Thanks for calling out some ideas here and trying out the app, great to have your feedback!

from oni.

jordwalke avatar jordwalke commented on May 10, 2024

One thought: If there were an efficient way to invoke VimScript commands directly from JavaScript, then I'd be okay with half my configuration being in VimScript, and the other half being in JS because I know that I can eventually port my VimScript setup to JavaScript (including keyboard mappings).

Bonus: The JS configuration can be made to spit out regular VimScript, and then the configuration can be loaded directly from VimScript for better use in regular (non-Oni) Vim (which would also help keep startup performance fast - if computing the pure VimScript configuration ahead of time (and caching it)).

The result is that there would be a path to converting all your vimscript config/bindings to JS without any downsides.

from oni.

Bretley avatar Bretley commented on May 10, 2024

For keybindings then, would it be feasible to make a keybinding interpreter/generator so that people can choose to live in their configuration environment of choice? if there was a way to convert vim keybindings into the JSON/JS usable form and vice verse, people can live in their configuration environment of choice. For most people, it would probably be the init.vim, at least until oni attracts new users on its own.

from oni.

jordwalke avatar jordwalke commented on May 10, 2024

@bert88sta That's a good idea. I'd love to see some examples of what the bidirectional conversion might look like. One challenge is that there may be complex logic in determining what bindings are generated. For example, let's take the case where we use JS to configure via a file myKeyBindings.js

let something = reallyComplicatedExpression ();
let other = reallySlowExpression ();
module.exports = {
  'insertMode': {
     'ctrl-l': something,
     'ctrl-h': other
  }
};

The idea I had was that this file could use arbitrary JS expressions / dependencies to determine the keybindings. That isn't something that's easy to convert into VimScript. It's similar to how many are using CSS in JS. You could take this raw JS object that is returned and turn it into pure VimScript.

The benefit is that we can run myKeyBindings.js ahead of time, convert it to VimScript, and cache the result so that not only are not waiting on a JS engine at startup time. Furthermore, the resulting VimScript is more lightweight than the original myKeyBindings.js because none of the expressions are evaluated.

The same could be done of color schemes, and possibly many other forms of configuration.

When given the full power of the language (JS) to author configuration, it's very expressive and powerful, but it is then impossible to create a bidirectional mapping between VimScript and JS. However, if the results are rendered as regular VimScript, it makes the appeal of bidirectional mapping smaller. The generated VimScript config could work in any existing Vim configuration (even without NeoVim). Yes, it must be authored in JS, but it works in all versions of Vim, and works fast at startup time because all the expensive stuff has been precomputed.

I think it's worth Oni coming up with some conventions early on about which things must be precomputed, and which things can be computed at runtime/startup time. You can put a hard line in the sand that anything that blocks the initial rendering/config of Vim must not have huge JS dependencies or huge computations. That could help keep the "new window" operation blazing fast, while allowing more expensive plugins to be loaded lazily, and asynchronously. I feel it's important to get this right early on before people start making render blocking heavy plugins.

from oni.

Bretley avatar Bretley commented on May 10, 2024

@jordwalke

However, if the results are rendered as regular VimScript, it makes the appeal of bidirectional mapping smaller.

I don't follow.

from oni.

jordwalke avatar jordwalke commented on May 10, 2024

However, if the results are rendered as regular VimScript, it makes the appeal of bidirectional mapping smaller.

It's only my personal opinion, but if you can render to plain VimScript, then the desire to be able to convert from JS to VimScript, and from VimScript to JS seamlessly seems less appealing.
If you can render from JS to VimScript ahead of time, then you can always just convert any JS config to plain VimScript, so that it can play well with other non-Oni based Vims.

from oni.

Bretley avatar Bretley commented on May 10, 2024

A place to start might be comparing the output of :map to a list of oni keybindings and just looking for conflicts

from oni.

Bretley avatar Bretley commented on May 10, 2024

@extr0py : As a start, I'm going to implement actual variables for keys globally... where would I define this? in config.ts? Oni.d.ts?

Any help would be appreciated

from oni.

bryphe avatar bryphe commented on May 10, 2024

Thanks @bert88sta ! Are you thinking like the actual letter keys, or something higher level like commands?

If its the former, we could have a Keys enum that maps to the letter value. If it's the latter, I think we might need to introduce a new concept like 'Commandand reference it likeCommand.autoCompleteNext`.

For key handling, I'm picturing we'll have a couple pieces:

  1. A VIM-command like OniExecute that lets us run Oni-facing commands - like :OniExecute("editor.menu.next"). This means we can do things like imaps and nmaps and have them push back to our VIM layer.
  2. Have NeovimInstance listen for the OniExecute messages and emit them
  3. Have the 'Services' like Format, QuickOpen, etc listen to these commands and react (like send a ui action or something). Some of the existing concepts that are baked into index.tsx, like the menus or autocompletion, should probably get their own editor 'service' to manage the state

That's at least what I was thinking - hope that can help get you started. Thanks for looking at it!

from oni.

Bretley avatar Bretley commented on May 10, 2024

@extr0py : I was just thinking of this suggestion

  1. Generalize functions that do things consistently ( UI.genericNext() instead of UI.nextCompletion() or UI.nextFile etc..). By offloading the logic into some boilerplate functions, the index code gets cleaned up.

  2. Because of 1, we can have general-case keybindings, as well as cleaning up some of the logic in browser/src/index. If we got keybindings 1 to 1 with generic functions, we can avoid nasty unclear code and make people like json config since it will be simple.

As for the OniCommand thing, I'll get on that since (unlike TS) I can actually write vimL. Assuming it's efficient to use it, keeping neovim in charge of the things neovim does best is a pretty solid Idea.

from oni.

bryphe avatar bryphe commented on May 10, 2024

The generic functions sound great, makes sense to generalize those.

Regarding the command execution, this file is a good place to start:
https://github.com/extr0py/oni/blob/master/vim/core/oni-core-interop/plugin/init.vim

This is all the special interop logic - the extra things we send over the wire that Neovim doesn't send out of the box. So might be a good place to define that function.

from oni.

Bretley avatar Bretley commented on May 10, 2024

alright, so the question becomes how do we add the state info for neovim to get a hold of?
I made the OniExecute function and replaced the "keybinding" in index with one in the init.vim, but as of right now, vim can't know anything about the UI state.

from oni.

bryphe avatar bryphe commented on May 10, 2024

Hmm, ya, we could always send information down to the Neovim layer by executing a command (NeovimInstance has a command method that would be good for this). So we could notify Neovim when a menu is up, autocomplete is up, etc, and set some global variable, like g:oni_ui_menu or something.

We'd probably need to do the following:

  • Define a handler in the default's init.vim to listen for these commands
    • Populate some global variable
  • Call the handler from NeovimInstance.command when the UI state changes

That way, the Vim key bindings can apply depending on the oni state. I think it'd also be good to declare a general global variable like g:is_oni so that users could differentiate in their init.vim if they needed to

from oni.

kopischke avatar kopischke commented on May 10, 2024

I think it'd also be good to declare a general global variable like g:is_oni so that users could differentiate in their init.vim if they needed to.

Good idea, but the convention seems to be to respond to has('gui_<name>'): MacVim has gui_macvim, VimR has gui_vimr (see https://github.com/qvacua/vimr/wiki/VimR-MacVim, “Distinguishing VimR and MacVim in vimrc” section).

from oni.

Bretley avatar Bretley commented on May 10, 2024

@extr0py:

Is it safe to assume that there's only going to be one "list" up at a time? A.K.A there won't be multiple UI instances that require c-p to navigate simultaneously? If not this is going to be complicated and slow.

from oni.

bryphe avatar bryphe commented on May 10, 2024

@kopischke - good point, thanks! I opened issue #94 to track setting gui_oni to follow that convention.

@bert88sta - IMO, it would be a poor user experience to have multiple menus up, so we should avoid that. And it seems like it might also be unclear to the user what the result of might be in that case, so I don't believe there'd be a case to have multiple menus / list up at one time.

from oni.

jordwalke avatar jordwalke commented on May 10, 2024

Could someone summarize the overall architecture for vim keybindings? Is anyone else concerned about impacting the gloriously fast startup time of Vim, by putting large, user configurable JS bundles in the critical load path? This is why I suggested that a more constrained approach be taken for a subset of editor functionality (colorschemes, key bindings, and syntax highlighting), which allows that configuration to compiled ahead of time to VimScript. I understand that no one wants to build that ahead of time converter right now, but it would be nice to take into account the architecture's future potential to be able to do such a thing. Namely - would it require a JavaScript interpreter to know which map commands to execute/send to neovim? I believe that we could even adopt Atom's keybindings json configuration scheme.

from oni.

badosu avatar badosu commented on May 10, 2024

@bryphe I guess this is done already, or is there anything to address on this issue?

from oni.

bryphe avatar bryphe commented on May 10, 2024

@badosu - sorry for the late reply! Just going through items now.

@bryphe I guess this is done already, or is there anything to address on this issue?

Yes, although we still have further work to refine our input model, I believe we can close this and tracking remaining issues.

I drafted up some of the motivation and architecture behind our current input model here: Architecture: Input Management, and we still have several issues tracking enhancements (chorded key bindings, more robust resolution, config improvements)

from oni.

bryphe avatar bryphe commented on May 10, 2024

I'll close this out, and we can continue to track the outstanding work in the other issues:

  • #1055 - chorded key presses
  • #1240 - pain points with binding
  • #1331 - cross platform issues

from oni.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.