chrisbra / matchit

The matchit plugin from Vim
61 stars 9 forks source link

"m'gv``" inserted in insert visual mode #20

Closed user202729 closed 4 years ago

user202729 commented 4 years ago

Reproduction steps:

m'gv`` is displayed on the screen.

user202729 commented 4 years ago

@chrisbra I've just tested it and it's even worse -- <c-o>% in insert mode now always insert visual mode, and in visual mode it still insert "m'gv``"

However, it's possible to do this instead

--- a/plugin/matchit.vim
+++ b/plugin/matchit.vim
@@ -48,8 +48,8 @@ set cpo&vim

 nnoremap <silent> <Plug>(MatchitNormalForward)     :<C-U>call matchit#Match_wrapper('',1,'n')<CR>
 nnoremap <silent> <Plug>(MatchitNormalBackward)    :<C-U>call matchit#Match_wrapper('',0,'n')<CR>
-xnoremap <silent> <Plug>(MatchitVisualForward)     :<C-U>call matchit#Match_wrapper('',1,'v')<CR>m'gv``
-xnoremap <silent> <Plug>(MatchitVisualBackward)    :<C-U>call matchit#Match_wrapper('',0,'v')<CR>m'gv``
+xnoremap <silent> <Plug>(MatchitVisualForward)     :<C-U>call matchit#Match_wrapper('',1,'v') <bar> normal! m'gv``<CR>
+xnoremap <silent> <Plug>(MatchitVisualBackward)    :<C-U>call matchit#Match_wrapper('',0,'v') <bar> normal! m'gv``<CR>
 onoremap <silent> <Plug>(MatchitOperationForward)  :<C-U>call matchit#Match_wrapper('',1,'o')<CR>
 onoremap <silent> <Plug>(MatchitOperationBackward) :<C-U>call matchit#Match_wrapper('',0,'o')<CR>

(it may be better to include the normal! command into the Match_wrapper function)

chrisbra commented 4 years ago

I do not see this. For me this works. What vim version is this?

Am 03.03.2020 um 01:56 schrieb user202729 notifications@github.com:

 I've just tested it and it's even worse -- v in insert mode now always insert visual mode, and in visual mode it still insert "m'gv``".

— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub, or unsubscribe.

user202729 commented 4 years ago

Vim 8.2.0148-1, Arch Linux.

(I copy the repository into ~/.vim/pack. If I understood correctly, the plugin check for a global variable so that it only loads once, so it's not necessary to remove the global version)

But how can it be correct to run normal! v when the old mode is "n"?

(the old message has a typo. <c-o>% in insert mode always enter visual mode.)

user202729 commented 4 years ago

@chrisbra I upgraded to a newer version and the issue still persists (for matchit version 1.17)

Full version info:

``` VIM - Vi IMproved 8.2 (2019 Dec 12, compiled Mar 1 2020 17:21:03) Included patches: 1-343 Compiled by Arch Linux Huge version with GTK3 GUI. Features included (+) or not (-): +acl -farsi -mouse_sysmouse -tag_old_static +arabic +file_in_path +mouse_urxvt -tag_any_white +autocmd +find_in_path +mouse_xterm +tcl/dyn +autochdir +float +multi_byte +termguicolors -autoservername +folding +multi_lang +terminal +balloon_eval -footer -mzscheme +terminfo +balloon_eval_term +fork() +netbeans_intg +termresponse +browse +gettext +num64 +textobjects ++builtin_terms -hangul_input +packages +textprop +byte_offset +iconv +path_extra +timers +channel +insert_expand +perl/dyn +title +cindent +job +persistent_undo +toolbar +clientserver +jumplist +popupwin +user_commands +clipboard +keymap +postscript +vartabs +cmdline_compl +lambda +printer +vertsplit +cmdline_hist +langmap +profile +virtualedit +cmdline_info +libcall +python/dyn +visual +comments +linebreak +python3/dyn +visualextra +conceal +lispindent +quickfix +viminfo +cryptv +listcmds +reltime +vreplace +cscope +localmap +rightleft +wildignore +cursorbind +lua/dyn +ruby/dyn +wildmenu +cursorshape +menu +scrollbind +windows +dialog_con_gui +mksession +signs +writebackup +diff +modify_fname +smartindent +X11 +digraphs +mouse +sound -xfontset +dnd +mouseshape +spell +xim -ebcdic +mouse_dec +startuptime -xpm +emacs_tags +mouse_gpm +statusline +xsmp_interact +eval -mouse_jsbterm -sun_workshop +xterm_clipboard +ex_extra +mouse_netterm +syntax -xterm_save +extra_search +mouse_sgr +tag_binary system vimrc file: "/etc/vimrc" user vimrc file: "$HOME/.vimrc" 2nd user vimrc file: "~/.vim/vimrc" user exrc file: "$HOME/.exrc" system gvimrc file: "/etc/gvimrc" user gvimrc file: "$HOME/.gvimrc" 2nd user gvimrc file: "~/.vim/gvimrc" defaults file: "$VIMRUNTIME/defaults.vim" system menu file: "$VIMRUNTIME/menu.vim" fall-back for $VIM: "/usr/share/vim" Compilation: gcc -c -I. -Iproto -DHAVE_CONFIG_H -DFEAT_GUI_GTK -I/usr/include/gtk-3.0 -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/lib/libffi-3.2.1/include -I/usr/include/harfbuzz -I/usr/include/fribidi -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/libmount -I/usr/include/blkid -I/usr/include/gio-unix-2.0 -I/usr/include/atk-1.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include -I/usr/include/at-spi-2.0 -pthread -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -D_REENTRANT -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 Linking: gcc -L. -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,-E -Wl,-rpath,/usr/lib/perl5/5.30/core_perl/CORE -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -L/usr/local/lib -Wl,--as-needed -o vim -lgtk-3 -lgdk-3 -lz -lpangocairo-1.0 -lpango-1.0 -lharfbuzz -latk-1.0 -lcairo-gobject -lcairo -lgdk_pixbuf-2.0 -lgio-2.0 -lgobject-2.0 -lglib-2.0 -lSM -lICE -lXt -lX11 -lXdmcp -lSM -lICE -lm -ltinfo -lelf -lnsl -lcanberra -lacl -lattr -lgpm -ldl -Wl,-E -Wl,-rpath,/usr/lib/perl5/5.30/core_perl/CORE -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -fstack-protector-strong -L/usr/local/lib -L/usr/lib/perl5/5.30/core_perl/CORE -lperl -lpthread -ldl -lm -lcrypt -lutil -lc -L/usr/lib -ltclstub8.6 -ldl -lz -lpthread -lm ```
chrisbra commented 4 years ago

So does this patch fix it?

diff --git a/autoload/matchit.vim b/autoload/matchit.vim
index 4f3dd8f..264df29 100644
--- a/autoload/matchit.vim
+++ b/autoload/matchit.vim
@@ -44,12 +44,12 @@ function matchit#Match_wrapper(word, forward, mode) range
   let restore_options = s:RestoreOptions()
   " If this function was called from Visual mode, make sure that the cursor
   " is at the correct end of the Visual range:
-  if a:mode == "v"
-    execute "normal! gv\<Esc>"
-  elseif a:mode == "o" && mode(1) !~# '[^VvV]'
+  if a:mode =~# "[nvV]" && mode(1) =~# 'ni'
     exe "norm! v"
-  elseif a:mode == "n" && mode(1) =~# 'ni'
+  elseif a:mode == "o" && mode(1) !~# '[^VvV]'
     exe "norm! v"
+  elseif a:mode == "v"
+    execute "normal! gv\<Esc>"
   endif
   " In s:CleanUp(), we may need to check whether the cursor moved forward.
   let startpos = [line("."), col(".")]
user202729 commented 4 years ago

@chrisbra Now % works in insert visual mode, but <c-o>% in insert mode still enters visual mode.

(the literal ^V character in the diff file is not preserved when copied to GitHub, so the diff file doesn't apply directly. I don't know if I made any mistake while applying the patch.)

chrisbra commented 4 years ago

Now % works in insert visual mode, but % in insert mode still enters visual mode.

ah <c-o>% is a different problem.

I think this patch fixes both problems:

diff --git a/autoload/matchit.vim b/autoload/matchit.vim
index 4f3dd8f..49841b1 100644
--- a/autoload/matchit.vim
+++ b/autoload/matchit.vim
@@ -42,14 +42,14 @@ endfunction

 function matchit#Match_wrapper(word, forward, mode) range
   let restore_options = s:RestoreOptions()
+  if a:mode =~# "v" && mode(1) =~# 'ni'
+    exe "norm! v"
+  elseif a:mode == "o" && mode(1) !~# '[^VvV]'
+    exe "norm! v"
   " If this function was called from Visual mode, make sure that the cursor
   " is at the correct end of the Visual range:
-  if a:mode == "v"
+  elseif a:mode == "v"
     execute "normal! gv\<Esc>"
-  elseif a:mode == "o" && mode(1) !~# '[^VvV]'
-    exe "norm! v"
-  elseif a:mode == "n" && mode(1) =~# 'ni'
-    exe "norm! v"
   endif
   " In s:CleanUp(), we may need to check whether the cursor moved forward.
   let startpos = [line("."), col(".")]

can you please test?

user202729 commented 4 years ago

Yes, now it works, but there is another problem.

Given a file (a.cpp) with content

{
    a
}

Putting the cursor in first line, then pressing i<c-o>v, press % once will move the cursor to the last line, but press % again will not move it to the first line.

That problem does not happen in normal visual mode.

chrisbra commented 4 years ago

I think you shouldn't really use <c-o> from insert mode for anything fancy. It was supposed to be used for a single (builtin) normal mode command. Now with custom maps and plugins, this will break sooner or later. Having said that, I believe this would fix it:

diff --git a/autoload/matchit.vim b/autoload/matchit.vim
index 4f3dd8f..10a3738 100644
--- a/autoload/matchit.vim
+++ b/autoload/matchit.vim
@@ -42,14 +42,14 @@ endfunction

 function matchit#Match_wrapper(word, forward, mode) range
   let restore_options = s:RestoreOptions()
+  if a:mode =~# "v" && mode(1) =~# 'ni'
+    exe "norm! gv"
+  elseif a:mode == "o" && mode(1) !~# '[^VvV]'
+    exe "norm! v"
   " If this function was called from Visual mode, make sure that the cursor
   " is at the correct end of the Visual range:
-  if a:mode == "v"
+  elseif a:mode == "v"
     execute "normal! gv\<Esc>"
-  elseif a:mode == "o" && mode(1) !~# '[^VvV]'
-    exe "norm! v"
-  elseif a:mode == "n" && mode(1) =~# 'ni'
-    exe "norm! v"
   endif
   " In s:CleanUp(), we may need to check whether the cursor moved forward.
   let startpos = [line("."), col(".")]

let me know, what you think.