6

Is there a way to run vim from command line to edit the last edited file?

Let say I first edit file giorgio.sh:

$ vi giorgio.sh

Afterwards, I exit back to terminal

$ do something...
$ do something else...
$ do something else again...

Is there a way to edit again the file in vim, maybe using some vim command line parameter/option ?

$ vi {option to edit last edited/saved file}

I mean without using:

  • an internal vim command like :browse oldfiles
  • the beautiful MRU plugin
  • the bash history (requiring to scroll, if, after your edit, you ran some other commands)

It is strange that it doesn't seem possible to do a so common task in a super quick Vim way.

  • 3
    "bash history (sometime misleading " ... eh? Have you ever run !vi? – muru Sep 23 '15 at 7:03
  • 1
    I also use history for this: ctrl-r "vim", which previews the command and allows refining the search (or continue backwards with repeated ctrl-r). – Fred Nurk Sep 30 '15 at 10:22
5

An heavy solution: the sessions

Another possible option is to use the sessions mechanism:

First your vim version has to be compiled with the +mksession option. (Use :echo has('mksession') to check that).

Now when you are about to leave vim, use the following command:

:mksession!

This will create (or overwrite thanks to !) a file named Session.vim in the current directory which will save your current open files, windows layout and cursor position.

Note that you can also give a path as parameter to mksession to choose where to save and how to name you session file.

Then you can go back to your shell and do whatever you want. When you want to reopen vim with your last edited file you have to use:

$vim -S /path/to/Session.vim

This will reopen the files you where editing with the cursor at the same position

How to shorten it?

If this workflow is good for you you'll probably be able to create the bash alias the most convenient for your use case. Here is an example, maybe you'll want to bend it to your way to use sessions:

You can add this to your .vimrc:

command! Q mksession! ~/Session.vim | qall

this will allow you to use :Q to save your session in ~/Session.vim and quit vim.

As a bash alias you can create :

alias lvim='vim -S ~/Session.vim'

which will reload the session created when you used :Q in vim.


A much lighter solution: suspend vim

This solution is not suitable if you need to close your shell.

In unix shell you can suspend Vim using Ctrl+z. This will put Vim in background and you'll get acces to your shell again.

In your shell when you need to get Vim back you simply have to use the command:

$ fg 

Note That zsh provides convenient mappings to use also Ctrl+z on the shell to get Vim back.

Note2 If you tend to forget that you put vim in back ground you can add these lines to your .bashrc:

PROMPT_COMMAND='hasjobs=$(jobs -p)'
PS1=$PS1 + '${hasjobs:+\j }'

When you don't have any background job your prompt will stay the same and when you have some background jobs, a count will appear at the end of your prompt (It's up to you to bend it to your preferences). For this trick, credits goes to jw013

  • first of all: thanks statox for grammar corrections. my English is awful I admit. Yes, I know how to use session and the:Q and lvim alias simplify all. Good idea. I already do the suspended mode too, but I do not like because I forgot to be in suspended mode and often I close terminal. I appreciated your long explanantion and voted! – Giorgio Robino Sep 23 '15 at 18:32
  • 1
    @Solyaris: no problem for the corrections I also often do mistakes and get corrected that's how the community works :-) I'm glad you like the solution and I don't remember how but I think it is possible to have an indication on your prompt when some process are backgrounded so I'll see how to do that and edit my answer if I find it. – statox Sep 23 '15 at 19:09
  • 1
    @GiorgioRobino: Answer updated with the trick to show background jobs. Also in the cons of using the sessions I'm not sure but if I remember well NerdTree messes up the sessions sometimes so if you use this plugin you might experience some problems. – statox Sep 24 '15 at 15:06
  • 1
    I like your trick! so your "lighter" solution gain points :) and Yes I use NerdTree plugin too. Anyway your "heavy" solution is interesting for many reasons and I started to use it! thanks – Giorgio Robino Sep 24 '15 at 15:57
  • 1
    @GiorgioRobino: In case of multiple project you can still change a little bit my command to make it create the session file in the current working directory or you can make it take a parameter to choose where you want to save your session. Then you only need to adjust you bash alias. – statox Sep 25 '15 at 12:55
8

For this purpose, I have definde the following alias in my shell:

alias lvim="vim -c \"normal '0\""

(l meaning last)

3

Another possible alias:

alias lvim="vim -c':e#<1'"
  • yes, make me happy: alias v="vim -c':e#<1'" – Giorgio Robino Sep 23 '15 at 8:30
  • The problem with this is that NerdTree and other unused stuff is inside the oldfiles – edi9999 Sep 24 '15 at 13:21
  • This solution is better because works also on neovim – SergioAraujo Aug 29 '17 at 18:39
3

The last file should be at the top of the jumplist, which you can visit with CTRL-O.

Another way around your bash issue, related to muru's comment, is with the reverse-search-history CTRL-R.

3

I know this is the vi/vim stackexchange, but the best solution to this is actually the bash history. I see it mentioned in a few answers, but I thought I would expand on it a little bit, because bash history expansion has a lot more useful features than I've seen commonly used:

  • You can use !vi to immediately run the last command that started with vi.
  • You can use !vi:p to print that command (and add it to the history list) without running it. If it is indeed the command you want to run, you just press the up arrow and Enter, or just type !! and press Enter.
  • Let's say you run !vi:p and find the file you want, but the command was run the last time with a bunch of extra arguments, such as vim -s ./dostuff.vimscript -N mydir/subdir/myfile.txt and you want to edit myfile.txt without using any of the other options. Simply type vim !$ and voila! !$ is expanded to the last argument of the immediately preceding command, and you've got the file open as you wanted.

For further reading I recommend the bash man page. Type /^HISTORY EXPANSION and you will go straight to the applicable section.

  • 1
    I voted your proposal too, but I stll prefer the "sessions" heavy solution". – Giorgio Robino Oct 1 '15 at 11:25
1

@romainl answers doesn't work well if you use NerdTree (I don't want to go to the latest Nerdtree buffer), so here is my solution:

Put this in your .vimrc

function! s:Buflisted()
  return filter(range(1, bufnr('$')), 'buflisted(v:val)')
endfunction

function! g:Go_to_last_file()
  let b = extend(
  \ filter(copy(v:oldfiles),
  \        "v:val !~ 'fugitive:\\|NERD_tree\\|^/tmp/\\|.git/'"),
  \ filter(map(s:Buflisted(), 'bufname(v:val)'), '!empty(v:val)'))
  execute("e " . b[0])
  return b[0]
endfunction

and in your bashrc :

alias lvim="vim -c 'silent call g:Go_to_last_file()'"
1

Another solution (in normal mode) after opening vim/neovim

Ctrl-o Ctrl-o

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.