[vim/vim] Port the support for <Cmd> key in map commands to execute commands without changing modes from Neovim (#7282)

51 views
Skip to first unread message

Yegappan Lakshmanan

unread,
Nov 11, 2020, 1:46:42 PM11/11/20
to vim/vim, Subscribed

You can view, comment on, or merge this pull request online at:

  https://github.com/vim/vim/pull/7282

Commit Summary

  • Port the support for <Cmd> key in map commands to execute commands without changing modes from Neovim.

File Changes

Patch Links:


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or unsubscribe.

Bram Moolenaar

unread,
Nov 11, 2020, 2:23:41 PM11/11/20
to vim/vim, Subscribed

Unfortunately appears to fail on Mac, check Travis.

Yegappan Lakshmanan

unread,
Nov 11, 2020, 2:24:14 PM11/11/20
to vim/vim, Push

@yegappan pushed 1 commit.

  • bb09b71 Fix failure in Tiny build


You are receiving this because you are subscribed to this thread.

View it on GitHub or unsubscribe.

Bram Moolenaar

unread,
Nov 11, 2020, 2:26:50 PM11/11/20
to vim/vim, Subscribed

This text in map.txt isn't right "or an async event event was processed". "event" is doubled. And I suppose "async event" is a neovim thing.

Yegappan Lakshmanan

unread,
Nov 11, 2020, 2:36:48 PM11/11/20
to vim_dev, reply+ACY5DGGQW6E62AXOCQ...@reply.github.com, vim/vim, Subscribed
Hi Bram,

On Wed, Nov 11, 2020 at 11:23 AM Bram Moolenaar <vim-dev...@256bit.org> wrote:

Unfortunately appears to fail on Mac, check Travis.



Yes. I am looking into this test failure.

Regards,
Yegappan

Bram Moolenaar

unread,
Nov 11, 2020, 2:36:57 PM11/11/20
to vim/vim, vim-dev ML, Comment

Also in map.txt: "they must be followed by in the +{lhs} of the mapping definition." should be {rhs}.
It looks like this isn't checked at the time when the map is defined.
It also makes me wonder if must always come at the start of the {rhs}. What could come before this that makes sense?
And if it must always end in we could just check for it. Or could there be something following after the ?

In ex_getln.c a nested "if" is not needed, can use one "if" with "&&".


You are receiving this because you commented.

vim-dev ML

unread,
Nov 11, 2020, 2:37:05 PM11/11/20
to vim/vim, vim-dev ML, Your activity

Yegappan Lakshmanan

unread,
Nov 11, 2020, 3:19:14 PM11/11/20
to vim/vim, vim-dev ML, Push

@yegappan pushed 1 commit.

  • d131a56 Fix for test failure and fix typos


You are receiving this because you are subscribed to this thread.

Yegappan Lakshmanan

unread,
Nov 11, 2020, 4:21:51 PM11/11/20
to vim/vim, vim-dev ML, Push

@yegappan pushed 1 commit.

  • 3025c61 Fix test failure in normal builds without terminal


You are receiving this because you are subscribed to this thread.

Yegappan Lakshmanan

unread,
Nov 11, 2020, 10:20:14 PM11/11/20
to vim_dev, reply+ACY5DGGJZPFQLKAHQC...@reply.github.com, vim/vim, vim-dev ML, Comment
Hi Bram,

On Wed, Nov 11, 2020 at 11:36 AM Bram Moolenaar <vim-dev...@256bit.org> wrote:

Also in map.txt: "they must be followed by in the +{lhs} of the mapping definition." should be {rhs}.


I have changed this.
 

It looks like this isn't checked at the time when the map is defined.
It also makes me wonder if must always come at the start of the {rhs}. What could come before this that makes sense?
And if it must always end in we could just check for it. Or could there be something following after the ?

You can use a map like the following:

noremap <F3> aHello<Cmd>let x = 10<CR>World

When the <F3> key is pressed, it will insert the text, execute the command and
then continue inserting the rest of the text. So keys can be specified before
the <Cmd> pseudo key and after the <CR> at the end of the command.

In ex_getln.c a nested "if" is not needed, can use one "if" with "&&".


I have changed this.

BTW, I didn't port the following changes in edit.c from Neovim (as the
insert-mode completion code has changed). These changes were made as part of
the "api: select items in popupmenu" commit to Neovim. But all the new tests for
the <Cmd> key are passing without these changes. So I don't know the impact of
these missing changes on insert mode completion.

diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index 90da6c8ab..5d918d8f6 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -4406,6 +4443,9 @@ void ins_compl_check_keys(int frequency, int in_compl_func)
  */
 static int ins_compl_key2dir(int c)
 {
+  if (c == K_EVENT || c == K_COMMAND) {
+    return pum_want.item < pum_selected_item ? BACKWARD : FORWARD;
+  }
   if (c == Ctrl_P || c == Ctrl_L
       || c == K_PAGEUP || c == K_KPAGEUP
       || c == K_S_UP || c == K_UP) {
@@ -4433,6 +4473,11 @@ static int ins_compl_key2count(int c)
 {
   int h;
 
+  if (c == K_EVENT || c == K_COMMAND) {
+    int offset = pum_want.item - pum_selected_item;
+    return abs(offset);
+  }
+
   if (ins_compl_pum_key(c) && c != K_UP && c != K_DOWN) {
     h = pum_get_height();
     if (h > 3)
@@ -4459,6 +4504,9 @@ static bool ins_compl_use_match(int c)
   case K_KPAGEUP:
   case K_S_UP:
     return false;
+  case K_EVENT:
+  case K_COMMAND:
+    return pum_want.active && pum_want.insert;
   }
   return true;
 }

Regards,
Yegappan
 

vim-dev ML

unread,
Nov 11, 2020, 10:20:30 PM11/11/20
to vim/vim, vim-dev ML, Your activity

codecov[bot]

unread,
Nov 12, 2020, 12:01:10 AM11/12/20
to vim/vim, vim-dev ML, Comment

Codecov Report

Merging #7282 (d4ace00) into master (bbf9f34) will decrease coverage by 0.01%.
The diff coverage is 93.84%.

Impacted file tree graph

@@            Coverage Diff             @@

##           master    #7282      +/-   ##

==========================================

- Coverage   88.87%   88.85%   -0.02%     

==========================================

  Files         148      148              

  Lines      162672   162731      +59     

==========================================

+ Hits       144569   144602      +33     

- Misses      18103    18129      +26     
Impacted Files Coverage Δ
src/misc2.c 91.90% <ø> (ø)
src/getchar.c 86.28% <91.11%> (+0.15%) ⬆️
src/edit.c 92.52% <100.00%> (+0.01%) ⬆️
src/ex_docmd.c 94.61% <100.00%> (+<0.01%) ⬆️
src/ex_getln.c 91.35% <100.00%> (+0.01%) ⬆️
src/insexpand.c 91.19% <100.00%> (ø)
src/map.c 90.98% <100.00%> (ø)
src/normal.c 95.93% <100.00%> (+<0.01%) ⬆️
src/ops.c 92.36% <100.00%> (ø)
src/screen.c 86.71% <100.00%> (+0.09%) ⬆️
... and 11 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update bbf9f34...d4ace00. Read the comment docs.


You are receiving this because you commented.

Yegappan Lakshmanan

unread,
Nov 12, 2020, 12:31:45 AM11/12/20
to vim/vim, vim-dev ML, Push

@yegappan pushed 1 commit.


You are receiving this because you are subscribed to this thread.

Christian Brabandt

unread,
Nov 12, 2020, 3:45:32 AM11/12/20
to vim/vim, vim-dev ML, Comment

ah, that is nice for the various screen..() functions as you do not have to work-around using the mode-changing.


You are receiving this because you commented.

Bram Moolenaar

unread,
Nov 12, 2020, 7:17:24 AM11/12/20
to vim/vim, vim-dev ML, Comment

I see. If it's known Vim is insert mode, with the Normal mode mapping that starts with "a", then it would be possible to use CTRL-O for the Ex command. But I agree that using is more convenient, should have fewer side effects.


You are receiving this because you commented.

Bram Moolenaar

unread,
Nov 12, 2020, 8:21:45 AM11/12/20
to vim/vim, vim-dev ML, Comment

Closed #7282 via 957cf67.


You are receiving this because you commented.

lacygoill

unread,
Nov 12, 2020, 4:43:25 PM11/12/20
to vim/vim, vim-dev ML, Comment

@yegappan: It seems that using <cmd> in an operator-pending mapping might break the dot command. That is, instead of recomputing the text-object, Vim re-uses a text area with the same geometry as for the previous command.

vim9script
var lines =<< trim END
    ---
    aaa
    ---
    bbb
    bbb
    ---
    ccc
    ccc
    ccc
    ---
END
setline(1, lines)
xno i- <esc><cmd>call <sid>Func()<cr>
ono i- <cmd>norm vi-<cr>
def Func()
    search('^---\n\zs', 'bcW')
    norm! V
    search('\n\ze---$', 'W')
enddef
:2
norm di-
norm! j
norm .
norm! jj
norm .

The final contents of the buffer is:

---
---
bbb
---
ccc
ccc
---
vim9script
var lines =<< trim END
    ---
    aaa
    ---
    bbb
    bbb
    ---
    ccc
    ccc
    ccc
    ---
END
setline(1, lines)
xno i- <esc><cmd>call <sid>Func()<cr>
ono <silent> i- :<c-u>norm vi-<cr>
def Func()
    search('^---\n\zs', 'bcW')
    norm! V
    search('\n\ze---$', 'W')
enddef
:2
norm di-
norm! j
norm .
norm! jj
norm .

The final contents of the buffer is:

---
---
---
---

The only difference between the two snippets is the :ono mapping:

# first snippet
ono i- <cmd>norm vi-<cr>

# second snippet
ono <silent> i- :<c-u>norm vi-<cr>

In practice, I think I always want the second behavior, so I'll never use <cmd> in an :ono mapping. And yet, operator-pending mode is mentioned at :h <cmd>:

This is more flexible than :<C-U> in Visual and Operator-pending mode, or
<C-O>: in Insert mode, because the commands are executed directly in the
current mode, instead of always going to Normal mode. Visual mode is

Is it working as intended? If so, maybe it should be documented. I could try to write something if necessary.


Also, while it's true that <cmd> can replace :<C-U> in visual mode, in practice, you'll probably want to press <esc> before, so that the visual marks are set; at least, if your code refers to the visual marks. That was done automatically with :<C-U>, but not with <cmd>. Again, it might be useful to document this.


You are receiving this because you commented.

lacygoill

unread,
Nov 12, 2020, 5:01:28 PM11/12/20
to vim/vim, vim-dev ML, Comment

Also, it seems we don't need <silent> anymore with <cmd>. This could be added as an extra benefit in the "Note:" list.


You are receiving this because you commented.

Yegappan Lakshmanan

unread,
Nov 12, 2020, 7:35:06 PM11/12/20
to vim_dev, reply+ACY5DGCE7SPMUDDQXJ...@reply.github.com, vim/vim, vim-dev ML, Comment
Hi,

On Thu, Nov 12, 2020 at 1:43 PM lacygoill <vim-dev...@256bit.org> wrote:

Also, while it's true that <cmd> can replace :<C-U> in visual mode, in practice, you'll probably want to press <esc> before, so that the visual marks are set; at least, if your code refers to the visual marks. That was done automatically with :<C-U>, but not with <cmd>. Again, it might be useful to document this.


In the visual mode, you can use [line('v'), col('v')] and [line('.'), col('.')] to get the starting
and ending cursor position of the visually selected text without leaving visual mode.
For example, you can use the following map:

     vnoremap <F3> <Cmd>echo [col('v'), col('.')]<CR>

You can visually select some text and press <F3> to echo the column numbers
without leaving visual mode.

- Yegappan
 

vim-dev ML

unread,
Nov 12, 2020, 7:35:23 PM11/12/20
to vim/vim, vim-dev ML, Your activity

Björn Linse

unread,
Nov 13, 2020, 5:09:48 AM11/13/20
to vim/vim, vim-dev ML, Comment

@lacygoill hmm, I assume this issue (operatior-pending dot repeat) is in neovim as well? I agree changing it to operator-repeat instead of geometry-repeat would be more useful.


You are receiving this because you commented.

lacygoill

unread,
Nov 13, 2020, 5:39:44 AM11/13/20
to vim/vim, vim-dev ML, Comment

col('.')] to get the starting
and ending cursor position of the visually selected text without leaving
visual mode.
For example, you can use the following map:

 vnoremap <F3> <Cmd>echo [col('v'), col('.')]<CR>

You can visually select some text and press to echo the column numbers
without leaving visual mode.

  • Yegappan

Sure, I just thought it was easier to simply press <esc> without having to delve into the code to find where the visual marks are used:

xnoremap <F3> <esc><cmd>call <sid>Func()<cr>
              ^---^


You are receiving this because you commented.

lacygoill

unread,
Nov 13, 2020, 5:40:06 AM11/13/20
to vim/vim, vim-dev ML, Comment

@lacygoill hmm, I assume this issue (operatior-pending dot repeat) is in neovim as well? I agree changing it to operator-repeat instead of geometry-repeat would be more useful.

Yes, it also affects Neovim. I've just checked against master, with this code:

let lines =<< trim END
    
---
    aaa
    ---
    bbb
    bbb
    ---
    ccc
    ccc
    ccc
    ---
END
call setline(1, lines)
xno i- <esc><cmd>call Func()<cr>
ono i- <cmd>norm vi-<cr>
fu Func()
    call search('^---\n\zs', 'bcW')
    norm! V
    call search('\n\ze---$', 'W')
endfu
2
norm di-
norm! j
norm! .
norm! jj
norm! .

Expected:

---
---
---
---

Actual:

---
---
bbb
---
ccc
ccc
---


You are receiving this because you commented.

Shane-XB-Qian

unread,
Nov 13, 2020, 10:44:18 AM11/13/20
to vim/vim, vim-dev ML, Comment

and i was thinking it can reduce the mode switch which can reduce that annoyed esc code output, but looks it's not helpful much..
e.g map l <cmd>call system('ls')<cr> and map h :call system('ls')<cr> looks it still mode switched.. :)
and another amazing is when pressed l, this would print output into buffer directly -vs- h print output into cmdline.


You are receiving this because you commented.

Shane-XB-Qian

unread,
Nov 13, 2020, 10:52:55 AM11/13/20
to vim/vim, vim-dev ML, Comment

image
:)


You are receiving this because you commented.

Shane-XB-Qian

unread,
Nov 13, 2020, 11:01:07 AM11/13/20
to vim/vim, vim-dev ML, Comment

note it mapped to ':call' not ':echo', maybe not relevant, but just try to test its doc said it executes the command directly without changing modes. FYI. anyway.


You are receiving this because you commented.

Yegappan Lakshmanan

unread,
Nov 13, 2020, 11:02:50 AM11/13/20
to vim_dev, reply+ACY5DGDRYOY5PYZ3BL...@reply.github.com, vim/vim, vim-dev ML, Comment
Hi,

On Fri, Nov 13, 2020 at 7:44 AM Shane-XB-Qian <vim-dev...@256bit.org> wrote:

and i was thinking it can reduce the mode switch which can reduce that annoyed esc code output, but looks it's not helpful much..
e.g map l <cmd>call system('ls')<cr> and map h :call system('ls')<cr> looks it still mode switched.. :)
and another amazing is when pressed l, this would print output into buffer directly -vs- h print output into cmdline.



I am not able to reproduce this on MacOS or MS-Windows. With the above
map, when I press l or h, it doesn't output the directory listing and the buffer contents
are not changed. BTW, in your example, the second map is not using the <Cmd> key.

Regards,
Yegappan

vim-dev ML

unread,
Nov 13, 2020, 11:03:11 AM11/13/20
to vim/vim, vim-dev ML, Your activity


You are receiving this because you are subscribed to this thread.

Shane-XB-Qian

unread,
Nov 13, 2020, 11:07:08 AM11/13/20
to vim/vim, vim-dev ML, Comment

it doesn't output the directory listing and the buffer contents are not changed.

yes, you can not see if your terminal ignore/supported those annoyed esc code. this is (i) intended to do so.

BTW, in your example, the second map is not using the key.

yes, this is intended, to see the difference.

// maybe not relevant, but just try to test its doc said it executes the command directly without changing modes. FYI. anyway.


You are receiving this because you commented.

Björn Linse

unread,
Nov 13, 2020, 6:24:43 PM11/13/20
to vim/vim, vim-dev ML, Comment

I cannot reproduce map l <cmd>call system('ls')<cr> issues either on linux (as of patch 8.2.1981). Not sure what mode it would switch to, system() is just a function, not a mode (unlike say :terminal )

Christian Brabandt

unread,
Nov 18, 2020, 6:45:45 AM11/18/20
to vim/vim, vim-dev ML, Comment

It seems that using in an operator-pending mapping might break the dot command.

@lacygoill should be fixed with c77534c

Reply all
Reply to author
Forward
0 new messages