0

The vim manual page contains two similar -r type commands. I'll give more background below, this question is really how to invoke the first type of -r to list the swap files, but avoid the second -r that invokes recovery

   -r          List swap files, with information about using them for  re‐
               covery.

   -r {file}   Recovery  mode.  The swap file is used to recover a crashed
               editing session.  The swap file is a  file  with  the  same
               filename as the text file with ".swp" appended.  See ":help
               recovery".

The -r without filename (the first -r above ) reports on the swap files of other files too, including ones in other directories

Background:

I'm trying to have vim report the swap files of a specific file (mostly to determine if vim still editing the file). If the file is being edited ( in another window, either on linux or cygwin ) I can 'raise' that window up to the top with "\e[2t\e[1t" as I have successfully be able to do thanks to Bring Window to Front

Vim has multiple swap file names, and multiple directories that it could put a file, so I want to ask vim, please tell me the name of the swap files that are currently in use for a given file, and if there is a current vim process on the file. Unfortunately, sometimes vim will open a command file in recovery mode in unexpected ways.

I'm invoking vim like this vim -r -c :q file, well actually, I'm invoking it from script, since I want vim to see something more like a terminal, then I look at the output file, so it's more like script -q -c "vim -r -c :q foo" fooscript, then I look in the fooscript file for messages like /Note: process STILL RUNNING: (\d+)/

It is beginning to look like I need to use vim -r without a file name, and parse the output of the -r report, and that there isn't a way to get the report pre-filtered to a single file in question.

David Dyck
  • 130
  • 1
  • 6
  • I'm still researching further, but the question might be resolved as - "you can't do that", and my current workaround is to an an exclamation mark to the :q command ":q!" `script -q -c "vim -r -c :q! foo" fooscript` – David Dyck Jan 09 '22 at 23:03
  • This 'dir' option for the first -r example command is also called " the 'directory' option", which might be coming from a .exrc type file, e.g. ( see "testdir/test_swap.vim" in the sources, which test various methods of setting "dir" ) The help for vim options lists the 'directory' 'dir' option `List of directory names for the swap file, separated with commas. - The swap file will be created in the first directory where this is possible." ` I have a feeling that my :q! comand will be my workaround – David Dyck Jan 09 '22 at 23:17
  • Since I care more if a vim process is "STILL RUNNING" - I'm also investigating if the function `swapfile_process_running` is accessible from vim command Looks that process id might be saved in the swap file we found - and the `mch_process_running` os wrapper code code is invoked. Looking at the code made me realize that I don't care yet if another user is editing the file, maybe that's a future concern. – David Dyck Jan 10 '22 at 00:30
  • I'm not sure if this is documented elsewhere, but `If the file name ends in ".s[a-w][a-z]" we assume this is the swap file.` – David Dyck Jan 10 '22 at 00:33
  • So the swap file format is buried inside memline.c ( see struct block0 ), and a 4 char_u ( byte? ) process id is stored in the swap file, along with the name of the user, and host name. It is clear to me that this is no place for an external tool to look to find this information. I have low hopes that there will be an external api to access the `b0_pid` (process id of creator), but that would be my last change to avoid my present search of the output of vim -r – David Dyck Jan 10 '22 at 00:45
  • Maybe the vim `swapinfo` see: https://vimhelp.org/builtin.txt.html#swapinfo%28%29 would be useful to avoid parsing the script file output, as it is documented as returning a dictionary with a `pid` entry if a process is running. This would be a clue to find the window that I want to raise! – David Dyck Jan 10 '22 at 01:01
  • 2
    1. `-r` does exactly what you describe in the title of your question. 2. Reading the documentation would have been more fruitful and quicker than scuba diving in the source: the whole mechanism is thoroughly described under `:help swap-file` with links to every other relevant help section. – romainl Jan 10 '22 at 08:27
  • I see I wasn't clear in my question - I had been invoking vim with a file name before, so I thought I needed to continue to specify the file name. I think I see now that I could have used the directory and -r without a file name . Regarding #2, documentation, like a wiki, often requires the user to know the magic words to be able to search for the magic words. ( searching /usr/share/vim/vim82/doc.* files that mention both 'swap.*file' and 'recovery' yields 140K lines of text to read, which would be useful, but I think I got what I needed faster in the sources :-) ) – David Dyck Jan 10 '22 at 20:45

1 Answers1

1

after switching my focus to just vim -r, and

  • Knowing that vim will try to put the swap file into the same directory as the file it's editing ( thanks to @romainl for the pointer to :help swap-file )

  • observing that vim -r reports on the files in the current directory first,

  • observing that the file name associated with the swap file is reported before the process id of the vim process, and

  • observing that vim appends (STILL RUNNING) if it finds the active process

  • I changed the current directory appropriately and ran this code after plugging in the name of the file-to-search-for

     perl -lne '
       last if /^\s+In directory/;
       undef $f if /^\d+/;
       $f = $1 if /^\s+file name:\s+(.*)\s*$/;
       if ( $f =~ m#/file-to-search-for# && /^\s+ process ID:\s(\d+).*?STILL RUNNING/ ) {
         print $1;
         $pid //= $1;
       }
       END { exit !$pid; } '
    

The pid of the running vim process is printed, and the exit status is zero when the appropiate swap file is found, and non-zero if the file was not being edited

David Dyck
  • 130
  • 1
  • 6
  • Neovim has a default "directory" place: `$HOME/.local/share/nvim/swap//`. directory = List of directory names for the swap file, separated with commas. – SergioAraujo Jan 12 '22 at 18:38