The c_CTRL-\_e (<C-\>e) maps inside expression register are not working.
There is a very nice emacscommandline (http://www.vim.org/scripts/script.php?script_id=3554)
plugin which defines lots of nice maps in this way, but then when one
tries to write to expression register one gets errors. The minimal setup
to reproduce this is:
fun X()
return 'echo "X"'
endfun
cnoremap X <C-\>eX()<CR>
Now please try in insert mode:
<c-r>=X
and after pressing X I get the following error:
E15: invalid expression: ^eX()
E15: invalid expression: ^eX()
I got it twice. I think it would be nice to have the <C-\>e maps
working inside expression register (and in this case it would be nice of
vim script knew it, for example through including the '=' into to
getcmdline()) or to disable the <C-\>e maps inside the expression
register.
> The c_CTRL-\_e (<C-\>e) maps inside expression register are not working.
> There is a very nice emacscommandline (http://www.vim.org/scripts/script.php?script_id=3554)
> plugin which defines lots of nice maps in this way, but then when one
> tries to write to expression register one gets errors. The minimal setup
> to reproduce this is:
> fun X()
> return 'echo "X"'
> endfun
> cnoremap X <C-\>eX()<CR>
> Now please try in insert mode:
> <c-r>=X
> and after pressing X I get the following error:
> E15: invalid expression: ^eX()
> E15: invalid expression: ^eX()
> I got it twice. I think it would be nice to have the <C-\>e maps
> working inside expression register (and in this case it would be nice of
> vim script knew it, for example through including the '=' into to
> getcmdline()) or to disable the <C-\>e maps inside the expression
> register.
> Best regards,
> Marcin
In case somebody will stumble across this post, the solution that
I found for this is to define another map:
cnoremap <C-b> <C-R>
etc ... . It will not trigger the emacscommand line maps. One just has
to remember to not to use <C-W> while entering things into the
expression register (which is used rarely, so there is not much
opportunity to learn it, and lots of chances to forget it ;)
On Mon, October 1, 2012 13:16, Marcin Szamotulski wrote:
> On 09:20 Sun 23 Sep , Marcin Szamotulski wrote:
>> Hello
>> The c_CTRL-\_e (<C-\>e) maps inside expression register are not working.
>> There is a very nice emacscommandline
>> (http://www.vim.org/scripts/script.php?script_id=3554)
>> plugin which defines lots of nice maps in this way, but then when one
>> tries to write to expression register one gets errors. The minimal setup
>> to reproduce this is:
>> fun X()
>> return 'echo "X"'
>> endfun
>> cnoremap X <C-\>eX()<CR>
>> Now please try in insert mode:
>> <c-r>=X
>> and after pressing X I get the following error:
>> E15: invalid expression: ^eX()
>> E15: invalid expression: ^eX()
>> I got it twice. I think it would be nice to have the <C-\>e maps
>> working inside expression register (and in this case it would be nice of
>> vim script knew it, for example through including the '=' into to
>> getcmdline()) or to disable the <C-\>e maps inside the expression
>> register.
>> Best regards,
>> Marcin
> In case somebody will stumble across this post, the solution that
> I found for this is to define another map:
> cnoremap <C-b> <C-R>
> etc ... . It will not trigger the emacscommand line maps. One just has
> to remember to not to use <C-W> while entering things into the
> expression register (which is used rarely, so there is not much
> opportunity to learn it, and lots of chances to forget it ;)
> But this is far from perfect.
Would it be enough to simply disallow mappings in expression evalution mode?
diff --git a/src/ex_getln.c b/src/ex_getln.c
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -1128,7 +1128,6 @@
i = Ctrl_R; /* CTRL-R CTRL-O == CTRL-R CTRL-R */
if (i == Ctrl_R)
c = plain_vgetc(); /* CTRL-R CTRL-R <char> */
- --no_mapping;
#ifdef FEAT_EVAL
/*
* Insert the result of an expression.
@@ -1136,6 +1135,10 @@
* a new one...
*/
new_cmdpos = -1;
+ /* allow special keys like BS, but don't allow mappings.
+ * prevents from trying to evaluate c_Ctrl-\_e mappings
+ * where the ctrl-\ e makes the following expression invalid */
+ ++allow_keys;
if (c == '=')
{
if (ccline.cmdfirstc == '=')/* can't do this recursively */
@@ -1150,7 +1153,10 @@
restore_cmdline(&save_ccline);
}
}
-#endif
+ --allow_keys;
+#endif
+ --no_mapping;
+
if (c != ESC) /* use ESC to cancel inserting register */
{
cmdline_paste(c, i == Ctrl_R, FALSE);
> On Mon, October 1, 2012 13:16, Marcin Szamotulski wrote:
> > On 09:20 Sun 23 Sep , Marcin Szamotulski wrote:
> >> Hello
> >> The c_CTRL-\_e (<C-\>e) maps inside expression register are not working.
> >> There is a very nice emacscommandline
> >> (http://www.vim.org/scripts/script.php?script_id=3554)
> >> plugin which defines lots of nice maps in this way, but then when one
> >> tries to write to expression register one gets errors. The minimal setup
> >> to reproduce this is:
> >> fun X()
> >> return 'echo "X"'
> >> endfun
> >> cnoremap X <C-\>eX()<CR>
> >> Now please try in insert mode:
> >> <c-r>=X
> >> and after pressing X I get the following error:
> >> E15: invalid expression: ^eX()
> >> E15: invalid expression: ^eX()
> >> I got it twice. I think it would be nice to have the <C-\>e maps
> >> working inside expression register (and in this case it would be nice of
> >> vim script knew it, for example through including the '=' into to
> >> getcmdline()) or to disable the <C-\>e maps inside the expression
> >> register.
> >> Best regards,
> >> Marcin
> > In case somebody will stumble across this post, the solution that
> > I found for this is to define another map:
> > cnoremap <C-b> <C-R>
> > etc ... . It will not trigger the emacscommand line maps. One just has
> > to remember to not to use <C-W> while entering things into the
> > expression register (which is used rarely, so there is not much
> > opportunity to learn it, and lots of chances to forget it ;)
> > But this is far from perfect.
> Would it be enough to simply disallow mappings in expression evalution mode?
> diff --git a/src/ex_getln.c b/src/ex_getln.c
> --- a/src/ex_getln.c
> +++ b/src/ex_getln.c
> @@ -1128,7 +1128,6 @@
> i = Ctrl_R; /* CTRL-R CTRL-O == CTRL-R CTRL-R */
> if (i == Ctrl_R)
> c = plain_vgetc(); /* CTRL-R CTRL-R <char> */
> - --no_mapping;
> #ifdef FEAT_EVAL
> /*
> * Insert the result of an expression.
> @@ -1136,6 +1135,10 @@
> * a new one...
> */
> new_cmdpos = -1;
> + /* allow special keys like BS, but don't allow mappings.
> + * prevents from trying to evaluate c_Ctrl-\_e mappings
> + * where the ctrl-\ e makes the following expression invalid */
> + ++allow_keys;
> if (c == '=')
> {
> if (ccline.cmdfirstc == '=')/* can't do this recursively */
> @@ -1150,7 +1153,10 @@
> restore_cmdline(&save_ccline);
> }
> }
> -#endif
> + --allow_keys;
> +#endif
> + --no_mapping;
> +
> if (c != ESC) /* use ESC to cancel inserting register */
> {
> cmdline_paste(c, i == Ctrl_R, FALSE);
Christian Brabandt wrote:
> On Mon, October 1, 2012 13:16, Marcin Szamotulski wrote:
> > On 09:20 Sun 23 Sep , Marcin Szamotulski wrote:
> >> Hello
> >> The c_CTRL-\_e (<C-\>e) maps inside expression register are not working.
> >> There is a very nice emacscommandline
> >> (http://www.vim.org/scripts/script.php?script_id=3554)
> >> plugin which defines lots of nice maps in this way, but then when one
> >> tries to write to expression register one gets errors. The minimal setup
> >> to reproduce this is:
> >> fun X()
> >> return 'echo "X"'
> >> endfun
> >> cnoremap X <C-\>eX()<CR>
> >> Now please try in insert mode:
> >> <c-r>=X
> >> and after pressing X I get the following error:
> >> E15: invalid expression: ^eX()
> >> E15: invalid expression: ^eX()
> >> I got it twice. I think it would be nice to have the <C-\>e maps
> >> working inside expression register (and in this case it would be nice of
> >> vim script knew it, for example through including the '=' into to
> >> getcmdline()) or to disable the <C-\>e maps inside the expression
> >> register.
> >> Best regards,
> >> Marcin
> > In case somebody will stumble across this post, the solution that
> > I found for this is to define another map:
> > cnoremap <C-b> <C-R>
> > etc ... . It will not trigger the emacscommand line maps. One just has
> > to remember to not to use <C-W> while entering things into the
> > expression register (which is used rarely, so there is not much
> > opportunity to learn it, and lots of chances to forget it ;)
> > But this is far from perfect.
> Would it be enough to simply disallow mappings in expression evalution mode?
Would this not stop other mappings from working, e.g.:
cnoremap <C-Y> yank()
-- A special law prohibits unmarried women from parachuting on Sunday or she
shall risk arrest, fine, and/or jailing.
[real standing law in Florida, United States of America]
> > On Mon, October 1, 2012 13:16, Marcin Szamotulski wrote:
> > > On 09:20 Sun 23 Sep , Marcin Szamotulski wrote:
> > >> Hello
> > >> The c_CTRL-\_e (<C-\>e) maps inside expression register are not working.
> > >> There is a very nice emacscommandline
> > >> (http://www.vim.org/scripts/script.php?script_id=3554)
> > >> plugin which defines lots of nice maps in this way, but then when one
> > >> tries to write to expression register one gets errors. The minimal setup
> > >> to reproduce this is:
> > >> Now please try in insert mode:
> > >> <c-r>=X
> > >> and after pressing X I get the following error:
> > >> E15: invalid expression: ^eX()
> > >> E15: invalid expression: ^eX()
> > >> I got it twice. I think it would be nice to have the <C-\>e maps
> > >> working inside expression register (and in this case it would be nice of
> > >> vim script knew it, for example through including the '=' into to
> > >> getcmdline()) or to disable the <C-\>e maps inside the expression
> > >> register.
> > >> Best regards,
> > >> Marcin
> > > In case somebody will stumble across this post, the solution that
> > > I found for this is to define another map:
> > > cnoremap <C-b> <C-R>
> > > etc ... . It will not trigger the emacscommand line maps. One just has
> > > to remember to not to use <C-W> while entering things into the
> > > expression register (which is used rarely, so there is not much
> > > opportunity to learn it, and lots of chances to forget it ;)
> > > But this is far from perfect.
> > Would it be enough to simply disallow mappings in expression evalution mode?
> Would this not stop other mappings from working, e.g.:
> cnoremap <C-Y> yank()
Yes, in Expression evaluation mode (i.e. when doing <c-r>=)
regards,
Christian
-- Eine freie Seele, wie die seine, kommt in Gefahr, frech zu werden, wenn nicht ein edles Wohlwollen das sittliche Gleichgewicht herstellt.
-- Goethe, Maximen und Reflektionen, Nr. 190
Christian Brabandt wrote:
> On Mi, 03 Okt 2012, Bram Moolenaar wrote:
> > Christian Brabandt wrote:
> > > On Mon, October 1, 2012 13:16, Marcin Szamotulski wrote:
> > > > On 09:20 Sun 23 Sep , Marcin Szamotulski wrote:
> > > >> Hello
> > > >> The c_CTRL-\_e (<C-\>e) maps inside expression register are not working.
> > > >> There is a very nice emacscommandline
> > > >> (http://www.vim.org/scripts/script.php?script_id=3554)
> > > >> plugin which defines lots of nice maps in this way, but then when one
> > > >> tries to write to expression register one gets errors. The minimal setup
> > > >> to reproduce this is:
> > > >> Now please try in insert mode:
> > > >> <c-r>=X
> > > >> and after pressing X I get the following error:
> > > >> E15: invalid expression: ^eX()
> > > >> E15: invalid expression: ^eX()
> > > >> I got it twice. I think it would be nice to have the <C-\>e maps
> > > >> working inside expression register (and in this case it would be nice of
> > > >> vim script knew it, for example through including the '=' into to
> > > >> getcmdline()) or to disable the <C-\>e maps inside the expression
> > > >> register.
> > > >> Best regards,
> > > >> Marcin
> > > > In case somebody will stumble across this post, the solution that
> > > > I found for this is to define another map:
> > > > cnoremap <C-b> <C-R>
> > > > etc ... . It will not trigger the emacscommand line maps. One just has
> > > > to remember to not to use <C-W> while entering things into the
> > > > expression register (which is used rarely, so there is not much
> > > > opportunity to learn it, and lots of chances to forget it ;)
> > > > But this is far from perfect.
> > > Would it be enough to simply disallow mappings in expression evalution mode?
> > Would this not stop other mappings from working, e.g.:
> > cnoremap <C-Y> yank()
> Yes, in Expression evaluation mode (i.e. when doing <c-r>=)
Well, that's not nice, users should be able to type the expression with
their favorite mappings.
-- Any sufficiently advanced technology is indistinguishable from magic.
Arthur C. Clarke
Any sufficiently advanced bug is indistinguishable from a feature.
Rich Kulawiec
> > > > On Mon, October 1, 2012 13:16, Marcin Szamotulski wrote:
> > > > > On 09:20 Sun 23 Sep , Marcin Szamotulski wrote:
> > > > >> Hello
> > > > >> The c_CTRL-\_e (<C-\>e) maps inside expression register are not working.
> > > > >> There is a very nice emacscommandline
> > > > >> (http://www.vim.org/scripts/script.php?script_id=3554)
> > > > >> plugin which defines lots of nice maps in this way, but then when one
> > > > >> tries to write to expression register one gets errors. The minimal setup
> > > > >> to reproduce this is:
> > > > >> Now please try in insert mode:
> > > > >> <c-r>=X
> > > > >> and after pressing X I get the following error:
> > > > >> E15: invalid expression: ^eX()
> > > > >> E15: invalid expression: ^eX()
> > > > >> I got it twice. I think it would be nice to have the <C-\>e maps
> > > > >> working inside expression register (and in this case it would be nice of
> > > > >> vim script knew it, for example through including the '=' into to
> > > > >> getcmdline()) or to disable the <C-\>e maps inside the expression
> > > > >> register.
> > > > >> Best regards,
> > > > >> Marcin
> > > > > In case somebody will stumble across this post, the solution that
> > > > > I found for this is to define another map:
> > > > > cnoremap <C-b> <C-R>
> > > > > etc ... . It will not trigger the emacscommand line maps. One just has
> > > > > to remember to not to use <C-W> while entering things into the
> > > > > expression register (which is used rarely, so there is not much
> > > > > opportunity to learn it, and lots of chances to forget it ;)
> > > > > But this is far from perfect.
> > > > Would it be enough to simply disallow mappings in expression evalution mode?
> > > Would this not stop other mappings from working, e.g.:
> > > cnoremap <C-Y> yank()
> > Yes, in Expression evaluation mode (i.e. when doing <c-r>=)
> Well, that's not nice, users should be able to type the expression with
> their favorite mappings.
Okay, this seems to fix it:
diff --git a/src/ex_getln.c b/src/ex_getln.c
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -668,8 +668,7 @@
--no_mapping;
--allow_keys;
/* CTRL-\ e doesn't work when obtaining an expression. */
- if (c != Ctrl_N && c != Ctrl_G
- && (c != 'e' || ccline.cmdfirstc == '='))
+ if (c != Ctrl_N && c != Ctrl_G && c != 'e')
{
vungetc(c);
c = Ctrl_BSL;
regards,
Christian
-- Ein junger Igel verirrt sich im Botanischen Garten.
Er hat schreckliche Angst und fragt jeden Kaktus:
"Bist du es, Mami?"
среда, 3 октября 2012 г., 23:55:28 UTC+4 пользователь Christian Brabandt написал:
> diff --git a/src/ex_getln.c b/src/ex_getln.c
> --- a/src/ex_getln.c
> +++ b/src/ex_getln.c
> @@ -668,8 +668,7 @@
> --no_mapping;
> --allow_keys;
> /* CTRL-\ e doesn't work when obtaining an expression. */
> - if (c != Ctrl_N && c != Ctrl_G
> - && (c != 'e' || ccline.cmdfirstc == '='))
> + if (c != Ctrl_N && c != Ctrl_G && c != 'e')
> {
> vungetc(c);
> c = Ctrl_BSL;
I guess it needs to be
diff --git a/src/ex_getln.c b/src/ex_getln.c --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -668,8 +668,7 @@ --no_mapping; --allow_keys; - /* CTRL-\ e doesn't work when obtaining an expression. */ - if (c != Ctrl_N && c != Ctrl_G - && (c != 'e' || ccline.cmdfirstc == '=')) + if (c != Ctrl_N && c != Ctrl_G && c != 'e') { vungetc(c); c = Ctrl_BSL;
as the comment is no longer valid in this case.
> diff --git a/src/ex_getln.c b/src/ex_getln.c > --- a/src/ex_getln.c > +++ b/src/ex_getln.c > @@ -668,8 +668,7 @@ > --no_mapping; > --allow_keys; > /* CTRL-\ e doesn't work when obtaining an expression. */ > - if (c != Ctrl_N && c != Ctrl_G > - && (c != 'e' || ccline.cmdfirstc == '=')) > + if (c != Ctrl_N && c != Ctrl_G && c != 'e') > { > vungetc(c); > c = Ctrl_BSL;
Wondering what behavior do you see when doing C-\e inside C-\e? I guess (have not tested) this check is there for a reason and you either have to check the nesting level or purge out the reason (globals?): because expression register is the only way I see to launch a command-line mode from within a command-line mode, and the other way to increase nesting (<C-r>=) is also forbidden.
Christian Brabandt wrote:
> > > On Mi, 03 Okt 2012, Bram Moolenaar wrote:
> > > > Christian Brabandt wrote:
> > > > > On Mon, October 1, 2012 13:16, Marcin Szamotulski wrote:
> > > > > > On 09:20 Sun 23 Sep , Marcin Szamotulski wrote:
> > > > > >> Hello
> > > > > >> The c_CTRL-\_e (<C-\>e) maps inside expression register are not working.
> > > > > >> There is a very nice emacscommandline
> > > > > >> (http://www.vim.org/scripts/script.php?script_id=3554)
> > > > > >> plugin which defines lots of nice maps in this way, but then when one
> > > > > >> tries to write to expression register one gets errors. The minimal setup
> > > > > >> to reproduce this is:
> > > > > >> Now please try in insert mode:
> > > > > >> <c-r>=X
> > > > > >> and after pressing X I get the following error:
> > > > > >> E15: invalid expression: ^eX()
> > > > > >> E15: invalid expression: ^eX()
> > > > > >> I got it twice. I think it would be nice to have the <C-\>e maps
> > > > > >> working inside expression register (and in this case it would be nice of
> > > > > >> vim script knew it, for example through including the '=' into to
> > > > > >> getcmdline()) or to disable the <C-\>e maps inside the expression
> > > > > >> register.
> > > > > >> Best regards,
> > > > > >> Marcin
> > > > > > In case somebody will stumble across this post, the solution that
> > > > > > I found for this is to define another map:
> > > > > > cnoremap <C-b> <C-R>
> > > > > > etc ... . It will not trigger the emacscommand line maps. One just has
> > > > > > to remember to not to use <C-W> while entering things into the
> > > > > > expression register (which is used rarely, so there is not much
> > > > > > opportunity to learn it, and lots of chances to forget it ;)
> > > > > > But this is far from perfect.
> > > > > Would it be enough to simply disallow mappings in expression evalution mode?
> > > > Would this not stop other mappings from working, e.g.:
> > > > cnoremap <C-Y> yank()
> > > Yes, in Expression evaluation mode (i.e. when doing <c-r>=)
> > Well, that's not nice, users should be able to type the expression with
> > their favorite mappings.
> Okay, this seems to fix it:
Thanks. Thus this fixes the reported problem without side effects?
-- Beer & pretzels can't be served at the same time in any bar or restaurant.
[real standing law in North Dakota, United States of America]
> Thanks. Thus this fixes the reported problem without side effects?
I have tested it and it works fine in general. I only found a strange
behaviour in one case. I have a script which defines a cmap to <CR> and
calls a function via <C-\>e. When the function name is XX() everything
works fine, when the function name is WrapCmdLine() after pressing enter
in the expression register command line is not redraw, though it has
changes, since when I press <space><bs> it gets redrawn with the value
of the expression in the right place. You can test it with the attached
script. The function XX()=WrapCmdLine() only modifies the behaviour of
the cmdline when the cmdline starts with "! " sending the command line
to system() function rather than to the terminal directly.
I was testing with:
./vim -u NONE -i NONE --noplugin
> > Thanks. Thus this fixes the reported problem without side effects?
> I have tested it and it works fine in general. I only found a strange
> behaviour in one case. I have a script which defines a cmap to <CR> and
> calls a function via <C-\>e. When the function name is XX() everything
> works fine, when the function name is WrapCmdLine() after pressing enter
> in the expression register command line is not redraw, though it has
> changes, since when I press <space><bs> it gets redrawn with the value
> of the expression in the right place. You can test it with the attached
> script. The function XX()=WrapCmdLine() only modifies the behaviour of
> the cmdline when the cmdline starts with "! " sending the command line
> to system() function rather than to the terminal directly.
> I was testing with:
> ./vim -u NONE -i NONE --noplugin
> Best regards,
> Marcin Szamotulski
I found that the problem was caused by a <silent> keyword in a cmap:
fun! X()
return getcmdline()
endfun
" This map will not redraw the command line:
cnoremap <silent> <CR> <C-\>eX()<CR><CR>
" This map will redraw the command line:
cnoremap <CR> <C-\>eX()<CR><CR>
And actually all cmaps behave like that. Maybe we should add
:cmap-<silent> just after ":help :map-<silent>" in the help file. If so
I can write a patch for the documentation.