💾 Archived View for thrig.me › blog › 2023 › 05 › 13 › vi-backwards-search-bug.gmi captured on 2024-07-09 at 01:03:38. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2023-11-14)

-=-=-=-=-=-=-

OpenBSD vi Backwards Search Bug

The OpenBSD vi† has a bug that prevents a backwards search for "?"—but only with "extended" regular expressions enabled—as "?" is special to both the command (which uses the delimiter "?" to indicate a backwards search) and to extended regular expressions (which use the "?" to indicate that the previous portion of the expression is optional. The command "??" indicates that the previous regular expression should be used, but the command "?\?" is an error because the search delimiter parser removes the "\" which leaves a search of "?" which is an invalid extended regular expression. After sleeping on this I figured that a search of "[?]" would also work; hiding characters in character classes also sees use to e.g. prevent a grep from seeing itself in the process table—but you probably instead want to use `pgrep foo` and not `ps ... | grep '[f]oo'`. Anyways the command "?[\?]" works; the internal "?" must be escaped to prevent the outer command delimiter search from yielding the invalid expression of "[".

Finding this was pretty fun, as many vi commands simply call into some ex function (with a "but this is vi, not ex!" flag set)‡, and from there eventually one may find common/search.c, and maybe add code to "do the (hopefully) right thing" with the input "?\?" when extended regular expressions are enabled. Or how often do you search backwards for a literal "?" in a file with extended regex? How old is this bug?

Other weird things found along the way:

xkcd://1053

IDE

It also helps if you can see what you are searching for, or to have the text formatted in a predictable way, which automatic code formatters may help with. For C functions I use the following form, formatted by way of the ex command ":,/^`/-1!clang-format"

    int
    main(int argc, char *argv[])
    {
        ;
    }

so that "/^main" can easily find the function name; this is somewhat more difficult if the function name is hiding somewhere after the return type on the same line. Probably one of these years I should learn ctags, but I have other ways to accomplish "show me what files contain this here extended regular expression in this directory tree (or git repository)" and from there can launch into vi with those files. The startup and shutdown time of vi is negligible, so it's easy to quit out to some other command or shell to find a new set of files. You do lose marks, as vi doesn't have a .viminfo to store those in across instances.

It may also help to have a command that can associate process table entries with the relevant tmux pane as the tty, if you forgot where exactly you were editing triangle.go from a few days ago. Implementing something like the "j" command (or finding the various implementations of it) is left as an exercise to the reader.

    $ ps axo pid,tty,command | grep '[v]i'
    55438 ttyp4    /usr/bin/perl /home/jmates/bin/blog-about vi-backwards-se
     6533 ttyp4    vi -c5 /home/jmates/tmp/blog-about.4CnLWsa225.gmi
     6463 ttypa    vi triangle.go
    54238 ttypb    vi vi/v_search.c ex/ex_cmd.c common/search.c
    $ tmux list-windows '-aF#{pane_tty} #S:#I'
    /dev/ttyp7 ci:0
    ...
    $ j
       PID  TTY     CMD
      6463  pa:2    vi triangle.go
     54238  re:1    vi vi/v_search.c ex/ex_cmd.c common/search.c
      6533  re:0    vi -c5 /home/jmates/tmp/blog-about.4CnLWsa225.gmi
    $ grep votcana ~/.cwmrc
    bind-key 4-1 "xdotool search --name votcana-pa windowactivate"
    bind-key 4-2 "xdotool search --name votcana-re windowactivate"
    bind-key 4-3 "xdotool search --name votcana-ci windowactivate"
    bind-key 4-4 "xdotool search --name votcana-vo windowactivate"
    command votcana /home/jmates/libexec/votcana

tmux screen "pa" (the upper left xterm, clockwise to "re", "ci", and "vo") and window 2 thereof is a bit easier to get to than "where the heck is ttypa?" especially as the number of tmux screens and windows increases.

tags #vi #openbsd #ex

—

† Descended from "Version 1.79 (10/23/96) The CSRG, University of California, Berkeley" though modified since.

‡ Actually more complicated than described; vi sometimes injects a fake command into some system I haven't fully grokked and then...