Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions autoload/fern/helper/sync.vim
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,20 @@ function! s:sync_is_drawer() abort dict
endfunction
let s:sync.is_drawer = funcref('s:sync_is_drawer')

function! s:sync_is_left_drawer() abort dict
let helper = self.helper
let fern = helper.fern
return fern#internal#drawer#is_left_drawer(bufname(helper.bufnr))
endfunction
let s:sync.is_left_drawer = funcref('s:sync_is_left_drawer')

function! s:sync_is_right_drawer() abort dict
let helper = self.helper
let fern = helper.fern
return fern#internal#drawer#is_right_drawer(bufname(helper.bufnr))
endfunction
let s:sync.is_right_drawer = funcref('s:sync_is_right_drawer')

function! s:sync_get_scheme() abort dict
let helper = self.helper
let fern = helper.fern
Expand Down
14 changes: 9 additions & 5 deletions autoload/fern/internal/command/do.vim
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,20 @@ function! fern#internal#command#do#command(mods, fargs) abort
try
let stay = fern#internal#args#pop(a:fargs, 'stay', v:false)
let drawer = fern#internal#args#pop(a:fargs, 'drawer', v:false)
let right = fern#internal#args#pop(a:fargs, 'right', v:false)

if len(a:fargs) is# 0
\ || type(stay) isnot# v:t_bool
\ || type(drawer) isnot# v:t_bool
throw 'Usage: FernDo {expr...} [-drawer] [-stay]'
\ || type(right) isnot# v:t_bool
throw 'Usage: FernDo {expr...} [-drawer] [-right] [-stay]'
endif

" Does all options are handled?
call fern#internal#args#throw_if_dirty(a:fargs)

let found = fern#internal#window#find(
\ funcref('s:predicator', [drawer]),
\ funcref('s:predicator', [drawer, right]),
\ winnr() + 1,
\)
if !found
Expand All @@ -39,9 +41,11 @@ function! fern#internal#command#do#complete(arglead, cmdline, cursorpos) abort
return fern#internal#complete#options(a:arglead, a:cmdline, a:cursorpos)
endfunction

function! s:predicator(drawer, winnr) abort
function! s:predicator(drawer, right, winnr) abort
let bufname = bufname(winbufnr(a:winnr))
let fri = fern#fri#parse(bufname)
return fri.scheme ==# 'fern'
\ && (!a:drawer || fri.authority =~# '^drawer:')
return fri.scheme ==# 'fern' && (!a:drawer
\ || (!a:right && fri.authority =~# '^drawer:')
\ || (a:right && fri.authority =~# '^drawer-right:')
\)
endfunction
28 changes: 20 additions & 8 deletions autoload/fern/internal/command/fern.vim
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
let s:Promise = vital#fern#import('Async.Promise')
let s:drawer_opener = 'topleft vsplit'
let s:drawer_left_opener = 'topleft vsplit'
let s:drawer_right_opener = 'botright vsplit'

function! fern#internal#command#fern#command(mods, fargs) abort
try
Expand All @@ -8,15 +9,17 @@ function! fern#internal#command#fern#command(mods, fargs) abort
let reveal = fern#internal#args#pop(a:fargs, 'reveal', '')
let drawer = fern#internal#args#pop(a:fargs, 'drawer', v:false)
if drawer
let opener = s:drawer_opener
let width = fern#internal#args#pop(a:fargs, 'width', '')
let keep = fern#internal#args#pop(a:fargs, 'keep', v:false)
let toggle = fern#internal#args#pop(a:fargs, 'toggle', v:false)
let right = fern#internal#args#pop(a:fargs, 'right', v:false)
let opener = right ? s:drawer_right_opener : s:drawer_left_opener
else
let opener = fern#internal#args#pop(a:fargs, 'opener', g:fern#opener)
let width = ''
let keep = v:false
let toggle = v:false
let right = v:false
endif

if len(a:fargs) isnot# 1
Expand All @@ -28,10 +31,11 @@ function! fern#internal#command#fern#command(mods, fargs) abort
\ || type(width) isnot# v:t_string
\ || type(keep) isnot# v:t_bool
\ || type(toggle) isnot# v:t_bool
\ || type(right) isnot# v:t_bool
if empty(drawer)
throw 'Usage: Fern {url} [-opener={opener}] [-stay] [-wait] [-reveal={reveal}]'
else
throw 'Usage: Fern {url} -drawer [-toggle] [-keep] [-width={width}] [-stay] [-wait] [-reveal={reveal}]'
throw 'Usage: Fern {url} -drawer [-right] [-toggle] [-keep] [-width={width}] [-stay] [-wait] [-reveal={reveal}]'
endif
endif

Expand All @@ -41,9 +45,14 @@ function! fern#internal#command#fern#command(mods, fargs) abort
" Force project drawer style when
" - The current buffer is project drawer style fern
" - The 'opener' is 'edit'
if opener ==# 'edit' && fern#internal#drawer#is_drawer()
let drawer = v:true
let opener = s:drawer_opener
if opener ==# 'edit'
if fern#internal#drawer#is_left_drawer()
let drawer = v:true
let opener = s:drawer_left_opener
elseif right && fern#internal#drawer#is_right_drawer()
let drawer = v:true
let opener = s:drawer_right_opener
endif
endif

let expr = fern#util#expand(a:fargs[0])
Expand All @@ -58,7 +67,9 @@ function! fern#internal#command#fern#command(mods, fargs) abort
\ 'path': path,
\})
let fri.authority = drawer
\ ? printf('drawer:%d', tabpagenr())
\ ? right
\ ? printf('drawer-right:%d', tabpagenr())
\ : printf('drawer:%d', tabpagenr())
\ : ''
let fri.query = extend(fri.query, {
\ 'width': width,
Expand All @@ -77,12 +88,13 @@ function! fern#internal#command#fern#command(mods, fargs) abort
endif

let winid_saved = win_getid()
if fri.authority =~# '^drawer:'
if fri.authority =~# '^drawer\(-right\)\?:'
call fern#internal#drawer#open(fri, {
\ 'mods': a:mods,
\ 'toggle': toggle,
\ 'opener': opener,
\ 'stay': stay ? win_getid() : 0,
\ 'right': right,
\})
else
call fern#internal#viewer#open(fri, {
Expand Down
22 changes: 19 additions & 3 deletions autoload/fern/internal/drawer.vim
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
function! fern#internal#drawer#is_drawer(...) abort
let bufname = a:0 ? a:1 : bufname('%')
let fri = fern#fri#parse(bufname)
return fri.scheme ==# 'fern' && fri.authority =~# '^drawer\(-right\)\?:'
endfunction

function! fern#internal#drawer#is_left_drawer(...) abort
let bufname = a:0 ? a:1 : bufname('%')
let fri = fern#fri#parse(bufname)
return fri.scheme ==# 'fern' && fri.authority =~# '^drawer:'
endfunction

function! fern#internal#drawer#is_right_drawer(...) abort
let bufname = a:0 ? a:1 : bufname('%')
let fri = fern#fri#parse(bufname)
return fri.scheme ==# 'fern' && fri.authority =~# '^drawer-right:'
endfunction

function! fern#internal#drawer#resize() abort
let fri = fern#fri#parse(bufname('%'))
let width = str2nr(get(fri.query, 'width', string(g:fern#drawer_width)))
Expand All @@ -13,9 +25,10 @@ endfunction
function! fern#internal#drawer#open(fri, ...) abort
let options = extend({
\ 'toggle': 0,
\ 'right': 0,
\}, a:0 ? a:1 : {},
\)
if s:focus_next()
if s:focus_next(options.right)
if winnr('$') > 1
if options.toggle
close
Expand All @@ -42,9 +55,12 @@ function! fern#internal#drawer#init() abort
setlocal winfixwidth
endfunction

function! s:focus_next() abort
function! s:focus_next(right) abort
let l:Predicator = a:right
\ ? function('fern#internal#drawer#is_right_drawer')
\ : function('fern#internal#drawer#is_left_drawer')
let winnr = fern#internal#window#find(
\ { w -> fern#internal#drawer#is_drawer(bufname(winbufnr(w))) },
\ { w -> l:Predicator(bufname(winbufnr(w))) },
\)
if winnr is# 0
return
Expand Down
36 changes: 31 additions & 5 deletions autoload/fern/internal/drawer/auto_resize.vim
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,19 @@ function! fern#internal#drawer#auto_resize#init() abort
return
endif

augroup fern_internal_drawer_init
autocmd! * <buffer>
autocmd BufEnter <buffer> call s:load_width()
autocmd BufLeave <buffer> call s:save_width()
augroup END
if fern#internal#drawer#is_right_drawer()
augroup fern_internal_drawer_init_right
autocmd! * <buffer>
autocmd WinEnter <buffer> call s:load_width_right()
autocmd WinLeave <buffer> call s:save_width_right()
augroup END
else
augroup fern_internal_drawer_init
autocmd! * <buffer>
autocmd WinEnter <buffer> call s:load_width()
autocmd WinLeave <buffer> call s:save_width()
augroup END
endif
endfunction

if has('nvim')
Expand Down Expand Up @@ -37,3 +45,21 @@ function! s:load_width() abort
execute 'vertical resize' t:fern_drawer_auto_resize_width
endif
endfunction

function! s:save_width_right() abort
if s:should_ignore()
return
endif
let t:fern_drawer_auto_resize_width_right = winwidth(0)
endfunction

function! s:load_width_right() abort
if s:should_ignore()
return
endif
if !exists('t:fern_drawer_auto_resize_width_right')
call fern#internal#drawer#resize()
else
execute 'vertical resize' t:fern_drawer_auto_resize_width_right
endif
endfunction
1 change: 1 addition & 0 deletions autoload/fern/mapping/open.vim
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ function! fern#mapping#open#init(disable_default_mappings) abort
\ fern#smart#drawer(
\ "\<Plug>(fern-action-open:left)",
\ "\<Plug>(fern-action-open:right)",
\ "\<Plug>(fern-action-open:right)",
\ )
nmap <buffer><silent><expr>
\ <Plug>(fern-action-open-or-enter)
Expand Down
16 changes: 12 additions & 4 deletions autoload/fern/smart.vim
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,19 @@ function! fern#smart#leaf(leaf, branch, ...) abort
endif
endfunction

function! fern#smart#drawer(drawer, viewer) abort
function! fern#smart#drawer(drawer, viewer, ...) abort
let helper = fern#helper#new()
return helper.sync.is_drawer()
\ ? a:drawer
\ : a:viewer
if a:0 is# 0
return helper.sync.is_drawer()
\ ? a:drawer
\ : a:viewer
else
return helper.sync.is_drawer()
\ ? helper.sync.is_right_drawer()
\ ? a:viewer
\ : a:drawer
\ : a:1
endif
endfunction

function! fern#smart#scheme(default, schemes) abort
Expand Down
12 changes: 11 additions & 1 deletion doc/fern-develop.txt
Original file line number Diff line number Diff line change
Expand Up @@ -400,9 +400,19 @@ Following methods are executed synchronously.

*fern-develop-helper.sync.is_drawer()*
.sync.is_drawer()
Returns 1 if the fern buffer is shwon in a project drawer. Otherwise
Returns 1 if the fern buffer is shown in a project drawer. Otherwise
it returns 0.

*fern-develop-helper.sync.is_left_drawer()*
.sync.is_left_drawer()
Returns 1 if the fern buffer is shown in a project drawer (left).
Otherwise it returns 0.

*fern-develop-helper.sync.is_right_drawer()*
.sync.is_right_drawer()
Returns 1 if the fern buffer is shown in a project drawer (right).
Otherwise it returns 0.

*fern-develop-helper.sync.get_scheme()*
.sync.get_scheme()
Return |String| which represent the scheme name of the fern buffer.
Expand Down
10 changes: 7 additions & 3 deletions doc/fern.txt
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,7 @@ COMMAND *fern-command*
Note that the command can be followed by a '|' and another command.

*:Fern-drawer*
:Fern {url} -drawer [-width={width}] [-keep] [-toggle] ...
:Fern {url} -drawer [-width={width}] [-keep] [-toggle] [-right]...
Open a fern buffer in project drawer style with the {width}.

If the {width} is specified, the width of the window is regulated to
Expand All @@ -600,16 +600,19 @@ COMMAND *fern-command*
only this window exist. (See |g:fern#drawer_keep|)
If "-toggle" option is specified, existing fern buffer will be closed
rather than opening a new fern buffer when exist.
If "-right" option is specified, the drawer is placed on the right
side.

See |:Fern| for other arguments and options. Note that -opener options
is ignored for project drawer style.

*:FernDo*
:FernDo {expr...} [-drawer] [-stay]
:FernDo {expr...} [-drawer] [-right] [-stay]
Focus a next fern viewer and execute {expr...}. It does nothing if no
next fern viewer is found.
If "-drawer" option is specified, it focus and execute only a project
drawer style fern.
If "-right" option is specified, the drawer on the right side is used.
If "-stay" option is specified, it stay focus after execution.
Note that the command can be followed by a '|' and another command.

Expand Down Expand Up @@ -663,9 +666,10 @@ fern#smart#leaf({leaf}, {collapsed}[, {expanded}])
<
*fern#smart#drawer()*
fern#smart#drawer({drawer}, {explorer})
fern#smart#drawer({drawer}, {drawer-right}, {explorer})
Return one of a given mapping expression determined by the style of
a current buffer. If the current buffer is drawer, the {drawer} is
returned. Otherwise the {explorer} is retunred.
returned. Otherwise the {explorer} is returned.
>
" Perform 'expand' on drawer and 'enter' on explorer
nmap <buffer><expr>
Expand Down