2

I am looking for a way to quickly change my Vim directory to a directory I find through an FZF-type-of-way. I understand it stands for Fuzzy File Searcher, not Fuzzy Directory Searcher, but I'm sure there is a similar tool or a hidden feature to use and benefit from switching directories so fast.

Example: Directory I want to go to: ~/Notes/Class 1/04-24-2020

What I'd like to type:

:FZF class 1 04 24

Thanks in advance!

Bonus question: How would I include hidden directories into this? If I would like to edit my init.vim configuration file that's hidden in .config, how would I pass an argument that would include that?

EDIT: Answer to bonus question written out below.

StolaDev
  • 137
  • 1
  • 7

2 Answers2

1

Found the answer for "including hidden files".

In the example below, I am using fdfind. Feel free to use anything you'd like!

command! -nargs=? -complete=dir AF
  \ call fzf#run(fzf#wrap(fzf#vim#with_preview({
  \   'source': 'fdfind --type f --hidden --follow --exclude .git --no-ignore . '.expand(<q-args>)
  \ })))

You'll do fine with the code above, but if you're looking for a more meaty configuration addition, here you go:

" Terminal buffer options for fzf
autocmd! FileType fzf
autocmd  FileType fzf set noshowmode noruler nonu

" nnoremap <silent> <Leader><Leader> :Files<CR>
nnoremap <silent> <expr> <Leader><Leader> (expand('%') =~ 'NERD_tree' ? "\<c-w>\<c-w>" : '').":Files\<cr>"
nnoremap <silent> <Leader>C        :Colors<CR>
nnoremap <silent> <Leader><Enter>  :Buffers<CR>
nnoremap <silent> <Leader>L        :Lines<CR>
nnoremap <silent> <Leader>ag       :Ag <C-R><C-W><CR>
nnoremap <silent> <Leader>AG       :Ag <C-R><C-A><CR>
xnoremap <silent> <Leader>ag       y:Ag <C-R>"<CR>
nnoremap <silent> <Leader>`        :Marks<CR>
" nnoremap <silent> q: :History:<CR>
" nnoremap <silent> q/ :History/<CR>

" inoremap <expr> <c-x><c-t> fzf#complete('tmuxwords.rb --all-but-current --scroll 500 --min 5')
imap <c-x><c-k> <plug>(fzf-complete-word)
imap <c-x><c-f> <plug>(fzf-complete-path)
inoremap <expr> <c-x><c-d> fzf#vim#complete#path('blsd')
imap <c-x><c-j> <plug>(fzf-complete-file-ag)
imap <c-x><c-l> <plug>(fzf-complete-line)

function! s:plug_help_sink(line)
  let dir = g:plugs[a:line].dir
  for pat in ['doc/*.txt', 'README.md']
    let match = get(split(globpath(dir, pat), "\n"), 0, '')
    if len(match)
      execute 'tabedit' match
      return
    endif
  endfor
  tabnew
  execute 'Explore' dir
endfunction

command! PlugHelp call fzf#run(fzf#wrap({
  \ 'source': sort(keys(g:plugs)),
  \ 'sink':   function('s:plug_help_sink')}))

function! RipgrepFzf(query, fullscreen)
  let command_fmt = 'rg --column --line-number --no-heading --color=always --smart-case %s || true'
  let initial_command = printf(command_fmt, shellescape(a:query))
  let reload_command = printf(command_fmt, '{q}')
  let options = {'options': ['--phony', '--query', a:query, '--bind', 'change:reload:'.reload_command]}
  if a:fullscreen
    let options = fzf#vim#with_preview(options)
  endif
  call fzf#vim#grep(initial_command, 1, options, a:fullscreen)
endfunction

command! -nargs=* -bang RG call RipgrepFzf(<q-args>, <bang>0)
StolaDev
  • 137
  • 1
  • 7
1

I wrote a function that I keep in my .bashrc which you can use to select any files through fzf and have them passed to whatever program you want. It works with both GUI programs like vlc, evince etc. and with command line tools like cd, cat, tail, head and so on. Also you can cycle back through your history and find the command as it was expanded after fzf did its thing.

In your case you would just type in the terminal:

f cd

and fzf would launch, after you select your directory you will cd there immediately.

I put the function below, and I got inspiration for it here

# Run command/application and choose paths/files with fzf.
# Always return control of the terminal to user (e.g. when opening GUIs).
# The full command that was used will appear in your history just like any
# other (N.B. to achieve this I write the shell's active history to
# ~/.bash_history)
#
# Usage:
# f cd (hit enter, choose path)
# f cat (hit enter, choose files)
# f vim (hit enter, choose files)
# f vlc (hit enter, choose files)

f() {
    # if no arguments passed, just lauch fzf
    if [ $# -eq 0 ]
    then
        fzf
        return 0
    fi

    # Store the program
    program="$1"

    # Remove first argument off the list
    shift

    # Store any option flags
    options="$@"

    # Store the arguments from fzf
    arguments=$(fzf --multi)

    # If no arguments passed (e.g. if Esc pressed), return to terminal
    if [ -z "${arguments}" ]; then
        return 1
    fi

    # Sanitise the command by putting single quotes around each argument, also
    # first put an extra single quote next to any pre-existing single quotes in
    # the raw argument. Put them all on one line.
    for arg in "${arguments[@]}"; do
        arguments=$(echo "$arg" | sed "s/'/''/g; s/.*/'&'/g; s/\n//g")
    done

    # If the program is on the GUI list, add a '&'
    if [[ "$program" =~ ^(nautilus|zathura|evince|vlc|eog|kolourpaint)$ ]]; then
        arguments="$arguments &"
    fi

    # Write the shell's active history to ~/.bash_history.
    history -w

    # Add the command with the sanitised arguments to .bash_history
    echo $program $options $arguments >> ~/.bash_history

    # Reload the ~/.bash_history into the shell's active history
    history -r

    # execute the last command in history
    fc -s -1
    }
mattb
  • 2,787
  • 2
  • 6
  • 20