[vim/vim] Feature Request: mode() returns Insert sub-mode (#1397)

104 views
Skip to first unread message

Zhen-Huan (Kenny) Hu

unread,
Jan 19, 2017, 11:40:01 AM1/19/17
to vim/vim, Subscribed

Please make mode() return i_CTRL-X sub mode. Currently there seems to be no way to determine this. It would be very helpful for writing completion plugins.


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

Yegappan Lakshmanan

unread,
Jan 19, 2017, 12:40:56 PM1/19/17
to vim_dev, reply+00b1d198a25e8de842c8240949f417ed9157cbf...@reply.github.com, Subscribed
Hi,

On Thu, Jan 19, 2017 at 8:39 AM, Zhen-Huan (Kenny) Hu
<vim-dev...@256bit.org> wrote:
> Please make mode() return i_CTRL-X sub mode. Currently there seems to be no
> way to determine this. It would be very helpful for writing completion
> plugins.
>

Can you try the attached diff? The mode() function will return
'x' in i_CTRL-X sub mode. Need to test this under different insert mode
conditions where CTRL-X can be pressed.

- Yegappan
mode.diff

vim-dev ML

unread,
Jan 19, 2017, 12:41:21 PM1/19/17
to vim/vim, vim-dev ML, Your activity
Hi,

On Thu, Jan 19, 2017 at 8:39 AM, Zhen-Huan (Kenny) Hu
<vim-dev...@256bit.org> wrote:
> Please make mode() return i_CTRL-X sub mode. Currently there seems to be no
> way to determine this. It would be very helpful for writing completion
> plugins.
>

Can you try the attached diff? The mode() function will return
'x' in i_CTRL-X sub mode. Need to test this under different insert mode
conditions where CTRL-X can be pressed.

- Yegappan

diff --git a/src/evalfunc.c b/src/evalfunc.c
index 4b6bfaa..69a36e0 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -7757,6 +7757,11 @@ f_mode(typval_T *argvars, typval_T *rettv)
buf[0] = '!';
else if (State & INSERT)
{
+#ifdef FEAT_INS_EXPAND
+ if (ctrl_x_mode != 0)
+ buf[0] = 'x';
+ else
+#endif
#ifdef FEAT_VREPLACE
if (State & VREPLACE_FLAG)
{

Bram Moolenaar

unread,
Jan 19, 2017, 4:43:23 PM1/19/17
to vim/vim, vim-dev ML, Comment

Since it's a sub mode of insert it should be "ix".


You are receiving this because you commented.

Christian Brabandt

unread,
Jan 19, 2017, 5:09:35 PM1/19/17
to vim/vim, vim-dev ML, Comment

but mode() only returns one letter without argument.


You are receiving this because you commented.

Zhen-Huan (Kenny) Hu

unread,
Jan 19, 2017, 6:56:58 PM1/19/17
to vim/vim, vim-dev ML, Comment
#ifdef FEAT_INS_EXPAND
	if (ctrl_x_mode != 0)
	    buf[0] = 'x';
	else
#endif

I tested the code. mode() all returns x as expected when pressing <C-x> alone, or combined with <C-d>, <C-f>, <C-i>, <C-v>, <C-l>, <C-s>, <C-o>, as well as <C-e>, <C-y>

Pressing <C-x><C-n> or <C-x><C-p>, mode() returns i.

I agree it should be ix since it's a sub-mode.


You are receiving this because you commented.

Yegappan Lakshmanan

unread,
Jan 19, 2017, 10:33:31 PM1/19/17
to vim_dev, reply+00b1d198dc04cb03165dded03d49eedb02d32d6...@reply.github.com, vim/vim, vim-dev ML, Comment
Hi Bram,

On Thu, Jan 19, 2017 at 1:43 PM, Bram Moolenaar
<vim-dev...@256bit.org> wrote:
> Since it's a sub mode of insert it should be "ix".
>

The CTRL-X key can be used in Replace mode also. So it
is either 'ix' or 'Rx'.

- Yegappan

vim-dev ML

unread,
Jan 19, 2017, 10:33:59 PM1/19/17
to vim/vim, vim-dev ML, Your activity

Yegappan Lakshmanan

unread,
Jan 19, 2017, 10:44:23 PM1/19/17
to vim_dev, reply+00b1d1985a2cf8234f27e051aba600a730f050a...@reply.github.com, vim/vim, vim-dev ML, Comment
Hi,

On Thu, Jan 19, 2017 at 3:56 PM, Zhen-Huan (Kenny) Hu
<vim-dev...@256bit.org> wrote:
> #ifdef FEAT_INS_EXPAND
> if (ctrl_x_mode != 0)
> buf[0] = 'x';
> else
> #endif
>
> I tested the code. mode() all returns x as expected when pressing <C-x>
> alone, or combined with <C-d>, <C-f>, <C-i>, <C-v>, <C-l>, <C-s>, <C-o>, as
> well as <C-e>, <C-y>
>
> Pressing <C-x><C-n> or <C-x><C-p>, mode() returns i.
>
> I agree it should be ix since it's a sub-mode.
>

An updated patch to return either "ix" or "Rx" is attached.

- Yegappan
mode.diff

vim-dev ML

unread,
Jan 19, 2017, 10:44:50 PM1/19/17
to vim/vim, vim-dev ML, Your activity
diff --git a/src/evalfunc.c b/src/evalfunc.c
index 4b6bfaa..1f3164f 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -7765,10 +7765,16 @@ f_mode(typval_T *argvars, typval_T *rettv)
}
else
#endif
- if (State & REPLACE_FLAG)
- buf[0] = 'R';
- else
- buf[0] = 'i';
+ {
+ if (State & REPLACE_FLAG)
+ buf[0] = 'R';
+ else
+ buf[0] = 'i';

+#ifdef FEAT_INS_EXPAND
+ if (ctrl_x_mode != 0)
+ buf[1] = 'x';
+#endif
+ }
}
else if (State & CMDLINE)
{

h_east

unread,
Jan 20, 2017, 10:44:40 AM1/20/17
to vim_dev, v...@noreply.github.com, vim-dev...@256bit.org, your_a...@noreply.github.com, reply+00b1d1987f910c830505e7c19074c24bcdb41d8...@reply.github.com
Hi Bram, Yegappan, Zhen and Vim developers,

2017-1-20(Fri) 12:44:50 UTC+9 vim-dev ML:


> Hi,
>
>
>
> On Thu, Jan 19, 2017 at 3:56 PM, Zhen-Huan (Kenny) Hu
>
> <vim-dev...@256bit.org> wrote:
>
> > #ifdef FEAT_INS_EXPAND
>
> > if (ctrl_x_mode != 0)
>
> > buf[0] = 'x';
>
> > else
>
> > #endif
>
> >
>
> > I tested the code. mode() all returns x as expected when pressing <C-x>
>
> > alone, or combined with <C-d>, <C-f>, <C-i>, <C-v>, <C-l>, <C-s>, <C-o>, as
>
> > well as <C-e>, <C-y>
>
> >
>
> > Pressing <C-x><C-n> or <C-x><C-p>, mode() returns i.
>
> >
>
> > I agree it should be ix since it's a sub-mode.
>
> >
>
>
>
> An updated patch to return either "ix" or "Rx" is attached.

[...]

How about attached patch?
--
Best regards,
Hirohito Higashi (a.k.a. h_east)

mode2.patch

vim-dev ML

unread,
Jan 20, 2017, 10:45:09 AM1/20/17
to vim/vim, vim-dev ML, Your activity

Yegappan Lakshmanan

unread,
Jan 20, 2017, 2:20:02 PM1/20/17
to vim_dev, vim/vim, vim-dev ML, your_a...@noreply.github.com, reply+00b1d1987f910c830505e7c19074c24bcdb41d8...@reply.github.com
Hi Hirohito,
Note that Ctrl-X can be pressed in replace mode also. For example, you
can press 'R' to enter replace mode and then invoke completion using
CTRL-X. This diff handles only the insert mode case.

- Yegappan

vim-dev ML

unread,
Jan 20, 2017, 2:20:31 PM1/20/17
to vim/vim, vim-dev ML, Your activity

Zhen-Huan (Kenny) Hu

unread,
Jan 20, 2017, 3:35:52 PM1/20/17
to vim/vim, vim-dev ML, Comment
diff --git a/src/evalfunc.c b/src/evalfunc.c
index 4b6bfaa..1f3164f 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -7765,10 +7765,16 @@ f_mode(typval_T *argvars, typval_T *rettv)
 	}
 	else
 #endif
-	if (State & REPLACE_FLAG)
-	    buf[0] = 'R';
-	else
-	    buf[0] = 'i';
+	{
+	    if (State & REPLACE_FLAG)
+		buf[0] = 'R';
+	    else
+		buf[0] = 'i';
+#ifdef FEAT_INS_EXPAND
+	    if (ctrl_x_mode != 0)
+		buf[1] = 'x';
+#endif
+	}
     }
     else if (State & CMDLINE)
     {

I tested CTRL-X under both replace mode and insert mode. Under replace mode, mode(1) returns Rx and under insert mode, it returns ix.

As a side note, why CTRL-N/P and CTRL-X + CTRL-N/P behave differently than CTRL-X + others. It seems if CTRL-N/P cannot find a match, it will automatically return to the insert mode. If CTRL-X + others cannot find a match, it will stay under CTRL-X mode?


You are receiving this because you commented.

h_east

unread,
Jan 20, 2017, 7:23:22 PM1/20/17
to vim_dev, v...@noreply.github.com, vim-dev...@256bit.org, your_a...@noreply.github.com, reply+00b1d1987f910c830505e7c19074c24bcdb41d8...@reply.github.com
Hi Yegappan,

2017-1-21(Sat) 4:20:02 UTC+9 yega...@gmail.com:

That's right. Also, Virtual Replace is the same.
Unfortunately, Two letters are not enough for CTRL-X mode on Virtual Replace mode.
For example, how do we represent it in the following cases?

Type: gR<C-X>
Represent: Rvx ??


Thanks for many advice.

vim-dev ML

unread,
Jan 20, 2017, 7:24:00 PM1/20/17
to vim/vim, vim-dev ML, Your activity

Yegappan Lakshmanan

unread,
Jan 22, 2017, 12:40:48 PM1/22/17
to vim_dev, reply+00b1d198baea84636313e61ebebf549a7b1a15a...@reply.github.com, vim/vim, vim-dev ML, Comment
Hi,
Based on the patch from Hirohito, I have adjusted the patch to handle
this case. Try using the attached patch.

- Yegappan
mode.diff

vim-dev ML

unread,
Jan 22, 2017, 12:41:21 PM1/22/17
to vim/vim, vim-dev ML, Your activity
index 4b6bfaa..76d36f7 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -7765,10 +7765,18 @@ f_mode(typval_T *argvars, typval_T *rettv)

}
else
#endif
- if (State & REPLACE_FLAG)
- buf[0] = 'R';
- else
- buf[0] = 'i';
+ {
+ if (State & REPLACE_FLAG)
+ buf[0] = 'R';
+ else
+ buf[0] = 'i';
+#ifdef FEAT_INS_EXPAND
+ if (ctrl_x_mode != 0)
+ buf[1] = 'x';
+ else if (ins_compl_active())
+ buf[1] = pum_visible() ? 'C' : 'c';

+#endif
+ }
}
else if (State & CMDLINE)
{

Yegappan Lakshmanan

unread,
Jan 22, 2017, 12:42:25 PM1/22/17
to vim_dev, vim/vim, vim-dev ML, your_a...@noreply.github.com, reply+00b1d1987f910c830505e7c19074c24bcdb41d8...@reply.github.com
Hi Hirohito,
I think, in this case three letters can be used.

Regards,
Yegappan

vim-dev ML

unread,
Jan 22, 2017, 12:42:58 PM1/22/17
to vim/vim, vim-dev ML, Your activity

h_east

unread,
Jan 22, 2017, 8:31:19 PM1/22/17
to vim_dev, reply+00b1d198baea84636313e61ebebf549a7b1a15a...@reply.github.com, v...@noreply.github.com, vim-dev...@256bit.org, com...@noreply.github.com
Hi Yegappan,

2017-1-23(Mon) 2:40:48 UTC+9 yega...@gmail.com:

`ins_compl_active()` should be referenced before referring to `ctrl_x_mode`.
My patch's 'x' means "wait for CTRL-X mode selection".
That is, when the following text is displayed on the last line.
-- ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)

Thanks.

vim-dev ML

unread,
Jan 22, 2017, 8:31:49 PM1/22/17
to vim/vim, vim-dev ML, Your activity

Zhen-Huan (Kenny) Hu

unread,
Jan 23, 2017, 12:03:05 PM1/23/17
to vim/vim, vim-dev ML, Comment
  • else if (ins_compl_active())
    
  • buf[1] = pum_visible() ? 'C' : 'c';
    

    Does this 'C' vs. 'c' mean whether a completion was successful? I don't think pum_visible() alone is able to determine this accurately since it depends on whether the user have completeopt=menuone to have a menu if there is only one match. I'd rather not distinguish it in mode() and let it return 'ic' if ins_compl_active() no matther whether pum_visible().


    You are receiving this because you commented.

    h_east

    unread,
    Jan 24, 2017, 11:36:45 AM1/24/17
    to vim_dev, v...@noreply.github.com, vim-dev...@256bit.org, com...@noreply.github.com, reply+00b1d1989898b041d446eb45559a6e06e3dff25...@reply.github.com
    Hi All,

    2017-1-24(Tue) 2:03:05 UTC+9 Zhen-Huan (Kenny) Hu:


    > else if (ins_compl_active())
    >
    >
    >
    > buf[1] = pum_visible() ? 'C' : 'c';
    >
    >
    >
    >
    >
    > Does this 'C' vs. 'c' mean whether a completion was successful? I don't think pum_visible() alone is able to determine this accurately since it depends on whether the user have completeopt=menuone to have a menu if there is only one match. I'd rather not distinguish it in mode() and let it return 'ic' if ins_compl_active() no matther whether pum_visible().


    I was also thinking somewhat similar.

    It's a idea level proposal.
    Adding completion info built-in function ...

    completion_info()
    Returns a Dictionary with information about insert mode completion:
    "active" When completion is active, set to 1.
    "matches" Numner of matches.
    "Searching_match_done" Searching match done.
    "popupmenued" Popup menu displayed.
    "inserted" Insert a match from the menu.
    "selected" Select a match in the menu.
    "ctrl_x_selecting" Waiting for the ctrl-x mode selection.
    ...

    vim-dev ML

    unread,
    Jan 24, 2017, 11:37:21 AM1/24/17
    to vim/vim, vim-dev ML, Your activity
    Hi All,

    2017-1-24(Tue) 2:03:05 UTC+9 Zhen-Huan (Kenny) Hu:
    > else if (ins_compl_active())
    >
    >
    >
    > buf[1] = pum_visible() ? 'C' : 'c';
    >
    >
    >
    >
    >
    > Does this 'C' vs. 'c' mean whether a completion was successful? I don't think pum_visible() alone is able to determine this accurately since it depends on whether the user have completeopt=menuone to have a menu if there is only one match. I'd rather not distinguish it in mode() and let it return 'ic' if ins_compl_active() no matther whether pum_visible().


    I was also thinking somewhat similar.

    It's a idea level proposal.
    Adding completion info built-in function ...

    completion_info()
    Returns a Dictionary with information about insert mode completion:
    "active" When completion is active, set to 1..

    "matches" Numner of matches.
    "Searching_match_done" Searching match done.
    "popupmenued" Popup menu displayed.
    "inserted" Insert a match from the menu.
    "selected" Select a match in the menu.
    "ctrl_x_selecting" Waiting for the ctrl-x mode selection.
    ...

    --
    Best regards,
    Hirohito Higashi (a.k.a. h_east)

    Yegappan Lakshmanan

    unread,
    Jan 30, 2017, 10:16:42 AM1/30/17
    to vim_dev, reply+00b1d1989898b041d446eb45559a6e06e3dff25...@reply.github.com, vim/vim, vim-dev ML, Comment
    Hi,

    On Mon, Jan 23, 2017 at 9:02 AM, Zhen-Huan (Kenny) Hu
    <vim-dev...@256bit.org> wrote:
    > else if (ins_compl_active())
    >
    > buf[1] = pum_visible() ? 'C' : 'c';
    >
    > Does this 'C' vs. 'c' mean whether a completion was successful? I don't
    > think pum_visible() alone is able to determine this accurately since it
    > depends on whether the user have completeopt=menuone to have a menu if there
    > is only one match. I'd rather not distinguish it in mode() and let it return
    > 'ic' if ins_compl_active() no matther whether pum_visible().
    >

    I am attaching a patch to the mode() function that returns 'ic' or 'ix'
    or 'Rc' or 'Rx' depending on the insert completion mode. I have also
    added a test for the mode() function.

    The idea from Hirohito to add a separate function to get more
    information about the insert mode completion can be addressed in a
    separate patch.

    - Yegappan
    mode.diff

    vim-dev ML

    unread,
    Jan 30, 2017, 10:17:26 AM1/30/17
    to vim/vim, vim-dev ML, Your activity
    diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
    index 58a61f2..40e8a79 100644
    --- a/runtime/doc/eval.txt
    +++ b/runtime/doc/eval.txt
    @@ -5848,8 +5848,12 @@ mode([expr]) Return a string that indicates the current mode.
    S Select by line
    CTRL-S Select blockwise
    i Insert
    + ic Insert mode completion |compl-generic|
    + ix Insert mode |i_CTRL-X| completion
    R Replace |R|
    + Rc Replace mode completion |compl-generic|
    Rv Virtual Replace |gR|
    + Rx Replace mode |i_CTRL-X| completion
    c Command-line
    cv Vim Ex mode |gQ|
    ce Normal Ex mode |Q|
    diff --git a/src/evalfunc.c b/src/evalfunc.c
    index 7f433a5..8f90fc1 100644
    --- a/src/evalfunc.c
    +++ b/src/evalfunc.c
    @@ -7783,10 +7783,18 @@ f_mode(typval_T *argvars, typval_T *rettv)

    }
    else
    #endif
    - if (State & REPLACE_FLAG)
    - buf[0] = 'R';
    - else
    - buf[0] = 'i';
    + {
    + if (State & REPLACE_FLAG)
    + buf[0] = 'R';
    + else
    + buf[0] = 'i';
    +#ifdef FEAT_INS_EXPAND
    + if (ins_compl_active())
    + buf[1] = 'c';
    + else if (ctrl_x_mode == 1)

    + buf[1] = 'x';
    +#endif
    + }
    }
    else if (State & CMDLINE)
    {
    diff --git a/src/testdir/test_functions.vim b/src/testdir/test_functions.vim
    index 38f7723..e12bc6c 100644
    --- a/src/testdir/test_functions.vim
    +++ b/src/testdir/test_functions.vim
    @@ -304,4 +304,42 @@ func Test_toupper()
    call assert_equal("Ⱥ Ⱦ", toupper("ⱥ ⱦ"))
    endfunc

    +" Tests for the mode() function
    +let saved_modes = ''
    +func! Save_mode()
    + let g:saved_modes .= mode(1) . " "
    + return ''
    +endfunc

    +func! Test_mode()
    + new
    + call append(0, ["Blue Ball Black", "Brown Band Bowl", ""])
    +
    + inoremap <F2> <C-R>=Save_mode()<CR>
    +
    + normal! 3G
    + exe "normal i\<F2>\<Esc>"
    + exe "normal i\<C-G>uBa\<C-P>\<F2>\<Esc>u"
    + exe "normal iBro\<C-P>\<F2>\<Esc>u"
    + exe "normal iBa\<C-X>\<F2>\<Esc>u"
    + exe "normal iBa\<C-X>\<C-P>\<F2>\<Esc>u"
    + exe "normal iBro\<C-X>\<C-P>\<F2>\<Esc>u"
    + exe "normal iBro\<C-X>\<C-P>\<C-P>\<F2>\<Esc>u"
    + exe "normal iCom\<C-P>\<F2>\<Esc>u"
    + exe "normal iCom\<C-X>\<C-P>\<F2>\<Esc>u"
    +
    + exe "normal RBa\<C-P>\<F2>\<Esc>u"
    + exe "normal RBro\<C-P>\<F2>\<Esc>u"
    + exe "normal RBa\<C-X>\<F2>\<Esc>u"
    + exe "normal RBa\<C-X>\<C-P>\<F2>\<Esc>u"
    + exe "normal RBro\<C-X>\<C-P>\<F2>\<Esc>u"
    + exe "normal RBro\<C-X>\<C-P>\<C-P>\<F2>\<Esc>u"
    + exe "normal RCom\<C-P>\<F2>\<Esc>u"
    + exe "normal RCom\<C-X>\<C-P>\<F2>\<Esc>u"
    +
    + call assert_equal("i ic ic ix ic ic ic ic ic Rc Rc Rx Rc Rc Rc Rc Rc ",
    + \ g:saved_modes)
    +
    + enew! | close
    + iunmap <F2>
    +endfunc

    Bram Moolenaar

    unread,
    Feb 1, 2017, 11:25:59 AM2/1/17
    to vim/vim, vim-dev ML, Comment

    Closed #1397 via e90858d.


    You are receiving this because you commented.

    Reply all
    Reply to author
    Forward
    0 new messages