3

I know how to fzf.vim, but I'd like to open from terminal.

Grepping history or viminfo may be achieve thst, but I wonder if there is any smart way.

oguz ismail
  • 1
  • 16
  • 47
  • 69
Kohei Murakami
  • 339
  • 4
  • 14

5 Answers5

2

This is how you can save the list of recent files from vim to a file:

vim -c "call append(0, v:oldfiles)" -c "write vim-oldfiles.tmp" -c exit

Put v:oldfiles (the list of recent files saved in ~/.viminfo) into the first (new and empty at the start) buffer, write the buffer to a file, exit.

Now you can pass the content of file to fzf.

phd
  • 82,685
  • 13
  • 120
  • 165
0

Not exact solution. But you could open a terminal buffer on the lower part of your vim edit like an IDE and use your terminal fzf

However, not sure if this will let you open a file in a new vim tab

HaffiM
  • 31
  • 1
  • 4
0

If you're having trouble executing vim on files that have ~ in their path (vim open a new blank file instead of the desired file) because fzf and vim don't expand tilde (~), here's how I do it:

export FZF_DEFAULT_OPTS=$FZF_DEFAULT_OPTS"
--bind 'ctrl-e:execute(vim -c \"execute \\\"edit\\\" expand({})\" >/dev/tty)'
"

It's trial and error, based on this.

M Imam Pratama
  • 998
  • 11
  • 26
0

I have an zsh autoloaded function called old:

function old(){
    vim -c 'redir >> /tmp/oldfiles.txt | silent oldfiles | redir end | q'
    sed -i '/NvimTree$/d' /tmp/oldfiles.txt
    local fname
    fname=$(awk '/home/ && !/man:/ {print $2}' /tmp/oldfiles.txt | fzf) || return
    vim "$fname"
    \rm /tmp/oldfiles.txt
}
SergioAraujo
  • 11,069
  • 3
  • 50
  • 40
0

Combining some of the other answers, here's a version that does not need a temporary file and writes to stdout (so you can pipe this into another command, or capture the output using $(...)).

vim -e -c "redir >> /dev/fd/100 | for f in v:oldfiles | silent echo substitute(f, \"^\\\\~\", \$HOME, \"g\")  | endfor | redir end | q" 100>&1 &>/dev/null

This solution combines elements from other solutions, but with some improvements:

  • It uses some shell redirection to duplicate stdout to some free fd (100>&1) and then uses /dev/fd/100 to force writing output there. This ensures that vim actually writes to stdout rather than the terminal. Note that this can also be made to work using /dev/fd/1 (but only when omitting redir end for some reason), but then we cannot apply the next point.
  • It redirects stdout (and for good measure) also stderr to /dev/null, to prevent vim writing some terminal escape codes to stdout on startup, so using a different fd ensures clean output.
  • It uses vim in "ex" mode (vim -e) to suppress the "Vim: Warning: Output is not to a terminal" output and accompanying delay. [source]
  • It uses a for-loop to iterate over v:oldfiles to output just the filenames (the oldfiles command used by https://stackoverflow.com/a/70749181/740048 adds line numbers).
  • It uses a substitute to expand ~ in the filenames returned by vim (making the returned filenames easier to proces. Normally, shells like bash expand ~ in arguments passed to commands, but this happens only for tildes in the command typed, not tildes that result from variables or command substitution. To prevent having to rely on unsafe eval'ing later, better to expand (just) the tildes beforehand.
  • I also tried using the append / write combo from https://stackoverflow.com/a/60018642/740048, which worked with the /dev/fd/100 trick, but then ended up putting /dev/fd/100 in the list of oldfiles, so I did not use that approach.
Matthijs Kooijman
  • 2,498
  • 23
  • 30