How do I deal with vim's swap file system? - linux

When using vim in ubuntu, I accidentally pressed ctrl-z which suspended my session of vim. I was editing a file (I'll call it test) which was not saved.
When I opened the file again in vim, I got the swap file error:
E325: ATTENTION
Found a swap file by the name ".test.swp"
Swap file ".test.swp" already exists!
According to Found a swap file by the name question, I have two options:
Find the session and finish it (preferable).
Delete the .swp file (if you're sure the other git session has gone away).
How would I do either of those things? If I perform rm test.swp it doesn't see the file:
rm: cannot remove `test.swp': No such file or directory
What am I doing wrong in the deletion of the swap file and how can I finish the session?
EDIT: I forgot the period in test.swp
So the correct way to remove the swp file is rm .test.swp.
My remaining question is how to resume/finish a suspended session of vim.

This is not related to Ubuntu alone, since what happens is a base mechanism of
nearly every Unix OS.
By pressin ^Z you ave suspended (not ended) the currently running vim session. The vim
session is still there and waiting for a signal to put it to foreground again.
To reactivate the session:
If vim was started directly from the commandline -- use the command "fg" (which is for "ForeGroung") and vim will appear again. This works on all ksh/bourne-like shells. For t/csh I dont know. This only works when the command "fg" was given on the console of the same terminal session as from which vim was started (which is the "controlling terminal" related to the vim session).
If vim was started (mostly under the name gvim) from a menu of a windowmanager you are a little bit out of luck here, since (g)vim gets detached from its controling terminal.
Your options to recover:
Use "fg" if the condition is valid described above. This is the cleanest way.
If the (g)vim session is detached from the controling terminal, which can be checked by doing a "ps -ef | grep vim". If the column for the TTY (see header of the output) shows
a "?" there is no controling terminal anymore, I would recommend to send the process
a SIGHUB (see manpage for the commmand "kill"/"killall") and then a SIGKILL if it is still there.
Killing vim (or any other task) will probably result in inconsistent data though, cause there was no "save" command to vim before it is killed.
After that, start a new vim with the same file, do a "recover" first (as offered by vim, which sees the according swp-file) , save the file, end vim and start it again with that file and do a "delete swap file". This is the savest way possible after killing vim.
To avoid accidentically putting vim into background if not wanted, map ^Z to another, more
"complicated" keysequence, which is hard to press accidentically. You can deactivate the
^Z command by adding the following line to your .vimrc:
map <C-z> ;
Addition: Your rm-command misses the dot in front of .test.swp causing rm not to
find the file...or deleting another file, which is named test.swp instead of ".test.swp". By deleting swp-files via vim, you are sure to delete the correct file.
Swp-files always start with a dot (hidden file) on UNIX like systems.

the file is going to be " .test.swp ", not " test.swp "
So you'll want to:
rm .test.swp

Related

Vim Opening File E325 Attention Error

On Git bash windows, I was editing .bash_profile file and then I decided not to save and closed the bash console. Now when I try to open the .bash_profile using vim, I get E325: Attention error. What should I do to fix this?
By closing the console without exiting Vim first, the Vim process got killed, and Vim didn't have a chance to properly shut down. Vim uses swap files to store the last unpersisted changes to a buffer to avoid data loss in case of a crash; you can read the whole story at :help E325.
In your case, as you've consciously closed the console, there probably weren't any pending changes to your .bash_profile [worth saving]. (But there's still the swap file!) Therefore, when prompted
Swap file ".bash_profile.swp" already exists!
[O]pen Read-Only, (E)dit anyway, (R)ecover, (Q)uit, (A)bort, (D)elete it:
answer with D to remove the outdated swap file. Alternatively, you can also search for the .bash_profile.swp (by default, it resides in the same directory as the edited file, likely $HOME in your case) and delete it manually. (It's hidden; use ls -a in Bash, or Windows Explorer.)
In the future, please exit Vim (:qall[!]) before closing the console it runs in, to allow for a clean shutdown.

Vim Ex mode loads when opening terminal

I know little about Vim in terminal(Mac) and the other day I was working copy and pasting text and i think I accidently did it when in terminal. Now whenever I open terminal it instantly loads on Vim Ex mode. I know how to quit Ex mode once in terminal but is there any way i can get rid of Vim loading when I open Terminal?
Thanks
Edit: To explain further to what i mean when I open terminal.app from Utilities I get the following
and the only way I get back to the command prompt is by typing quit every time I open terminal and i cant understand why the Vim process is running in the first place.
I was just outside the terminal in a document copy and pasting text then accidentally did a command v to paste within terminal which resulted in this happening.
It appears that you've accidentally updated one of your shell startup scripts so it launches vim.
If your default shell is csh or tcsh, take a look at .cshrc, .tcshrc, and .login in your home directory, and look for a command like vi -e or vim -e.
If your default shell is bash, check .bashrc and .bash_profile.
It may be easier to figure out which file you messed up by checking which file in your home directory was modified most recently:
% ls -altr $HOME | tail
-a lists all files, including files whose names start with ..
-l gives you a long listing, showing timestamps.
-t sorts by modification time.
-r reverses the order, so newer files are shown last

Can I write a script to tell me which files are currently being edited in vim?

I'm using tmux with many windows, and I frequently lose track of which files I'm editing in vim. I'd like to have another shell open that runs a script that tells me the paths of files that vim is currently editing.
I'm running Mac OS.
The way I would tackle the problem is to query all remote Vim processes for their opened buffers. You can use Vim's clientserver functionality for that. The GVIM server names are usually sequentially named: GVIM, GVIM1, ...; for terminal Vim, you'd have to name them with the --servername argument (e.g. via a shell alias).
You can then query the list of open files via the --remote-expr argument. A simple expression to loop over all listed buffers (like what the :ls command shows) is:
map(filter(range(1, bufnr('$')), 'buflisted(v:val) && ! empty(bufname(v:val))'), 'bufname(v:val)')
As you can see, it's a bit involved and might affect your workflow of launching Vim. Think hard whether you really need this!
That I know of there is no way to get every open vim buffer from an external process. Instead of using separate tmux layouts and a separate instance of vim to edit multiple files, you could have one instance of vim and edit multiple separate files using :split and :tabnew. Then in that vim instance you can use :ls to see the paths of all open files relative to the current working directory. :pwd also works.
If this isn't your style and you'd still like to use vim in separate layouts, you can use ps to see the arguments to each vim process and check the cwd of these processes. Something like:
paste <(pgrep vim | xargs pwdx) <(pgrep vim | xargs ps -o %a | sed 1d)
Note that if you use multiple buffers in vim the above won't quite work because it will only list the arguments given to each vim command and not list the actual buffers.
You could tweak around with the piped commands ps -eF | grep vim for your script.
At the end of each line, of the result, you'll see you the different processes dealing with anything related to 'vim'. Therefore you'll find which files are currently being edited by vim('vim foo.txt' for instance), as well as 'grep vim' that was being active to get this result. To have a pretty output, you'd have to filter all of these with a script.
I hope this will help you.

How to check if it's still in Vim shell mode

In vim, type :sh will switch to shell, and exit can exit the shell and get back to vim. Is there any command to check if it's in vim shell mode? So that I won't accidentally vim to open the same file again. I want to avoid below scenario:
vim myfile > :sh > exit > vim myfile // get warning of another vim instance is editing the same file
These are the normal scenario:
vim myfile > :sh > exit // keep editing
vim myfile > :wq > vim myfile // keep editing
In addition to #a3nm answer, what you can do is
use pstree -h: it will output process tree with current branch highligted and all you need to check is whether there is vim in the highlight.
Another possibility is ps t: it will show all processes using the current terminal and should show vim in a list when you are inside :sh. ps -oargs t may be more useful in case you want to know arguments you ran vim with.
These methods are more reliable because VIMRUNTIME, VIM and MYVIMRC environment variables may be overrided by you in order to do some customizations (BTW, they are defined by vim for use in vimscripts, not by :sh). They also work for other processes that allow you to run a subshell, but do not define any environment variables.
I would also suggest to consider using <C-z> in normal mode or :suspend/:stop in Ex because these use shell vim was launched from instead of creating new. This behavior gives you access to history of commands you typed before running vim and also makes you able to write more complex and time-consuming shell configuration without needing to wait every time.
In case you use <C-z> both methods still work, but first method won’t highlight vim because it will be at the same level (has the same parent) as pstree itself, likely just below or above pstree in graph. This also enables third method: jobs shell builtin.
In order to restore from <C-z> you should use fg (a single % in zsh and bash also works) which is less to type then exit (but more then <C-d>).
The :sh command in vim seems to define the VIMRUNTIME, VIM and MYVIMRC environment variables, so you can just check if they are defined. To do so, you can run echo $VIM, for instance, which should return an empty line in a normal shell and something like /usr/share/vim in a shell run from vim.

what is the load order of scripts when you start up vim?

If you start up vim with something like this:
vim -S myscript.vim file.txt
What is the load order of scripts? Does myscript.vim get loaded after or before ~/.vimrc.
If you pass in vimscript commands to vim directly on the command line, when do they get executed relative to sourced and default vimscripts?
I believe vimrc is always first. You can run :scriptnames to get a list of sourced scripts in order in which they were first sourced in your Vim instance.
The help entry is way too long to post here, but it lists the order of everything that vim does at initialization. See :help initialization.
The answer is myscript.vim gets loaded dead last.
The vim -V option is a lifesaver here. (Capital -V, because -v starts in vi mode.) Just ran across it, after searching further since although the other answers answered your question, they don't show what wasn't sourced because it wasn't found. If I could send it back in time, I'd save myself a lot of time banging my head against strace output.
This will not only show you all of the scriptnames that it did source in order, but also all of the scriptnames that it would have sourced if they existed in order. So, you can discover what files you can create to load at the appropriate time.
$ vim -V
Adding it to your vim arguments easily answers the question.
$ vim -V -S myscript.vim file.txt
It shows myscript.vim as dead last.
It prints a ton, and winds up at a "Press ENTER or type command to continue" prompt, which lets you step through Autocommands.

Resources