Skip to content

Commit 2de5aff

Browse files
committed
Add -right option to place drawer on right side
Close #272
1 parent 1b234d8 commit 2de5aff

File tree

9 files changed

+124
-29
lines changed

9 files changed

+124
-29
lines changed

autoload/fern/helper/sync.vim

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,20 @@ function! s:sync_is_drawer() abort dict
117117
endfunction
118118
let s:sync.is_drawer = funcref('s:sync_is_drawer')
119119

120+
function! s:sync_is_left_drawer() abort dict
121+
let helper = self.helper
122+
let fern = helper.fern
123+
return fern#internal#drawer#is_left_drawer(bufname(helper.bufnr))
124+
endfunction
125+
let s:sync.is_left_drawer = funcref('s:sync_is_left_drawer')
126+
127+
function! s:sync_is_right_drawer() abort dict
128+
let helper = self.helper
129+
let fern = helper.fern
130+
return fern#internal#drawer#is_right_drawer(bufname(helper.bufnr))
131+
endfunction
132+
let s:sync.is_right_drawer = funcref('s:sync_is_right_drawer')
133+
120134
function! s:sync_get_scheme() abort dict
121135
let helper = self.helper
122136
let fern = helper.fern

autoload/fern/internal/command/do.vim

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,20 @@ function! fern#internal#command#do#command(mods, fargs) abort
33
try
44
let stay = fern#internal#args#pop(a:fargs, 'stay', v:false)
55
let drawer = fern#internal#args#pop(a:fargs, 'drawer', v:false)
6+
let right = fern#internal#args#pop(a:fargs, 'right', v:false)
67

78
if len(a:fargs) is# 0
89
\ || type(stay) isnot# v:t_bool
910
\ || type(drawer) isnot# v:t_bool
10-
throw 'Usage: FernDo {expr...} [-drawer] [-stay]'
11+
\ || type(right) isnot# v:t_bool
12+
throw 'Usage: FernDo {expr...} [-drawer] [-right] [-stay]'
1113
endif
1214

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

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

42-
function! s:predicator(drawer, winnr) abort
44+
function! s:predicator(drawer, right, winnr) abort
4345
let bufname = bufname(winbufnr(a:winnr))
4446
let fri = fern#fri#parse(bufname)
45-
return fri.scheme ==# 'fern'
46-
\ && (!a:drawer || fri.authority =~# '^drawer:')
47+
return fri.scheme ==# 'fern' && (!a:drawer
48+
\ || (!a:right && fri.authority =~# '^drawer:')
49+
\ || (a:right && fri.authority =~# '^drawer-right:')
50+
\)
4751
endfunction

autoload/fern/internal/command/fern.vim

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
let s:Promise = vital#fern#import('Async.Promise')
2-
let s:drawer_opener = 'topleft vsplit'
2+
let s:drawer_left_opener = 'topleft vsplit'
3+
let s:drawer_right_opener = 'botright vsplit'
34

45
function! fern#internal#command#fern#command(mods, fargs) abort
56
try
@@ -8,15 +9,17 @@ function! fern#internal#command#fern#command(mods, fargs) abort
89
let reveal = fern#internal#args#pop(a:fargs, 'reveal', '')
910
let drawer = fern#internal#args#pop(a:fargs, 'drawer', v:false)
1011
if drawer
11-
let opener = s:drawer_opener
1212
let width = fern#internal#args#pop(a:fargs, 'width', '')
1313
let keep = fern#internal#args#pop(a:fargs, 'keep', v:false)
1414
let toggle = fern#internal#args#pop(a:fargs, 'toggle', v:false)
15+
let right = fern#internal#args#pop(a:fargs, 'right', v:false)
16+
let opener = right ? s:drawer_right_opener : s:drawer_left_opener
1517
else
1618
let opener = fern#internal#args#pop(a:fargs, 'opener', g:fern#opener)
1719
let width = ''
1820
let keep = v:false
1921
let toggle = v:false
22+
let right = v:false
2023
endif
2124

2225
if len(a:fargs) isnot# 1
@@ -28,10 +31,11 @@ function! fern#internal#command#fern#command(mods, fargs) abort
2831
\ || type(width) isnot# v:t_string
2932
\ || type(keep) isnot# v:t_bool
3033
\ || type(toggle) isnot# v:t_bool
34+
\ || type(right) isnot# v:t_bool
3135
if empty(drawer)
3236
throw 'Usage: Fern {url} [-opener={opener}] [-stay] [-wait] [-reveal={reveal}]'
3337
else
34-
throw 'Usage: Fern {url} -drawer [-toggle] [-keep] [-width={width}] [-stay] [-wait] [-reveal={reveal}]'
38+
throw 'Usage: Fern {url} -drawer [-right] [-toggle] [-keep] [-width={width}] [-stay] [-wait] [-reveal={reveal}]'
3539
endif
3640
endif
3741

@@ -41,9 +45,14 @@ function! fern#internal#command#fern#command(mods, fargs) abort
4145
" Force project drawer style when
4246
" - The current buffer is project drawer style fern
4347
" - The 'opener' is 'edit'
44-
if opener ==# 'edit' && fern#internal#drawer#is_drawer()
45-
let drawer = v:true
46-
let opener = s:drawer_opener
48+
if opener ==# 'edit'
49+
if fern#internal#drawer#is_left_drawer()
50+
let drawer = v:true
51+
let opener = s:drawer_left_opener
52+
elseif right && fern#internal#drawer#is_right_drawer()
53+
let drawer = v:true
54+
let opener = s:drawer_right_opener
55+
endif
4756
endif
4857

4958
let expr = fern#util#expand(a:fargs[0])
@@ -58,7 +67,9 @@ function! fern#internal#command#fern#command(mods, fargs) abort
5867
\ 'path': path,
5968
\})
6069
let fri.authority = drawer
61-
\ ? printf('drawer:%d', tabpagenr())
70+
\ ? right
71+
\ ? printf('drawer-right:%d', tabpagenr())
72+
\ : printf('drawer:%d', tabpagenr())
6273
\ : ''
6374
let fri.query = extend(fri.query, {
6475
\ 'width': width,
@@ -77,12 +88,13 @@ function! fern#internal#command#fern#command(mods, fargs) abort
7788
endif
7889

7990
let winid_saved = win_getid()
80-
if fri.authority =~# '^drawer:'
91+
if fri.authority =~# '^drawer\(-right\)\?:'
8192
call fern#internal#drawer#open(fri, {
8293
\ 'mods': a:mods,
8394
\ 'toggle': toggle,
8495
\ 'opener': opener,
8596
\ 'stay': stay ? win_getid() : 0,
97+
\ 'right': right,
8698
\})
8799
else
88100
call fern#internal#viewer#open(fri, {

autoload/fern/internal/drawer.vim

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,21 @@
11
function! fern#internal#drawer#is_drawer(...) abort
2+
let bufname = a:0 ? a:1 : bufname('%')
3+
let fri = fern#fri#parse(bufname)
4+
return fri.scheme ==# 'fern' && fri.authority =~# '^drawer\(-right\)\?:'
5+
endfunction
6+
7+
function! fern#internal#drawer#is_left_drawer(...) abort
28
let bufname = a:0 ? a:1 : bufname('%')
39
let fri = fern#fri#parse(bufname)
410
return fri.scheme ==# 'fern' && fri.authority =~# '^drawer:'
511
endfunction
612

13+
function! fern#internal#drawer#is_right_drawer(...) abort
14+
let bufname = a:0 ? a:1 : bufname('%')
15+
let fri = fern#fri#parse(bufname)
16+
return fri.scheme ==# 'fern' && fri.authority =~# '^drawer-right:'
17+
endfunction
18+
719
function! fern#internal#drawer#resize() abort
820
let fri = fern#fri#parse(bufname('%'))
921
let width = str2nr(get(fri.query, 'width', string(g:fern#drawer_width)))
@@ -13,9 +25,10 @@ endfunction
1325
function! fern#internal#drawer#open(fri, ...) abort
1426
let options = extend({
1527
\ 'toggle': 0,
28+
\ 'right': 0,
1629
\}, a:0 ? a:1 : {},
1730
\)
18-
if s:focus_next()
31+
if s:focus_next(options.right)
1932
if winnr('$') > 1
2033
if options.toggle
2134
close
@@ -42,9 +55,12 @@ function! fern#internal#drawer#init() abort
4255
setlocal winfixwidth
4356
endfunction
4457

45-
function! s:focus_next() abort
58+
function! s:focus_next(right) abort
59+
let l:Predicator = a:right
60+
\ ? function('fern#internal#drawer#is_right_drawer')
61+
\ : function('fern#internal#drawer#is_left_drawer')
4662
let winnr = fern#internal#window#find(
47-
\ { w -> fern#internal#drawer#is_drawer(bufname(winbufnr(w))) },
63+
\ { w -> l:Predicator(bufname(winbufnr(w))) },
4864
\)
4965
if winnr is# 0
5066
return

autoload/fern/internal/drawer/auto_resize.vim

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,19 @@ function! fern#internal#drawer#auto_resize#init() abort
33
return
44
endif
55

6-
augroup fern_internal_drawer_init
7-
autocmd! * <buffer>
8-
autocmd BufEnter <buffer> call s:load_width()
9-
autocmd BufLeave <buffer> call s:save_width()
10-
augroup END
6+
if fern#internal#drawer#is_right_drawer()
7+
augroup fern_internal_drawer_init_right
8+
autocmd! * <buffer>
9+
autocmd WinEnter <buffer> call s:load_width_right()
10+
autocmd WinLeave <buffer> call s:save_width_right()
11+
augroup END
12+
else
13+
augroup fern_internal_drawer_init
14+
autocmd! * <buffer>
15+
autocmd WinEnter <buffer> call s:load_width()
16+
autocmd WinLeave <buffer> call s:save_width()
17+
augroup END
18+
endif
1119
endfunction
1220

1321
if has('nvim')
@@ -37,3 +45,21 @@ function! s:load_width() abort
3745
execute 'vertical resize' t:fern_drawer_auto_resize_width
3846
endif
3947
endfunction
48+
49+
function! s:save_width_right() abort
50+
if s:should_ignore()
51+
return
52+
endif
53+
let t:fern_drawer_auto_resize_width_right = winwidth(0)
54+
endfunction
55+
56+
function! s:load_width_right() abort
57+
if s:should_ignore()
58+
return
59+
endif
60+
if !exists('t:fern_drawer_auto_resize_width_right')
61+
call fern#internal#drawer#resize()
62+
else
63+
execute 'vertical resize' t:fern_drawer_auto_resize_width_right
64+
endif
65+
endfunction

autoload/fern/mapping/open.vim

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ function! fern#mapping#open#init(disable_default_mappings) abort
2424
\ fern#smart#drawer(
2525
\ "\<Plug>(fern-action-open:left)",
2626
\ "\<Plug>(fern-action-open:right)",
27+
\ "\<Plug>(fern-action-open:right)",
2728
\ )
2829
nmap <buffer><silent><expr>
2930
\ <Plug>(fern-action-open-or-enter)

autoload/fern/smart.vim

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,19 @@ function! fern#smart#leaf(leaf, branch, ...) abort
1313
endif
1414
endfunction
1515

16-
function! fern#smart#drawer(drawer, viewer) abort
16+
function! fern#smart#drawer(drawer, viewer, ...) abort
1717
let helper = fern#helper#new()
18-
return helper.sync.is_drawer()
19-
\ ? a:drawer
20-
\ : a:viewer
18+
if a:0 is# 0
19+
return helper.sync.is_drawer()
20+
\ ? a:drawer
21+
\ : a:viewer
22+
else
23+
return helper.sync.is_drawer()
24+
\ ? helper.sync.is_right_drawer()
25+
\ ? a:viewer
26+
\ : a:drawer
27+
\ : a:1
28+
endif
2129
endfunction
2230

2331
function! fern#smart#scheme(default, schemes) abort

doc/fern-develop.txt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,9 +400,19 @@ Following methods are executed synchronously.
400400

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

406+
*fern-develop-helper.sync.is_left_drawer()*
407+
.sync.is_left_drawer()
408+
Returns 1 if the fern buffer is shown in a project drawer (left).
409+
Otherwise it returns 0.
410+
411+
*fern-develop-helper.sync.is_right_drawer()*
412+
.sync.is_right_drawer()
413+
Returns 1 if the fern buffer is shown in a project drawer (right).
414+
Otherwise it returns 0.
415+
406416
*fern-develop-helper.sync.get_scheme()*
407417
.sync.get_scheme()
408418
Return |String| which represent the scheme name of the fern buffer.

doc/fern.txt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -591,7 +591,7 @@ COMMAND *fern-command*
591591
Note that the command can be followed by a '|' and another command.
592592

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

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

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

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

@@ -663,9 +666,10 @@ fern#smart#leaf({leaf}, {collapsed}[, {expanded}])
663666
<
664667
*fern#smart#drawer()*
665668
fern#smart#drawer({drawer}, {explorer})
669+
fern#smart#drawer({drawer}, {drawer-right}, {explorer})
666670
Return one of a given mapping expression determined by the style of
667671
a current buffer. If the current buffer is drawer, the {drawer} is
668-
returned. Otherwise the {explorer} is retunred.
672+
returned. Otherwise the {explorer} is returned.
669673
>
670674
" Perform 'expand' on drawer and 'enter' on explorer
671675
nmap <buffer><expr>

0 commit comments

Comments
 (0)