Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When typing ".." change to upper directory #338

Closed
4 of 9 tasks
nbari opened this issue Mar 17, 2017 · 9 comments
Closed
4 of 9 tasks

When typing ".." change to upper directory #338

nbari opened this issue Mar 17, 2017 · 9 comments

Comments

@nbari
Copy link

nbari commented Mar 17, 2017

  • Category
    • Question
    • Bug
    • Suggestion
  • OS
    • Linux
    • macOS
    • Windows
    • Etc.
  • Vim
    • Vim
    • Neovim

First at all, thanks and congratulations for all your efforts creating and sharing this tools.

I start to use fzf to replace ctrl-p but I still can find a way to achieve/replicate the same behavior when typing 2 dots ".." in order to cd to the upper directory and be capable of searching files outside the main directory of the project.

If my project has this structure:

/projects/github.com/junegunn/projectA
/projects/github.com/nbari/projectA

If I open :Files within the path

/projects/github.com/nbari/projectA

I am bound only to that directory, but would be nice if withing fzf by typing .. I could go one level back:

  /projects/github.com/nbari/

By pressing again .. I would go to:

/projects/github.com/

And there I would eazy go to:

 junegunn/any-project

Any idea of how to achieve this?

Thanks in advance.

@unphased
Copy link

unphased commented Jul 20, 2018

I was looking for the same thing. What I had in mind was not to type .. but to use two other keybinds (I'd override the Ctrl+N and Ctrl+P, as i use arrow keys or Ctrl+J/Ctrl+K for that same existing functionality) that let me hop up/down the directory tree. I'd be fine with .. too though. (But how would you go back inside if you go up too far?)

The workaround of course is to exit the fzf context and run :cd .. in vim.

@nbari
Copy link
Author

nbari commented May 27, 2019

for the meantime, I am using https://github.com/airblade/vim-rooter

Rooter changes the working directory to the project root when you open a file or directory

@c02y
Copy link

c02y commented Jul 17, 2019

When using ":Files" in vim, I would like to change to upper directory using something like ".." or Backspace to delete the current directory in the path, but I found no solution to go to the upper directory, this is really painful.

@junegunn
Copy link
Owner

junegunn commented May 3, 2020

If you understand what fzf really is and how it works (it's a generic, context-free text filter running outside of Vim), you'll realize that it's not something we can easily implement with fzf. But you can experiment with --expect option or reload binding. I think this is the best we can do for the moment:

" Reloading source on CTRL-P. Requires fd command.
function! Foo(dir)
  let tf = tempname()
  call writefile(['.'], tf)

  call fzf#vim#files(a:dir, {'source': 'fd', 'options': ['--bind', printf('ctrl-p:reload:base="$(cat %s)"/..; echo "$base" > %s; fd . "$base"', shellescape(tf), shellescape(tf))]})
endfunction

command! -nargs=* Foo call Foo(<q-args>)

@jxs
Copy link

jxs commented Dec 27, 2020

Hi there,
for anyone also interested, I made a small function based on @junegunn's to achieve file browsing:

" Search pattern across repository files
function! FzfExplore(...)
    let inpath = substitute(a:1, "'", '', 'g')
    if inpath == "" || matchend(inpath, '/') == strlen(inpath)
        execute "cd" getcwd() . '/' . inpath
        let cwpath = getcwd() . '/'
        call fzf#run(fzf#wrap(fzf#vim#with_preview({'source': 'ls -1ap', 'dir': cwpath, 'sink': 'FZFExplore', 'options': ['--prompt', cwpath]})))
    else
        let file = getcwd() . '/' . inpath
        execute "e" file
    endif
endfunction

command! -nargs=* FZFExplore call FzfExplore(shellescape(<q-args>))

@unphased
Copy link

That works great! I wonder what it would take to make it honor the fzf_actions so you can hit ctrl+v or ctrl+s to split instead of e.

@mikehaertl
Copy link

mikehaertl commented Jun 9, 2021

@junegunn Wouldnt this also work without a temp file? I'm a beginner with vimscript so the following code might not be perfect but it works for me:

function! TFile(dir)
  if empty(a:dir)
    let dir = getcwd()
  else
    let dir = a:dir
  endif
  let parentdir = fnamemodify(dir, ':h')
  let spec = fzf#wrap(fzf#vim#with_preview({'options': ['--expect', 'ctrl-u'] }))

  " hack to retain original sink used by fzf#vim#files
  let origspec = copy(spec)

  unlet spec.sinklist
  unlet spec['sink*']
  function spec.sinklist(lines) closure
    if len(a:lines) < 2
      return
    endif
    if a:lines[0] == 'ctrl-u'
      call TFile(parentdir)
    else
      call origspec.sinklist(a:lines)
    end
  endfunction
  call fzf#vim#files(dir, spec)
endfunction

command! -nargs=* TFile call TFile(<q-args>)

I can now use CTRL-u to restart fzf in the parent directory. The script could need some tweaking though:

  • Allow to pass options and use bang
  • Improve how the "parent" sink is called
  • Block reload when / is reached

@char101
Copy link

char101 commented Jul 5, 2022

Batch file for Windows (assuming git is installed)

fzf-up.bat

@echo off
setlocal disabledelayedexpansion
"C:\Program Files\Git\usr\bin\echo.exe" -n \.. >> "%1"
for /f %%l in ('findstr . "%1"') do set base=%%l
fd.exe . "%base%"
endlocal
function Files(dir)
  var tf = tempname()
  call writefile(['.'], tf, 'b')
  call fzf#vim#files(dir, {'options': ['--bind', printf('pgup:clear-query+reload:fzf-up %s', shellescape(tf))]})
endfunction

command! -nargs=? -complete=dir Files call Files(<q-args>)

@ruanformigoni
Copy link

ruanformigoni commented Aug 12, 2022

Hi there, for anyone also interested, I made a small function based on @junegunn's to achieve file browsing:

" Search pattern across repository files
function! FzfExplore(...)
    let inpath = substitute(a:1, "'", '', 'g')
    if inpath == "" || matchend(inpath, '/') == strlen(inpath)
        execute "cd" getcwd() . '/' . inpath
        let cwpath = getcwd() . '/'
        call fzf#run(fzf#wrap(fzf#vim#with_preview({'source': 'ls -1ap', 'dir': cwpath, 'sink': 'FZFExplore', 'options': ['--prompt', cwpath]})))
    else
        let file = getcwd() . '/' . inpath
        execute "e" file
    endif
endfunction

command! -nargs=* FZFExplore call FzfExplore(shellescape(<q-args>))

@unphased I modified the code a bit, to restore the functionality to open in new tab, split and vsplit.

function! FzfExplore(...)
  if a:1 =~ "enter"
    return
  elseif a:1 =~ "ctrl-t"
    execute "tabnew"
  elseif a:1 =~ "ctrl-v"
    execute "vnew"
  elseif a:1 =~ "ctrl-s"
    execute "new"
  else
    let inpath = substitute(a:1, "'", '', 'g')
    echo matchend(inpath, '/')
    if inpath == "" || matchend(inpath, '/') == strlen(inpath)
      execute "cd" getcwd() . '/' . inpath
      let cwpath = getcwd() . '/'
      let cmd = 'ls -1p; echo ../'
      let spec = fzf#vim#with_preview({'source': cmd, 'dir': cwpath, 'sink': 'FZFExplore', 'options': ['--prompt', cwpath, '--expect=ctrl-t,ctrl-v,ctrl-s,enter']})
      call fzf#run(fzf#wrap(spec))
    else
      let file = getcwd() . '/' . inpath
      execute "e" file
      set acd
    endif
  endif
endfunction

command! -nargs=* FZFExplore set noacd | call FzfExplore(<q-args>)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants