I have the text in the file tmp.txt below with fileformat=unix. In normal mode, if I issue the backward search command ?da\?ta<CR>, the many occurrences of data are not found. If I then search forward using /<CR> alone, they are not found. However, if I search forward and explicitly provide the pattern using /da\?ta<CR>, all occurrences of data light up (:set hlsearch is enabled). I can then search backward using ?<CR> alone, i.e., without respecifying the search pattern -- because if I do, it will again fail to recognize the occurrences of data. I can also search backward without the \? conditional quantifier, i.e., ?data<CR> works.

I thought that maybe Vim was confused because I had traversed so many buffers, files, opened/close so many tabs, had many indentation levels of folds, and turned line numbering on and off with wild abandonment. I was using Gvim when I did this. So I used an xterm and Vim to edit tmp.txt. I got the same behaviour, where I cannot search using ?da\?ta<CR>, but I can using /da\?ta<CR>.

Does anyone else observe this behaviour? What might cause it, and how might I avoid this failure to recognize the pattern when searching backward?


Lorem ipsum dolor data sit amet, consectetur
adipiscing data elit, sed do eiusmod data tempor
incididunt ut labore data et dolore magna aliqua.
data Ut enim ad minim data veniam, quis nostrud
exercitation data ullamco laboris nisi ut data
aliquip ex ea commodo data consequat. Duis aute
irure data dolor in reprehenderit in data
voluptate velit esse cillum data dolore eu fugiat
nulla data pariatur. Excepteur sint occaecat data
cupidatat non proident, data sunt in culpa qui
data officia deserunt mollit anim data id est

Vim version

VIM - Vi IMproved 8.2 (2019 Dec 12, compiled Mar 30 2020 21:51:17)
Included patches: 1-486
Modified by <cygwin@cygwin.com>
Compiled by <cygwin@cygwin.com>
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
+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: "/etc"
 f-b for $VIMRUNTIME: "/usr/share/vim/vim82"

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/include/cairo
-I/usr/include/pixman-1 -I/usr/include/freetype2
-I/usr/include/libpng16 -I/usr/include/uuid
-I/usr/include/at-spi-2.0 -I/usr/include/dbus-1.0
-I/usr/lib/dbus-1.0/include -D_REENTRANT    -ggdb
-O2 -pipe -Wall -Werror=format-security
-fstack-protector-strong --param=ssp-buffer-size=4
-fstack-protector-strong -D_REENTRANT

Linking: gcc   -L. -fstack-protector-strong
-L/usr/local/lib -Wl,--as-needed -o vim.exe
-lgtk-3 -lgdk-3 -lpangocairo-1.0 -lpango-1.0
-latk-1.0 -lcairo-gobject -lcairo -lgdk_pixbuf-2.0
-lgio-2.0 -lgobject-2.0 -lglib-2.0 -lintl  -lSM
-lICE -lXpm -lXt -lX11 -lXdmcp -lSM -lICE  -lm
-lncursesw -lcanberra  -liconv -lacl -lattr -lintl
-Wl,--enable-auto-import -Wl,--export-all-symbols
-lperl -lpthread -ldl -lcrypt        

Short answer: Use the \= atom instead, when searching backwards. The vim documentation for \? mentions this

\? Just like \=. Cannot be used when searching backwards with the "?" command.

  • 2
    I guess it's because ? is used as the separator between the pattern and the (optional) line offset e.g. ?foo?-3 will put the cursor 3 lines above the next occurrence of "foo". Although, that's not escaped...hmmm. (I didn't know about \=, though. Cool.)
    – B Layer
    Sep 3 at 20:48
  • 3
    When searching backwards, you need to escape the ? to match a questionmark literally, because otherwise you would end the pattern already. Which means, you cannot use \? to match the previous atom optionally and that makes \? ambigious in backwards search mode, so it is forbidden. Sep 3 at 21:16
  • 1
    Oh, duh, of course! IOW, it's because it has potentially three meanings: literal question mark, wildcard, and offset separator. Only two of them could be allowed: one with escaping (literal) and one without escaping (offset). So the wildcard gets left out. Thanks.
    – B Layer
    Sep 3 at 21:30
  • @Christian Brabandt: Thanks so much. I'm getting cocky, thinking that I know the patterns cold and not RTFMing. Sep 4 at 2:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.