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

Vim Support #700

Open
dzhou121 opened this issue Jun 28, 2022 · 68 comments
Open

Vim Support #700

dzhou121 opened this issue Jun 28, 2022 · 68 comments
Labels
A-editor Area: editor, modal editing A-keymap Area: default key bindings C-feature Category: New feature or request

Comments

@dzhou121
Copy link
Collaborator

Currently Lapce only has implemented a very small set of Vim keys/features, mainly because I'm not a very powerful Vim user.

Feel free to comment on what Vim features you wish to support in Lapce.

@dzhou121 dzhou121 pinned this issue Jun 28, 2022
@MinusGix MinusGix added C-feature Category: New feature or request A-keymap Area: default key bindings A-editor Area: editor, modal editing labels Jun 28, 2022
@DakshG07
Copy link

change - c key.
Things like ciw, which iw selects the word and c changes it.
ctrl+c, which puts you back into insert mode
>> to indent

@DakshG07
Copy link

Those are just the ones I noticed within 5 minutes of opening the editor.

@lihe07
Copy link
Contributor

lihe07 commented Jun 30, 2022

ctrl+c = Esc
This will certainly help those people(like me) who are lazy to reach the ESC key

@dakata1337
Copy link
Contributor

dakata1337 commented Jun 30, 2022

  • Just like @DakshG07 said the i key.
    Can be combined with other keys.
    ci" will change eveything between "...".
    yi( will yank everything between (...).
    vi{ visual selection between {...}

  • Ctrl+ww to cycle between visible editor tabs.

  • Macros

@DaQueenJodi
Copy link

:w being an alias for :Save would be really nice

@mystchonky
Copy link

Buffer split commands like :sp and :vs
Substitute mode :s
Some popular plugins like vim-surround and vim-commentary (These don't need to make into lapce directly. They are better suited for external plugins but I am adding it here as plugin api is still in development)

lihe07 pushed a commit to lihe07/lapce that referenced this issue Jul 4, 2022
@lihe07 lihe07 mentioned this issue Jul 4, 2022
@ghishadow
Copy link
Contributor

• ctrl-w - – decrease split height by 1 line
• ctrl-w + – increase
• ctrl-w > – increase split width by 1 line
• ctrl-w < – decrease

@DakshG07
Copy link

In addition to @dakata1337 :
cit will change in tag.
Also, suggesting vim-surround functionality:
ysw” will surround the word with quotes.
ys, then motion, then tag.

@Nesaijn
Copy link

Nesaijn commented Jul 29, 2022

  • D to remove everything from cursor to end of line
  • C to remove everything from cursor to end of line and switch to insert mode
  • P like p but instead of inserting after the cursor P inserts before the cursor
  • S to remove the contents of the current line and switch to insert mode
  • ´rto replace the character under the cursor but do not change to insert mode (likes` does)
  • Ctrl+f to move one page forward (like currently PageDown)
  • Ctrl+b to move one page backwards (like currently PageUp)
  • Ctrl+d to move one half-page forward
  • Ctrl+u to move one half-page forward
  • text object selection like i and a (partially mentioned already). For more information see in vim :help text-object.
    examples with d as operator and i as the text object:
    di(, di) and dib to delete the text inside the parentheses where the cursor is in or on,
    di{, di} and diB to delete the text inside the curly-brackets where the cursor is in or on,
    dis to delete inner sentence
    dip to delete inner paragraph
  • t as a movement command to operate on text until the following character is met.
    Example: dt. to delete text until a . is met
  • . the command to repeat the last edit done
  • commands with : like search and replace
    :%s/foo/bar/g to replace all occurrences of foo to bar in the entire file
  • / for search in file

Also I really want to show my appreciation for the work you all do, because a text editor like Lapce is something that I was looking for, for a while. I really want it to see in a daily-drivable state, so please keep up the awesome work you guys already did! ❤️

@ThePerfectComputer
Copy link

} - jump to next paragraph (or function/block, when editing code)
{ - jump to previous paragraph (or function/block, when editing code)
% - move to matching character (default supported pairs: '()', '{}', '[]' - use :h matchpairs in vim for more info)
0 - jump to the start of the line
^ - jump to the first non-blank character of the line
$ - jump to the end of the line

@DakshG07
Copy link

Technically a plugin, but infinitely useful:
surround
cs({ replaces turns (this) to {this}
ds{ removes surround ({this} to this)
then ys, and then a motion, and then a character surrounds the word. for example:
ysiw( with cursor in this makes it (this).
if now i use cs} instead of cs{, it makes space: (this) to { this }
lastly, in visual mode, use S to add surround.
Surround uses enter to end a command, as you can also add html tags.
(ysiw<p> makes this become <p>this</p>)
Check out it's docs here.

@l-7-l
Copy link

l-7-l commented Aug 2, 2022

Use HJKL to move the cursor in the folder tree (CTRL/CMD + Shift E)

@med1844
Copy link

med1844 commented Sep 4, 2022

As a colemak + vim user, I wish there could be langmap (map hjkl to hnei) and easymotion. Full support of vimrc would be ideal to have.

@szbergeron
Copy link

It would be really helpful to be able to add command palette commands that execute an editor action, so :w would execute the w command which could be aliased to save the document. This could potentially be expanded into parameterized commands so things like :%s/a/b/g could be handled. Perhaps allow a Python API or similar that can define command functions? Or that can match a prefix and be given the command string to parse out itself (maybe calling other commands in the process, so % could be a command that passes specific buffer segments).

Vim has a lot of weird legacy decisions that influence how its commands behave, so allowing a flexible approach that users can tailor to their internal model of how it works would IMO be a good direction to go.

@infdivzero
Copy link

infdivzero commented Sep 11, 2022

colorcolumn

Maybe word wrap?

Regex search and replace

@benediktms
Copy link

using gU or gu in visual mode to change a string to upper or lower case respectively would be nice :)

@erf
Copy link

erf commented Sep 14, 2022

The dot operator . for repeating the previous operation is a big one for me.

Also c-w change the next word and c-b to change the previous word (in Normal mode).

@nullndr
Copy link

nullndr commented Sep 16, 2022

  • [{ inside a {} block, jump to the first {
  • [} inside a {} block, jump to the first }
  • di-c delete all text surrounded by c, excluding c
  • da-c delete all text surrounded by c, including c
  • ds-c delete the inner most c surroundings
  • dt-c delete until c, excluding c
  • df-c delete until c, including c
  • dh delete the previous character
  • dl delete the next character
  • ch delete the previous character and enters insert mode
  • cl delete the next character and enters insert mode
  • vap enters visual mode selecting the entire paragraph
  • vaw enters visual mode selecting the word under the cursor
  • vit enters visual mode selecting all content inside tag, excluding the tag
  • vat enters visual mode selecting all content inside tag, including the tag
  • vi( enters visual mode selecting all text inside () block
  • va( enters visual mode selecting all text inside () block, including ()
  • vib same as vi(
  • vab same as va(
  • vi{ enters visual mode selecting all text inside {} block
  • va{ enters visual mode selecting all text inside {} block, including {}
  • viB same as vi{
  • vaB same as va{
  • cs-a-b change the surroundings a with b
  • yi-c yank everything inside c, excluding c
  • ya-c yank everything inside c, including c

@NatanFreeman
Copy link

It would be useful to have the W, B and E commands. (Vim documentation on click)

@giluis
Copy link

giluis commented Sep 19, 2022

Use HJKL to move the cursor in the folder tree (CTRL/CMD + Shift E)

I believe this is plugin specific, not native vim functionality.
Nothing wrong with having plugin specific functionality, but J is actually a popular keymap in vim, it concatenates the current line with the line below it.

@giluis
Copy link

giluis commented Sep 19, 2022

targets.vim
: A very common plugin that adds additional text objects and movements.
cia: deletes function parameter/argument (it only works for comma separated, parentheses delimited arguments. might be worth it to use treesitter for this and make it more inclusive of other syntaxes)
cina: deletes the next function parameter/argument
cin): moves cursor inside nearest (...) and deletes the content.

replace.vim: Allows replacing of a text object with text from a register
Riw: replaces current word with contents of main register

Comment.nvim: Allows commenting a text object
gciw: comment current word with block comments
gcc: toggle comment in current line

Honorable mentions, but rather hard to implement: lightspeed and telescope

@fwip
Copy link

fwip commented Sep 19, 2022

Speaking as somebody who primarily uses vim, and wants "everything to be just exactly like vim please" (which is probably not your target demographic):

In order of usage for me, this is what I've noticed missing that I haven't seen in this thread so far:

  • ctrl-f, ctrl-b - scroll down/up
  • W, B, E - like lowercase counterparts, but treat every non-whitespace character as a contiguous word. e.g foo.bar.baz = 1 is 7 items to w, but 3 to W.

A word consists of a sequence of letters, digits and underscores, or a sequence of other non-blank characters, separated with white space (spaces, tabs, ). This can be changed with the 'iskeyword' option. An empty line is also considered to be a word.
A WORD consists of a sequence of non-blank characters, separated with white space. An empty line is also considered to be a WORD.

  • :s/foo/bar/ - regex replacement commands
  • ? - search backwards (note that this also reverses the directions of n and N)
  • r - replace a single character (e.g: rx to replace the char under the cursor with x`)
  • R - replace many characters (e.g: Rfoobar replaces the six characters starting at the cursor with foobar)
  • H, M, L - put cursor at top, middle, bottom of screen (respectively)
  • { } - move up/down a "paragraph" at a time

Of the ones already mentioned, c (change) is by far the hardest to adjust to not having.

@LarryTheFatCat
Copy link
Contributor

images

@jtbx
Copy link

jtbx commented Jan 13, 2023

gk, gj, g^ and g$ are probably the most important missing binds for me.

@KyleFontenot
Copy link

Didn't find # to work. and I'm surprised to have to discovered this that quickly.

@viktor-yakubiv
Copy link

I came with the question similar to @awilkins': is it reimplementing Vim motions just for reimplementing it in Rust or it really brings benefits? To me, integrating a library or the Vim itself sounds a reasonable solution.


Speaking of the original question, I would rather have full support but I don't know how much straightforward it is. I've check a PR, and have to agree with @DakshG07: the implementation seem to lack context in which Vim motions operate. Let me explain:

  • keystroke like ciw (read: change inner word) select the current word (going into both ways, excluding surrounding spacing characters) and execute change command, i.e. cuts the word into register and starts insert mode.

  • command like da( (read: delete a (-block) selects the closest block surrounded by parentheses including them and deletes it.

I find those kind of keystrokes important for my productivity and noticed that many people find them very helpful too.


In general, Vim motions follow the following structure: [N][command][M][motion]:

  • N – number of repeating for the command
  • M – count of repeating the motions
  • command — one of d (delete), c (change), i (insert), a (append) etc.
  • motion – one of j (down), l (right), w (word), aw (a word) etc.

When both N and M are present, the command is executed N×M times. This exists due to the fact that both command and motion accept quantifier:

  • you might want to go 10 lines down just typing 10j in command mode
  • you might want to delete 5 next lines typing 10dd (repeated command works as line)

Vim motions are straightforward having this structure in mind, they are very well explained in the documentation. On the linked page, commands and motions are broken down into logical pieces.

The biggest problem I see at the moment is that motions are highly configurable. This is important for people who use different keyboard layout such as Dvorak, Colemak, Workman, any other or even a custom one, but want to preserve natural motions. For example, a Colemak user might want to replace j with n to keep the same button for a navigation motion. Vim solves this with keymap and langmap. However, Vim also allows remapping keys one by one preserving functionality.

I hope, these links and explanations are any helpful. I admire Lapce and work of all its contributors 🙂

@panekj
Copy link
Collaborator

panekj commented Mar 5, 2023

To me, integrating a library or the Vim itself sounds a reasonable solution.

What that library is supposed to do?

@viktor-yakubiv
Copy link

What that library is supposed to do?

Operate modal commands and motions, literally in a way that Vim does it. I am referring to libvim that @awilkins mentioned.

I am sorry if I suggest a nonsense, I don't know how much of a hassle is integrating C++ library into Rust.

@panekj
Copy link
Collaborator

panekj commented Mar 5, 2023

My problem with people who suggest "just use library X" or "just run X with lapce" is that they don't know how much work we would have to do to rewrite keymapping, actions and the core of the editor to fit or at least allow the model of such a library or program, just for the sake of using it, and what the implications would be for editor performance, API dependency, code complexity and distribution.

I am sorry if I suggest a nonsense, I don't know how much of a hassle is integrating C++ library into Rust.

This is not about language. Although it is a factor.

@viktor-yakubiv
Copy link

@panekj I see you point, thank you for explaining this 🙂

I think, it might be worth defining to what extent Lapce should support Vim commands in general. I can guess that the work towards supporting external library is somewhat comparable to work towards supporting (more/other/all) motions. A scope definition and a roadmap might help with this.

@NyanHelsing
Copy link

If you're gonna state built in vim support on the lapce.dev site, and not actually support this stuff ppl will think it's misleading.

@NyanHelsing
Copy link

NyanHelsing commented Apr 13, 2023

i have stuff in my config like n+> to indent n tabstops, yiw, ciw, diw, ci", ci', di" are all conspicuously absent; these are meat and potatoes for vim, and get used probably multiple times a minute for a lot of vim users. like more often than ctrl-c and ctrl-v are used in ms Word

@jtbx
Copy link

jtbx commented Apr 13, 2023

I don't think it would be realistic to implement every single Vim feature inside of Lapce, so I'm currently just using Vim.

@Bruce-Hopkins
Copy link

Markers are important to me. Especially markers that work between files.

@panekj panekj unpinned this issue Jun 2, 2023
@panekj panekj pinned this issue Jun 6, 2023
@boardfish
Copy link

I've noticed that the c command is not a MotionMode command like others, so it's not possible to use c2w, for example.

@DakshG07
Copy link

Alright, this is probably going to be really tough, since you'd pretty much have to re-architect most of the codebase, which is why it's nothing but a thought.

In the perfect ideal world, the editing interface itself would swappable. As in, the default lapce editing could be a module, but then you could also remove that and plug in a neovim module, or a helix module, a kakoune module, or really even a custom module.

Of course, I can't really speak here, I have no idea how tough that would be. Would probably be a nightmare to implement.
Just a thought.

@NyanHelsing
Copy link

Alright, this is probably going to be really tough, since you'd pretty much have to re-architect most of the codebase, which is why it's nothing but a thought.

In the perfect ideal world, the editing interface itself would swappable. As in, the default lapce editing could be a module, but then you could also remove that and plug in a neovim module, or a helix module, a kakoune module, or really even a custom module.

Of course, I can't really speak here, I have no idea how tough that would be. Would probably be a nightmare to implement. Just a thought.

This seems totally unrelated to supporting the commands and keyboard shortcuts that vim supports.

Furthermore, Lapce is already architected such that there's a frontend (ui) and backend (lsp, filesystem, plugins, etc) which are separate components. the issue with this suggestion isn't so much whether its possible to put slap a different ui into lapce, as much as is the entire benefit of lapce and what makes it fast IS the frontend; (lapce-data) which is where all the rope stuff is. putting a different frontend defeats the entire point of lapce in the first place.

@erf
Copy link

erf commented Jun 29, 2023

Alright, this is probably going to be really tough, since you'd pretty much have to re-architect most of the codebase, which is why it's nothing but a thought.

In the perfect ideal world, the editing interface itself would swappable. As in, the default lapce editing could be a module, but then you could also remove that and plug in a neovim module, or a helix module, a kakoune module, or really even a custom module.

Of course, I can't really speak here, I have no idea how tough that would be. Would probably be a nightmare to implement. Just a thought.

If the lapce keybinding would support various modes it would be perhaps be possbile to emulate other editor modes like kakoune / vim etc. but not sure how flexible this is at the moment.

@squalou
Copy link

squalou commented Jul 28, 2023

My 2 cents here :

"search to " /<char>
and "delete to " d/<char> are what I miss the most form vim in any other editor

I also miss search and replace but that should be covered by a search&replace feature, not vim-like specific thing.

@yanorei32
Copy link

yanorei32 commented Aug 28, 2023

ctrl+a ^A, ctrl+x ^X commands in normal mode:
numeric addition/subtraction for the following numeric literal.

ctrl+u ^U commands in insert mode:
delete the characters before the cursor in line. (emacs like command)

ctrl+n ^N in insert mode then next auto-complete candidate.
ctrl+p ^P in insert mode then previous auto-complete candidate.
ctrl+y ^Y in insert mode then confirm the auto-complete candidate.

@akiradeveloper
Copy link

I found two lacking bindings

  • ctrl+f: page forward
  • ctrl+b: page backward

@thajohns
Copy link

thajohns commented Sep 10, 2023

A quick thing I noticed is that in the current implementation, cw is not atomic as far as u is concerned, which I believe is different from vi.

@thajohns
Copy link

I've also noticed that the lack of the other visual modes (line and block) has disrupted my usual workflow. And the missing :w is catastrophic.

@FRutkowski
Copy link

W, E, B - it works similiar to w, e, b but it stop only on places splited by space

@wurli
Copy link

wurli commented Jan 16, 2024

Why not use Neovim as a backend for vim mode? AFAIK, this is an expected (intended?) use of Neovim, so would seem sensible to capitalise on it. Here's a very good VSCode plugin which does something similar: https://github.com/vscode-neovim/vscode-neovim.

@panekj
Copy link
Collaborator

panekj commented Jan 16, 2024

@wurli #700 (comment)

@wurli
Copy link

wurli commented Jan 16, 2024

@wurli #700 (comment)

Ah, thanks, I missed that. But, I do think it's worth seriously considering, as the benefits would be significant. I've used vim motions in various editors, but haven't yet found anything that comes close to the speed or featureset of an actual vim backend. I find it hard to imagine that rebuilding vim would be an easier option, but I suppose that depends on how much feature parity you're seeking for.

@NatanFreeman
Copy link

Why not use Neovim as a backend for vim mode? AFAIK, this is an expected (intended?) use of Neovim, so would seem sensible to capitalise on it. Here's a very good VSCode plugin which does something similar: https://github.com/vscode-neovim/vscode-neovim.

Isn't Lapce trying to be a browser written in pure Rust? I feel like using neovim would undermine that. Unless I'm mistaken and non-Rust backends are used elsewhere anyway.

@ashishbista
Copy link

Support for vimrc files and vim plugins.

@josb
Copy link

josb commented Mar 15, 2024

~ (tilde) to toggle letter case.

@NyanHelsing
Copy link

NyanHelsing commented Mar 17, 2024

i've switched to neovide because its literally actually vim and solves my problems with using vim in the terminal; (scrolling is annoying) and issues i have with actual vim; eg no lsp etc.

can do stuff like :split +term to get a terminal like lapce (vs code, zed, ect) does now; posession is a nvim plugin that does session management so can reopen the same stuff after closing, etc.

I think overall lapce doesnt intend to support vim commands in a real way any time soon, and the benefits of ropes dont outweigh the negatives of the change in ergonomics.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-editor Area: editor, modal editing A-keymap Area: default key bindings C-feature Category: New feature or request
Projects
None yet
Development

No branches or pull requests