[vim] Restore working directory even when new window is opened
Close #612
This commit is contained in:
parent
f941012687
commit
942ba749c7
115
plugin/fzf.vim
115
plugin/fzf.vim
@ -147,9 +147,9 @@ try
|
|||||||
return s:execute_term(dict, command, temps)
|
return s:execute_term(dict, command, temps)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let ret = tmux ? s:execute_tmux(dict, command, temps) : s:execute(dict, command, temps)
|
let lines = tmux ? s:execute_tmux(dict, command, temps) : s:execute(dict, command, temps)
|
||||||
call s:popd(dict, ret)
|
call s:callback(dict, lines)
|
||||||
return ret
|
return lines
|
||||||
finally
|
finally
|
||||||
let &shell = oshell
|
let &shell = oshell
|
||||||
endtry
|
endtry
|
||||||
@ -200,22 +200,17 @@ function! s:pushd(dict)
|
|||||||
return 0
|
return 0
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:popd(dict, lines)
|
augroup fzf_popd
|
||||||
" Since anything can be done in the sink function, there is no telling that
|
autocmd!
|
||||||
" the change of the working directory was made by &autochdir setting.
|
autocmd WinEnter * call s:dopopd()
|
||||||
"
|
augroup END
|
||||||
" We use the following heuristic to determine whether to restore CWD:
|
|
||||||
" - Always restore the current directory when &autochdir is disabled.
|
function! s:dopopd()
|
||||||
" FIXME This makes it impossible to change directory from inside the sink
|
if !exists('w:fzf_prev_dir') || exists('*haslocaldir') && !haslocaldir()
|
||||||
" function when &autochdir is not used.
|
return
|
||||||
" - In case of an error or an interrupt, a:lines will be empty.
|
|
||||||
" And it will be an array of a single empty string when fzf was finished
|
|
||||||
" without a match. In these cases, we presume that the change of the
|
|
||||||
" directory is not expected and should be undone.
|
|
||||||
if has_key(a:dict, 'prev_dir') &&
|
|
||||||
\ (!&autochdir || (empty(a:lines) || len(a:lines) == 1 && empty(a:lines[0])))
|
|
||||||
execute 'lcd' s:escape(remove(a:dict, 'prev_dir'))
|
|
||||||
endif
|
endif
|
||||||
|
execute 'lcd' s:escape(w:fzf_prev_dir)
|
||||||
|
unlet w:fzf_prev_dir
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:xterm_launcher()
|
function! s:xterm_launcher()
|
||||||
@ -256,7 +251,7 @@ function! s:execute(dict, command, temps) abort
|
|||||||
endif
|
endif
|
||||||
execute 'silent !'.command
|
execute 'silent !'.command
|
||||||
redraw!
|
redraw!
|
||||||
return s:exit_handler(v:shell_error, command) ? s:callback(a:dict, a:temps) : []
|
return s:exit_handler(v:shell_error, command) ? s:collect(a:temps) : []
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:execute_tmux(dict, command, temps) abort
|
function! s:execute_tmux(dict, command, temps) abort
|
||||||
@ -268,7 +263,7 @@ function! s:execute_tmux(dict, command, temps) abort
|
|||||||
|
|
||||||
call system(command)
|
call system(command)
|
||||||
redraw!
|
redraw!
|
||||||
return s:exit_handler(v:shell_error, command) ? s:callback(a:dict, a:temps) : []
|
return s:exit_handler(v:shell_error, command) ? s:collect(a:temps) : []
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:calc_size(max, val, dict)
|
function! s:calc_size(max, val, dict)
|
||||||
@ -361,31 +356,58 @@ function! s:execute_term(dict, command, temps) abort
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
call s:pushd(self.dict)
|
call s:pushd(self.dict)
|
||||||
let ret = []
|
let lines = s:collect(self.temps)
|
||||||
try
|
call s:callback(self.dict, lines)
|
||||||
let ret = s:callback(self.dict, self.temps)
|
call self.switch_back(s:getpos() == self.ppos)
|
||||||
call self.switch_back(s:getpos() == self.ppos)
|
|
||||||
finally
|
|
||||||
call s:popd(self.dict, ret)
|
|
||||||
endtry
|
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
call s:pushd(a:dict)
|
try
|
||||||
call termopen(a:command, fzf)
|
if s:present(a:dict, 'dir')
|
||||||
call s:popd(a:dict, [])
|
execute 'lcd' s:escape(a:dict.dir)
|
||||||
|
endif
|
||||||
|
call termopen(a:command, fzf)
|
||||||
|
finally
|
||||||
|
if s:present(a:dict, 'dir')
|
||||||
|
lcd -
|
||||||
|
endif
|
||||||
|
endtry
|
||||||
setlocal nospell bufhidden=wipe nobuflisted
|
setlocal nospell bufhidden=wipe nobuflisted
|
||||||
setf fzf
|
setf fzf
|
||||||
startinsert
|
startinsert
|
||||||
return []
|
return []
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:callback(dict, temps) abort
|
function! s:collect(temps) abort
|
||||||
let lines = []
|
try
|
||||||
try
|
return filereadable(a:temps.result) ? readfile(a:temps.result) : []
|
||||||
if filereadable(a:temps.result)
|
finally
|
||||||
let lines = readfile(a:temps.result)
|
for tf in values(a:temps)
|
||||||
|
silent! call delete(tf)
|
||||||
|
endfor
|
||||||
|
endtry
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:callback(dict, lines) abort
|
||||||
|
" Since anything can be done in the sink function, there is no telling that
|
||||||
|
" the change of the working directory was made by &autochdir setting.
|
||||||
|
"
|
||||||
|
" We use the following heuristic to determine whether to restore CWD:
|
||||||
|
" - Always restore the current directory when &autochdir is disabled.
|
||||||
|
" FIXME This makes it impossible to change directory from inside the sink
|
||||||
|
" function when &autochdir is not used.
|
||||||
|
" - In case of an error or an interrupt, a:lines will be empty.
|
||||||
|
" And it will be an array of a single empty string when fzf was finished
|
||||||
|
" without a match. In these cases, we presume that the change of the
|
||||||
|
" directory is not expected and should be undone.
|
||||||
|
let popd = has_key(a:dict, 'prev_dir') &&
|
||||||
|
\ (!&autochdir || (empty(a:lines) || len(a:lines) == 1 && empty(a:lines[0])))
|
||||||
|
if popd
|
||||||
|
let w:fzf_prev_dir = a:dict.prev_dir
|
||||||
|
endif
|
||||||
|
|
||||||
|
try
|
||||||
if has_key(a:dict, 'sink')
|
if has_key(a:dict, 'sink')
|
||||||
for line in lines
|
for line in a:lines
|
||||||
if type(a:dict.sink) == 2
|
if type(a:dict.sink) == 2
|
||||||
call a:dict.sink(line)
|
call a:dict.sink(line)
|
||||||
else
|
else
|
||||||
@ -394,20 +416,19 @@ try
|
|||||||
endfor
|
endfor
|
||||||
endif
|
endif
|
||||||
if has_key(a:dict, 'sink*')
|
if has_key(a:dict, 'sink*')
|
||||||
call a:dict['sink*'](lines)
|
call a:dict['sink*'](a:lines)
|
||||||
endif
|
endif
|
||||||
endif
|
catch
|
||||||
|
if stridx(v:exception, ':E325:') < 0
|
||||||
|
echoerr v:exception
|
||||||
|
endif
|
||||||
|
endtry
|
||||||
|
|
||||||
for tf in values(a:temps)
|
" We may have opened a new window or tab
|
||||||
silent! call delete(tf)
|
if popd
|
||||||
endfor
|
let w:fzf_prev_dir = a:dict.prev_dir
|
||||||
catch
|
call s:dopopd()
|
||||||
if stridx(v:exception, ':E325:') < 0
|
|
||||||
echoerr v:exception
|
|
||||||
endif
|
endif
|
||||||
finally
|
|
||||||
return lines
|
|
||||||
endtry
|
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
let s:default_action = {
|
let s:default_action = {
|
||||||
|
@ -43,6 +43,11 @@ Execute (fzf#run with dir option and noautochdir):
|
|||||||
" No change in working directory
|
" No change in working directory
|
||||||
AssertEqual cwd, getcwd()
|
AssertEqual cwd, getcwd()
|
||||||
|
|
||||||
|
call fzf#run({'source': ['/foobar'], 'sink': 'tabe', 'dir': '/tmp', 'options': '-1'})
|
||||||
|
AssertEqual cwd, getcwd()
|
||||||
|
tabclose
|
||||||
|
AssertEqual cwd, getcwd()
|
||||||
|
|
||||||
Execute (Incomplete fzf#run with dir option and autochdir):
|
Execute (Incomplete fzf#run with dir option and autochdir):
|
||||||
set acd
|
set acd
|
||||||
let cwd = getcwd()
|
let cwd = getcwd()
|
||||||
|
Loading…
Reference in New Issue
Block a user