From 3118afc4d76cd18d6bfc37d04f0102a8830ab65e Mon Sep 17 00:00:00 2001 From: Michael Chris Lopez Date: Mon, 26 Jul 2021 12:23:10 +0800 Subject: [PATCH 01/20] make use of native border support --- autoload/nnn.vim | 113 +++++++++++------------------------------------ 1 file changed, 27 insertions(+), 86 deletions(-) diff --git a/autoload/nnn.vim b/autoload/nnn.vim index 3ff8d6d..cbd2945 100644 --- a/autoload/nnn.vim +++ b/autoload/nnn.vim @@ -1,5 +1,5 @@ -let s:temp_file = "" -let s:action = "" +let s:temp_file = '' +let s:action = '' let s:tbuf = 0 let s:local_ses = 'nnn_vim_' @@ -75,12 +75,8 @@ function! s:eval_temp_file(opts) endfunction function! s:popup(opts, term_opts) - " Support ambiwidth == 'double' - let ambidouble = &ambiwidth == 'double' ? 2 : 1 - " Size and position let width = min([max([0, float2nr(&columns * a:opts.width)]), &columns]) - let width += width % ambidouble let height = min([max([0, float2nr(&lines * a:opts.height)]), &lines - has('nvim')]) let row = float2nr(get(a:opts, 'yoffset', 0.5) * (&lines - height)) let col = float2nr(get(a:opts, 'xoffset', 0.5) * (&columns - width)) @@ -91,80 +87,35 @@ function! s:popup(opts, term_opts) let row += !has('nvim') let col += !has('nvim') - " Border style - let style = tolower(get(a:opts, 'border', 'rounded')) - if !has_key(a:opts, 'border') && !get(a:opts, 'rounded', 1) - let style = 'sharp' - endif - - if style =~ 'vertical\|left\|right' - let mid = style == 'vertical' ? '│' .. repeat(' ', width - 2 * ambidouble) .. '│' : - \ style == 'left' ? '│' .. repeat(' ', width - 1 * ambidouble) - \ : repeat(' ', width - 1 * ambidouble) .. '│' - let border = repeat([mid], height) - let shift = { 'row': 0, 'col': style == 'right' ? 0 : 2, 'width': style == 'vertical' ? -4 : -2, 'height': 0 } - elseif style =~ 'horizontal\|top\|bottom' - let hor = repeat('─', width / ambidouble) - let mid = repeat(' ', width) - let border = style == 'horizontal' ? [hor] + repeat([mid], height - 2) + [hor] : - \ style == 'top' ? [hor] + repeat([mid], height - 1) - \ : repeat([mid], height - 1) + [hor] - let shift = { 'row': style == 'bottom' ? 0 : 1, 'col': 0, 'width': 0, 'height': style == 'horizontal' ? -2 : -1 } - else - let edges = style == 'sharp' ? ['┌', '┐', '└', '┘'] : ['╭', '╮', '╰', '╯'] - let bar = repeat('─', width / ambidouble - 2) - let top = edges[0] .. bar .. edges[1] - let mid = '│' .. repeat(' ', width - 2 * ambidouble) .. '│' - let bot = edges[2] .. bar .. edges[3] - let border = [top] + repeat([mid], height - 2) + [bot] - let shift = { 'row': 1, 'col': 2, 'width': -4, 'height': -2 } - endif - - let highlight = get(a:opts, 'highlight', 'Comment') - let l:frame = s:create_popup(highlight, { - \ 'row': row, 'col': col, 'width': width, 'height': height, 'border': border - \ }, a:term_opts) - let l:term_win = s:create_popup('Normal', { - \ 'row': row + shift.row, 'col': col + shift.col, 'width': width + shift.width, 'height': height + shift.height - \ }, a:term_opts) - if has('nvim') - execute 'autocmd BufWipeout bwipeout '..l:frame.buf - endif - - return { 'frame': l:frame, 'term': l:term_win } -endfunction + let l:border = get(a:opts, 'border', 'rounded') + let l:highlight = get(a:opts, 'highlight', 'Comment') -function s:create_popup(hl, opts, term_opts) if has('nvim') - let l:temp_buf = nvim_create_buf(v:false, v:true) - let l:opts = extend({'relative': 'editor', 'style': 'minimal'}, a:opts) - let l:border = has_key(l:opts, 'border') ? remove(l:opts, 'border') : [] - let l:win = nvim_open_win(l:temp_buf, v:true, l:opts) - call setwinvar(l:win, '&winhighlight', 'NormalFloat:'..a:hl) + let l:win = nvim_open_win(nvim_create_buf(v:false, v:true), v:true, { + \ 'row': row, + \ 'col': col, + \ 'width': width, + \ 'height': height, + \ 'border': l:border == 'rounded' ? 'rounded' : 'single', + \ 'relative': 'editor', + \ 'style': 'minimal' + \ }) + call setwinvar(l:win, '&winhighlight', 'NormalFloat:Normal') call setwinvar(l:win, '&colorcolumn', '') - if has_key(a:opts, 'border') - call nvim_buf_set_lines(l:temp_buf, 0, -1, v:true, l:border) - return { 'buf': l:temp_buf, 'winhandle': l:win } - else - let l:tbuf = s:create_term_buf(a:term_opts) - return { 'buf': l:tbuf, 'winhandle': l:win } - endif + return { 'term': { 'buf': s:create_term_buf(a:term_opts), 'winhandle': l:win } } else - let l:is_frame = has_key(a:opts, 'border') - let l:buf = l:is_frame ? '' : s:create_term_buf(extend(a:term_opts, { 'curwin': 0, 'hidden': 1 })) - let l:win = popup_create(l:buf, { - \ 'line': a:opts.row, - \ 'col': a:opts.col, - \ 'minwidth': a:opts.width, - \ 'minheight': a:opts.height, - \ 'zindex': 50 - l:is_frame, + let l:buf = s:create_term_buf(extend(a:term_opts, #{ curwin: 0, hidden: 1 })) + let l:borderchars = l:.border == 'rounded' ? ['─', '│', '─', '│', '╭', '╮','╯' , '╰'] : ['─', '│', '─', '│', '┌', '┐', '┘', '└'] + let l:win = popup_create(l:buf, #{ + \ line: row, + \ col: col, + \ minwidth: width, + \ minheight: height, + \ border: [], + \ borderhighlight: [l:highlight], + \ borderchars: l:borderchars, \ }) - - if l:is_frame - call setwinvar(l:win, '&wincolor', a:hl) - call setbufline(winbufnr(l:win), 1, a:opts.border) - endif - return { 'buf': l:buf, 'winhandle': l:win } + return #{ term: { buf: l:buf, winhandle: l:win } } endif endfunction @@ -214,26 +165,16 @@ function! s:switch_back(opts, Cmd) if nvim_win_is_valid(l:term_wins.term.winhandle) call nvim_win_close(l:term_wins.term.winhandle, v:false) endif - if nvim_win_is_valid(l:term_wins.frame.winhandle) - call nvim_win_close(l:term_wins.frame.winhandle, v:false) - endif if bufexists(l:term_wins.term.buf) execute 'bwipeout!' l:term_wins.term.buf endif - if bufexists(l:term_wins.frame.buf) - execute 'bwipeout!' l:term_wins.frame.buf - endif else call popup_close(l:term_wins.term.winhandle) - call popup_close(l:term_wins.frame.winhandle) if bufexists(l:term_wins.term.buf) execute 'bwipeout!' l:term_wins.term.buf endif - if bufexists(l:term_wins.frame.buf) - execute 'bwipeout!' l:term_wins.frame.buf - endif endif endif @@ -322,7 +263,7 @@ function! s:build_window(layout, term_opts) if s:present(a:layout, 'window') if type(a:layout.window) == v:t_dict if !has('nvim') && !has('patch-8.2.191') - throw 'Neovim is required for floating window or Vim with patch-8.2.191' + throw 'Neovim 0.5+ or Vim with patch-8.2.191+ is required for floating window' end return s:popup(a:layout.window, a:term_opts) else From 0655f68a473e267771242bab4f23eec5707c1994 Mon Sep 17 00:00:00 2001 From: Michael Chris Lopez Date: Mon, 26 Jul 2021 12:24:43 +0800 Subject: [PATCH 02/20] fix vim object --- autoload/nnn.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autoload/nnn.vim b/autoload/nnn.vim index cbd2945..09893c9 100644 --- a/autoload/nnn.vim +++ b/autoload/nnn.vim @@ -115,7 +115,7 @@ function! s:popup(opts, term_opts) \ borderhighlight: [l:highlight], \ borderchars: l:borderchars, \ }) - return #{ term: { buf: l:buf, winhandle: l:win } } + return #{ term: #{ buf: l:buf, winhandle: l:win } } endif endfunction From a68a777160027297487d6970814587d80eb8932d Mon Sep 17 00:00:00 2001 From: Michael Chris Lopez Date: Mon, 26 Jul 2021 12:56:12 +0800 Subject: [PATCH 03/20] consistent border highlight between vim and nvim --- autoload/nnn.vim | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/autoload/nnn.vim b/autoload/nnn.vim index 09893c9..b38e7e5 100644 --- a/autoload/nnn.vim +++ b/autoload/nnn.vim @@ -19,10 +19,10 @@ endfunction function! nnn#select_action(action) abort let s:action = a:action " quit nnn - if has("nvim") - call feedkeys("i\") + if has('nvim') + call feedkeys('i\') else - call term_sendkeys(s:tbuf, "\") + call term_sendkeys(s:tbuf, '\') endif endfunction @@ -70,7 +70,7 @@ function! s:eval_temp_file(opts) endfor endif - let s:action = "" " reset action + let s:action = '' " reset action redraw! endfunction @@ -91,12 +91,17 @@ function! s:popup(opts, term_opts) let l:highlight = get(a:opts, 'highlight', 'Comment') if has('nvim') + let l:borderchars = map(l:border == 'rounded' + \ ? ['╭', '─' ,'╮', '│', '╯', '─', '╰', '│' ] + \ : ['┌', '─' ,'┐', '│', '┘', '─', '└', '│' ], + \ {_, val -> [v:val, l:highlight]}) + let l:win = nvim_open_win(nvim_create_buf(v:false, v:true), v:true, { \ 'row': row, \ 'col': col, \ 'width': width, \ 'height': height, - \ 'border': l:border == 'rounded' ? 'rounded' : 'single', + \ 'border': l:borderchars, \ 'relative': 'editor', \ 'style': 'minimal' \ }) @@ -149,7 +154,7 @@ function! s:switch_back(opts, Cmd) execute 'keepalt b' l:buf " in case nnn was used to delete file in open buffer catch /E211: File/ - let junk = input(matchstr(string(v:exception), 'E211: .*$') . "\nPress ENTER to continue") + let junk = input(matchstr(string(v:exception), 'E211: .*$') . '\nPress ENTER to continue') endtry if bufexists(l:term_wins.term.buf) execute 'bwipeout!' l:term_wins.term.buf From 84039fd90f3fa723abbb32bc4b72eeeeba430004 Mon Sep 17 00:00:00 2001 From: Michael Chris Lopez Date: Mon, 26 Jul 2021 13:10:53 +0800 Subject: [PATCH 04/20] simplify file filtering --- autoload/nnn.vim | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/autoload/nnn.vim b/autoload/nnn.vim index b38e7e5..eb4be9c 100644 --- a/autoload/nnn.vim +++ b/autoload/nnn.vim @@ -130,17 +130,18 @@ function! s:extract_filenames() return [] endif - let l:file = readfile(s:temp_file) - if empty(l:file) + let l:files = readfile(s:temp_file) + if empty(l:files) return [] endif - let l:names = uniq(filter(l:file, '!isdirectory(v:val) && filereadable(v:val)')) - if empty(l:names) || strlen(l:names[0]) <= 0 + uniq(filter(l:files, {_, val -> !isdirectory(val) && filereadable(val) })) + + if empty(l:files) || strlen(l:files[0]) <= 0 return [] endif - return l:names + return l:files endfunction function! s:switch_back(opts, Cmd) From 2fb90d4a5d69e7826a1ef4ce07a15f9b3185995f Mon Sep 17 00:00:00 2001 From: Michael Chris Lopez Date: Mon, 26 Jul 2021 13:18:52 +0800 Subject: [PATCH 05/20] fix select action --- autoload/nnn.vim | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/autoload/nnn.vim b/autoload/nnn.vim index eb4be9c..16aaae4 100644 --- a/autoload/nnn.vim +++ b/autoload/nnn.vim @@ -1,6 +1,7 @@ let s:temp_file = '' let s:action = '' let s:tbuf = 0 +let s:nnn_conf_dir = (!empty($XDG_CONFIG_HOME) ? $XDG_CONFIG_HOME : $HOME.'/.config') . '/nnn' let s:local_ses = 'nnn_vim_' " Add timestamp for convenience @@ -20,9 +21,9 @@ function! nnn#select_action(action) abort let s:action = a:action " quit nnn if has('nvim') - call feedkeys('i\') + call feedkeys("i\") else - call term_sendkeys(s:tbuf, '\') + call term_sendkeys(s:tbuf, "\") endif endfunction @@ -47,6 +48,26 @@ function! s:calc_size(val, max) endif endfunction +function! s:extract_filenames() + if !filereadable(s:temp_file) + return [] + endif + + let l:files = readfile(s:temp_file) + if empty(l:files) + return [] + endif + + call uniq(filter(l:files, {_, val -> !isdirectory(val) && filereadable(val) })) + + if empty(l:files) || strlen(l:files[0]) <= 0 + return [] + endif + + echom string(l:files) + return l:files +endfunction + function! s:eval_temp_file(opts) let l:Cmd = type(s:action) == v:t_func || strlen(s:action) > 0 ? s:action : a:opts.edit @@ -125,25 +146,6 @@ function! s:popup(opts, term_opts) endfunction -function! s:extract_filenames() - if !filereadable(s:temp_file) - return [] - endif - - let l:files = readfile(s:temp_file) - if empty(l:files) - return [] - endif - - uniq(filter(l:files, {_, val -> !isdirectory(val) && filereadable(val) })) - - if empty(l:files) || strlen(l:files[0]) <= 0 - return [] - endif - - return l:files -endfunction - function! s:switch_back(opts, Cmd) let l:buf = a:opts.ppos.buf let l:layout = a:opts.layout @@ -234,8 +236,6 @@ function! s:create_term_buf(opts) endif endfunction -let s:nnn_conf_dir = (!empty($XDG_CONFIG_HOME) ? $XDG_CONFIG_HOME : $HOME.'/.config') . '/nnn' - function! s:create_on_exit_callback(opts) let l:opts = a:opts function! s:callback(id, code, ...) closure From cbd97425486340394fd181cb28f4230f87e2a079 Mon Sep 17 00:00:00 2001 From: Michael Chris Lopez Date: Mon, 26 Jul 2021 13:38:45 +0800 Subject: [PATCH 06/20] default layout is window --- autoload/nnn.vim | 14 +++----------- plugin/nnn.vim | 8 +++++++- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/autoload/nnn.vim b/autoload/nnn.vim index 16aaae4..e1384f3 100644 --- a/autoload/nnn.vim +++ b/autoload/nnn.vim @@ -173,16 +173,11 @@ function! s:switch_back(opts, Cmd) if nvim_win_is_valid(l:term_wins.term.winhandle) call nvim_win_close(l:term_wins.term.winhandle, v:false) endif - - if bufexists(l:term_wins.term.buf) - execute 'bwipeout!' l:term_wins.term.buf - endif else call popup_close(l:term_wins.term.winhandle) - - if bufexists(l:term_wins.term.buf) - execute 'bwipeout!' l:term_wins.term.buf - endif + endif + if bufexists(l:term_wins.term.buf) + execute 'bwipeout!' l:term_wins.term.buf endif endif @@ -268,9 +263,6 @@ function! s:build_window(layout, term_opts) if s:present(a:layout, 'window') if type(a:layout.window) == v:t_dict - if !has('nvim') && !has('patch-8.2.191') - throw 'Neovim 0.5+ or Vim with patch-8.2.191+ is required for floating window' - end return s:popup(a:layout.window, a:term_opts) else throw 'Invalid layout' diff --git a/plugin/nnn.vim b/plugin/nnn.vim index e449b0a..5b78b51 100644 --- a/plugin/nnn.vim +++ b/plugin/nnn.vim @@ -8,7 +8,13 @@ if !(exists("g:nnn#set_default_mappings")) endif if !(exists("g:nnn#layout")) - let g:nnn#layout = 'enew' + if has('nvim-0.5') || !has('patch-8.2.191') + let g:nnn#layout = { 'window': { 'width': 0.9, 'height': 0.6 } } + else + let g:nnn#layout = 'enew' + endif +elseif type(g:nnn#layout.window) == v:t_dict && !(has('nvim-0.5') || !has('patch-8.2.191')) + throw 'Neovim 0.5+ or Vim with patch-8.2.191+ is required for floating window' endif if !(exists("g:nnn#action")) From dd16e2d5272afc2b3ec14cbebb7f7e13aacb5026 Mon Sep 17 00:00:00 2001 From: Michael Chris Lopez Date: Mon, 26 Jul 2021 13:41:15 +0800 Subject: [PATCH 07/20] fix window feature detect error --- autoload/nnn.vim | 3 +++ plugin/nnn.vim | 2 -- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/autoload/nnn.vim b/autoload/nnn.vim index e1384f3..a9e22f0 100644 --- a/autoload/nnn.vim +++ b/autoload/nnn.vim @@ -263,6 +263,9 @@ function! s:build_window(layout, term_opts) if s:present(a:layout, 'window') if type(a:layout.window) == v:t_dict + if !has('nvim') && !has('patch-8.2.191') + throw 'Neovim 0.5+ or Vim with patch-8.2.191+ is required for floating window' + endif return s:popup(a:layout.window, a:term_opts) else throw 'Invalid layout' diff --git a/plugin/nnn.vim b/plugin/nnn.vim index 5b78b51..bbd78c5 100644 --- a/plugin/nnn.vim +++ b/plugin/nnn.vim @@ -13,8 +13,6 @@ if !(exists("g:nnn#layout")) else let g:nnn#layout = 'enew' endif -elseif type(g:nnn#layout.window) == v:t_dict && !(has('nvim-0.5') || !has('patch-8.2.191')) - throw 'Neovim 0.5+ or Vim with patch-8.2.191+ is required for floating window' endif if !(exists("g:nnn#action")) From 3d2cd4e07df968de5c36c734721179a0ad093835 Mon Sep 17 00:00:00 2001 From: Michael Chris Lopez Date: Mon, 26 Jul 2021 13:44:29 +0800 Subject: [PATCH 08/20] simple global var for floating window support --- autoload/nnn.vim | 2 +- plugin/nnn.vim | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/autoload/nnn.vim b/autoload/nnn.vim index a9e22f0..98a6a11 100644 --- a/autoload/nnn.vim +++ b/autoload/nnn.vim @@ -263,7 +263,7 @@ function! s:build_window(layout, term_opts) if s:present(a:layout, 'window') if type(a:layout.window) == v:t_dict - if !has('nvim') && !has('patch-8.2.191') + if !g:nnn#has_floating_window_support throw 'Neovim 0.5+ or Vim with patch-8.2.191+ is required for floating window' endif return s:popup(a:layout.window, a:term_opts) diff --git a/plugin/nnn.vim b/plugin/nnn.vim index bbd78c5..d869edd 100644 --- a/plugin/nnn.vim +++ b/plugin/nnn.vim @@ -7,8 +7,10 @@ if !(exists("g:nnn#set_default_mappings")) let g:nnn#set_default_mappings = 1 endif +let g:nnn#has_floating_window_support = has('nvim-0.5') || !has('patch-8.2.191') + if !(exists("g:nnn#layout")) - if has('nvim-0.5') || !has('patch-8.2.191') + if g:nnn#has_floating_window_support let g:nnn#layout = { 'window': { 'width': 0.9, 'height': 0.6 } } else let g:nnn#layout = 'enew' From 74aa9f07ea314696399481ca88db9a34ba9f8849 Mon Sep 17 00:00:00 2001 From: Michael Chris Lopez Date: Mon, 26 Jul 2021 14:20:31 +0800 Subject: [PATCH 09/20] remove extra dict layer --- autoload/nnn.vim | 83 +++++++++++++++++++----------------------------- 1 file changed, 33 insertions(+), 50 deletions(-) diff --git a/autoload/nnn.vim b/autoload/nnn.vim index 98a6a11..68a8e9c 100644 --- a/autoload/nnn.vim +++ b/autoload/nnn.vim @@ -128,10 +128,12 @@ function! s:popup(opts, term_opts) \ }) call setwinvar(l:win, '&winhighlight', 'NormalFloat:Normal') call setwinvar(l:win, '&colorcolumn', '') - return { 'term': { 'buf': s:create_term_buf(a:term_opts), 'winhandle': l:win } } + return { 'buf': s:create_term_buf(a:term_opts), 'winhandle': l:win } else let l:buf = s:create_term_buf(extend(a:term_opts, #{ curwin: 0, hidden: 1 })) - let l:borderchars = l:.border == 'rounded' ? ['─', '│', '─', '│', '╭', '╮','╯' , '╰'] : ['─', '│', '─', '│', '┌', '┐', '┘', '└'] + let l:borderchars = l:.border == 'rounded' + \ ? ['─', '│', '─', '│', '╭', '╮','╯' , '╰'] + \ : ['─', '│', '─', '│', '┌', '┐', '┘', '└'] let l:win = popup_create(l:buf, #{ \ line: row, \ col: col, @@ -141,7 +143,7 @@ function! s:popup(opts, term_opts) \ borderhighlight: [l:highlight], \ borderchars: l:borderchars, \ }) - return #{ term: #{ buf: l:buf, winhandle: l:win } } + return #{ buf: l:buf, winhandle: l:win } endif endfunction @@ -149,18 +151,13 @@ endfunction function! s:switch_back(opts, Cmd) let l:buf = a:opts.ppos.buf let l:layout = a:opts.layout - let l:term_wins = a:opts.term_wins + let l:term = a:opts.term " when split explorer if type(l:layout) == v:t_string && l:layout == 'enew' && bufexists(l:buf) - try - execute 'keepalt b' l:buf - " in case nnn was used to delete file in open buffer - catch /E211: File/ - let junk = input(matchstr(string(v:exception), 'E211: .*$') . '\nPress ENTER to continue') - endtry - if bufexists(l:term_wins.term.buf) - execute 'bwipeout!' l:term_wins.term.buf + execute 'keepalt b' l:buf + if bufexists(l:term.buf) + execute 'bwipeout!' l:term.buf endif endif @@ -170,14 +167,14 @@ function! s:switch_back(opts, Cmd) endif if has('nvim') " Making sure we close the windows when sometimes they linger - if nvim_win_is_valid(l:term_wins.term.winhandle) - call nvim_win_close(l:term_wins.term.winhandle, v:false) + if nvim_win_is_valid(l:term.winhandle) + call nvim_win_close(l:term.winhandle, v:false) endif else - call popup_close(l:term_wins.term.winhandle) + call popup_close(l:term.winhandle) endif - if bufexists(l:term_wins.term.buf) - execute 'bwipeout!' l:term_wins.term.buf + if bufexists(l:term.buf) + execute 'bwipeout!' l:term.buf endif endif @@ -189,17 +186,17 @@ function! s:switch_back(opts, Cmd) " delete the nnn window and buffer try if has('nvim') - if nvim_win_is_valid(l:term_wins.term.winhandle) - call nvim_win_close(l:term_wins.term.winhandle, v:false) + if nvim_win_is_valid(l:term.winhandle) + call nvim_win_close(l:term.winhandle, v:false) endif else - execute win_id2win(l:term_wins.term.winhandle) . 'close' + execute win_id2win(l:term.winhandle) . 'close' endif catch /E444: Cannot close last window/ " In case Vim complains it is the last window, fail silently. endtry - if bufexists(l:term_wins.term.buf) - execute 'bwipeout!' l:term_wins.term.buf + if bufexists(l:term.buf) + execute 'bwipeout!' l:term.buf endif silent! execute 'tabnext' a:opts.ppos.tab silent! execute a:opts.ppos.win.'wincmd w' @@ -215,19 +212,12 @@ function! s:create_term_buf(opts) startinsert return bufnr('') else - let l:curwin = get(a:opts, 'curwin', 1) - let l:hidden = get(a:opts, 'hidden', 0) - let l:Exit_cb = get(a:opts, 'on_exit') - let l:tbuf = term_start([g:nnn#shell, &shellcmdflag, a:opts.cmd], { + return term_start([g:nnn#shell, &shellcmdflag, a:opts.cmd], { + \ 'curwin': get(a:opts, 'curwin', 1), + \ 'hidden': get(a:opts, 'hidden', 0), \ 'env': { 'NNN_SEL': s:temp_file }, - \ 'curwin': l:curwin, - \ 'hidden': l:hidden, - \ 'exit_cb': l:Exit_cb + \ 'exit_cb': get(a:opts, 'on_exit') \ }) - if !has('patch-8.0.1261') && !has('nvim') - call term_wait(l:tbuf, 20) - endif - return l:tbuf endif endfunction @@ -253,18 +243,10 @@ function! s:create_on_exit_callback(opts) endfunction function! s:build_window(layout, term_opts) - if type(a:layout) == v:t_string - execute 'keepalt ' . a:layout - return { 'term': { - \ 'buf': s:create_term_buf(a:term_opts), - \ 'winhandle': win_getid() - \ } } - endif - if s:present(a:layout, 'window') if type(a:layout.window) == v:t_dict if !g:nnn#has_floating_window_support - throw 'Neovim 0.5+ or Vim with patch-8.2.191+ is required for floating window' + throw 'Your vim/neovim version does not support floating window/popup.' endif return s:popup(a:layout.window, a:term_opts) else @@ -272,6 +254,11 @@ function! s:build_window(layout, term_opts) endif endif + if type(a:layout) == v:t_string + execute 'keepalt ' . a:layout + return { 'buf': s:create_term_buf(a:term_opts), 'winhandle': win_getid() } + endif + let l:directions = { \ 'up': ['topleft', 'resize', &lines], \ 'down': ['botright', 'resize', &lines], @@ -283,10 +270,7 @@ function! s:build_window(layout, term_opts) let l:size = a:layout[key] let [l:cmd, l:resz, l:max]= l:directions[key] execute l:cmd . s:calc_size(l:size, l:max) . 'new' - return { 'term': { - \ 'buf': s:create_term_buf(a:term_opts), - \ 'winhandle': win_getid() - \ } } + return { 'buf': s:create_term_buf(a:term_opts), 'winhandle': win_getid() } endif endfor @@ -317,12 +301,11 @@ function! nnn#pick(...) abort let l:opts.layout = l:layout let l:opts.ppos = { 'buf': bufnr(''), 'win': winnr(), 'tab': tabpagenr() } - let l:On_exit = s:create_on_exit_callback(l:opts) - let l:opts.term_wins = s:build_window(l:layout, { 'cmd': l:cmd, 'on_exit': l:On_exit }) - let s:tbuf = l:opts.term_wins.term.buf + let l:opts.term = s:build_window(l:layout, { 'cmd': l:cmd, 'on_exit': s:create_on_exit_callback(l:opts) }) + let s:tbuf = l:opts.term.buf setfiletype nnn - if g:nnn#statusline && type(l:layout) == v:t_string + if g:nnn#statusline && !s:present(l:layout, 'window') call s:statusline() endif endfunction From ea8961252c889cc18f65b078d987158aa034cc9f Mon Sep 17 00:00:00 2001 From: Michael Chris Lopez Date: Mon, 26 Jul 2021 14:20:51 +0800 Subject: [PATCH 10/20] fix nnn#has_floating_window_support --- plugin/nnn.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/nnn.vim b/plugin/nnn.vim index d869edd..c88ab94 100644 --- a/plugin/nnn.vim +++ b/plugin/nnn.vim @@ -7,7 +7,7 @@ if !(exists("g:nnn#set_default_mappings")) let g:nnn#set_default_mappings = 1 endif -let g:nnn#has_floating_window_support = has('nvim-0.5') || !has('patch-8.2.191') +let g:nnn#has_floating_window_support = has('nvim-0.5') || has('patch-8.2.191') if !(exists("g:nnn#layout")) if g:nnn#has_floating_window_support From 965ccf37710b40a050ac214b247c1df720dce472 Mon Sep 17 00:00:00 2001 From: Michael Chris Lopez Date: Mon, 26 Jul 2021 14:21:10 +0800 Subject: [PATCH 11/20] update window layout doc --- doc/nnn.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/nnn.txt b/doc/nnn.txt index 16563ca..a8b9da3 100644 --- a/doc/nnn.txt +++ b/doc/nnn.txt @@ -95,8 +95,8 @@ g:nnn#set_default_mappings *g:nnn#set_default_mappings* < g:nnn#layout *g:nnn#layout* - Default: 'enew' - Display type for the n³ buffer. Default is |enew|, which + Default: { 'window': { 'width': 0.9, 'height': 0.6 } } + Display type for the n³ buffer. Default is a floating window. |enew| has a special behavior to act as a "split explorer" reusing the current window and brings back the last buffer if nothing is selected. @@ -113,7 +113,7 @@ g:nnn#layout *g:nnn#layout* " Options: " width, height, yoffset, xoffset : number " highlight : highlight group assign to the border - " border : border style - 'rounded' / 'sharp' / 'horizontal' / 'vertical' / 'top' / 'bottom' / 'left' / 'right' + " border : border style - 'rounded' / 'sharp' < g:nnn#action *g:nnn#action* From f02a164a310e762e782c6a469b75d9663d77e9c7 Mon Sep 17 00:00:00 2001 From: Michael Chris Lopez Date: Mon, 26 Jul 2021 14:34:19 +0800 Subject: [PATCH 12/20] small cleanup --- autoload/nnn.vim | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/autoload/nnn.vim b/autoload/nnn.vim index 68a8e9c..b12a4ac 100644 --- a/autoload/nnn.vim +++ b/autoload/nnn.vim @@ -165,11 +165,9 @@ function! s:switch_back(opts, Cmd) if type(l:layout.window) != v:t_dict throw 'Invalid layout' endif - if has('nvim') - " Making sure we close the windows when sometimes they linger - if nvim_win_is_valid(l:term.winhandle) - call nvim_win_close(l:term.winhandle, v:false) - endif + " Making sure we close the windows when sometimes they linger + if has('nvim') && nvim_win_is_valid(l:term.winhandle) + call nvim_win_close(l:term.winhandle, v:false) else call popup_close(l:term.winhandle) endif @@ -185,10 +183,8 @@ function! s:switch_back(opts, Cmd) \ || (type(l:layout) == v:t_string && l:layout != 'enew')) " delete the nnn window and buffer try - if has('nvim') - if nvim_win_is_valid(l:term.winhandle) - call nvim_win_close(l:term.winhandle, v:false) - endif + if has('nvim') && nvim_win_is_valid(l:term.winhandle) + call nvim_win_close(l:term.winhandle, v:false) else execute win_id2win(l:term.winhandle) . 'close' endif From 7fb34b3f1d983adb7b82f0e9f3f5818dab9acaed Mon Sep 17 00:00:00 2001 From: Michael Chris Lopez Date: Mon, 26 Jul 2021 15:07:07 +0800 Subject: [PATCH 13/20] fix switch back buffer --- autoload/nnn.vim | 35 +++++++---------------------------- 1 file changed, 7 insertions(+), 28 deletions(-) diff --git a/autoload/nnn.vim b/autoload/nnn.vim index b12a4ac..75a69f3 100644 --- a/autoload/nnn.vim +++ b/autoload/nnn.vim @@ -64,7 +64,6 @@ function! s:extract_filenames() return [] endif - echom string(l:files) return l:files endfunction @@ -147,7 +146,6 @@ function! s:popup(opts, term_opts) endif endfunction - function! s:switch_back(opts, Cmd) let l:buf = a:opts.ppos.buf let l:layout = a:opts.layout @@ -156,12 +154,7 @@ function! s:switch_back(opts, Cmd) " when split explorer if type(l:layout) == v:t_string && l:layout == 'enew' && bufexists(l:buf) execute 'keepalt b' l:buf - if bufexists(l:term.buf) - execute 'bwipeout!' l:term.buf - endif - endif - - if s:present(l:layout, 'window') + elseif s:present(l:layout, 'window') if type(l:layout.window) != v:t_dict throw 'Invalid layout' endif @@ -171,32 +164,19 @@ function! s:switch_back(opts, Cmd) else call popup_close(l:term.winhandle) endif - if bufexists(l:term.buf) - execute 'bwipeout!' l:term.buf - endif endif " don't switch when action = 'edit' and just retain the window " don't switch when layout = 'enew' for split explorer feature if (type(a:Cmd) == v:t_string && a:Cmd != 'edit') - \ || (type(l:layout) != v:t_string - \ || (type(l:layout) == v:t_string && l:layout != 'enew')) - " delete the nnn window and buffer - try - if has('nvim') && nvim_win_is_valid(l:term.winhandle) - call nvim_win_close(l:term.winhandle, v:false) - else - execute win_id2win(l:term.winhandle) . 'close' - endif - catch /E444: Cannot close last window/ - " In case Vim complains it is the last window, fail silently. - endtry - if bufexists(l:term.buf) - execute 'bwipeout!' l:term.buf - endif + \ || (type(l:layout) != v:t_string || (type(l:layout) == v:t_string && l:layout != 'enew')) silent! execute 'tabnext' a:opts.ppos.tab silent! execute a:opts.ppos.win.'wincmd w' endif + + if bufexists(l:term.buf) + execute 'bwipeout!' l:term.buf + endif endfunction function! s:create_term_buf(opts) @@ -242,7 +222,7 @@ function! s:build_window(layout, term_opts) if s:present(a:layout, 'window') if type(a:layout.window) == v:t_dict if !g:nnn#has_floating_window_support - throw 'Your vim/neovim version does not support floating window/popup.' + throw 'Your vim/neovim version does not support popup/floating window.' endif return s:popup(a:layout.window, a:term_opts) else @@ -273,7 +253,6 @@ function! s:build_window(layout, term_opts) throw 'Invalid layout' endfunction - function! nnn#pick(...) abort let l:directory = get(a:, 1, '') let l:default_opts = { 'edit': 'edit' } From 6d8718ef1ea1754392d9fcac833806e7fff5e384 Mon Sep 17 00:00:00 2001 From: Michael Chris Lopez Date: Mon, 26 Jul 2021 15:23:16 +0800 Subject: [PATCH 14/20] convert s:tbuf to b:tbuf --- autoload/nnn.vim | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/autoload/nnn.vim b/autoload/nnn.vim index 75a69f3..8c60f12 100644 --- a/autoload/nnn.vim +++ b/autoload/nnn.vim @@ -1,6 +1,5 @@ let s:temp_file = '' let s:action = '' -let s:tbuf = 0 let s:nnn_conf_dir = (!empty($XDG_CONFIG_HOME) ? $XDG_CONFIG_HOME : $HOME.'/.config') . '/nnn' let s:local_ses = 'nnn_vim_' @@ -23,7 +22,7 @@ function! nnn#select_action(action) abort if has('nvim') call feedkeys("i\") else - call term_sendkeys(s:tbuf, "\") + call term_sendkeys(b:tbuf, "\") endif endfunction @@ -278,7 +277,7 @@ function! nnn#pick(...) abort let l:opts.ppos = { 'buf': bufnr(''), 'win': winnr(), 'tab': tabpagenr() } let l:opts.term = s:build_window(l:layout, { 'cmd': l:cmd, 'on_exit': s:create_on_exit_callback(l:opts) }) - let s:tbuf = l:opts.term.buf + let b:tbuf = l:opts.term.buf setfiletype nnn if g:nnn#statusline && !s:present(l:layout, 'window') call s:statusline() From 88259488880e800c9a9bc9ff54e8cae7a90baeda Mon Sep 17 00:00:00 2001 From: Michael Chris Lopez Date: Thu, 29 Jul 2021 12:04:38 +0800 Subject: [PATCH 15/20] adjust spacing --- doc/nnn.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/nnn.txt b/doc/nnn.txt index a8b9da3..e9309ee 100644 --- a/doc/nnn.txt +++ b/doc/nnn.txt @@ -185,7 +185,7 @@ g:nnn#shell *g:nnn#shell* Default: &shell The shell to run the terminal window. -require('nnn').setup{} *nnn-lua-setup* +require('nnn').setup{} *nnn-lua-setup* Default: same as Vimscript defaults An alternative way to configure n³ more suitable for init.lua users. For example: From 086f78f5c581d5a2cc98ec14b7f023dabe32a0dd Mon Sep 17 00:00:00 2001 From: Michael Chris Lopez Date: Thu, 29 Jul 2021 15:31:45 +0800 Subject: [PATCH 16/20] add more options to lua setup --- lua/nnn.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lua/nnn.lua b/lua/nnn.lua index 6dc4f23..edc1406 100644 --- a/lua/nnn.lua +++ b/lua/nnn.lua @@ -1,12 +1,14 @@ local M = {} M.valid_options = { - 'session', 'set_default_mappings', 'layout', 'action', 'session', 'command', + 'replace_netrw', + 'statusline', + 'shell', } function M.setup(config) From 466be8b8ab5f6955582a869578959d05a74745b9 Mon Sep 17 00:00:00 2001 From: Michael Chris Lopez Date: Thu, 29 Jul 2021 15:52:36 +0800 Subject: [PATCH 17/20] add demo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c0f18be..e5fa3f0 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ File manager for vim/neovim powered by n³. +https://user-images.githubusercontent.com/7200153/127453278-3e638e33-707a-49c8-b34e-225c225906b1.mov

- colorscheme yin

From e73451e1529e18cf88897ebd6ad495d0cfb7ff5e Mon Sep 17 00:00:00 2001 From: Michael Chris Lopez Date: Thu, 29 Jul 2021 16:25:28 +0800 Subject: [PATCH 18/20] update floating window requirement to has('popupwin') instead of just a patch number --- plugin/nnn.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/nnn.vim b/plugin/nnn.vim index c88ab94..46b5389 100644 --- a/plugin/nnn.vim +++ b/plugin/nnn.vim @@ -7,7 +7,7 @@ if !(exists("g:nnn#set_default_mappings")) let g:nnn#set_default_mappings = 1 endif -let g:nnn#has_floating_window_support = has('nvim-0.5') || has('patch-8.2.191') +let g:nnn#has_floating_window_support = has('nvim-0.5') || has('popupwin') if !(exists("g:nnn#layout")) if g:nnn#has_floating_window_support From a3428702201f0ea017fef7f7d996aac583d66c3b Mon Sep 17 00:00:00 2001 From: Michael Chris Lopez Date: Thu, 29 Jul 2021 16:26:27 +0800 Subject: [PATCH 19/20] update requirements in docs --- README.md | 30 ++++++++++++++++-------------- doc/nnn.txt | 25 +++++++++++++------------ 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index e5fa3f0..3a012ae 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ File manager for vim/neovim powered by n³. https://user-images.githubusercontent.com/7200153/127453278-3e638e33-707a-49c8-b34e-225c225906b1.mov +

colorscheme yin

@@ -10,7 +11,8 @@ https://user-images.githubusercontent.com/7200153/127453278-3e638e33-707a-49c8-b ### Requirements 1. n³ -2. Neovim or Vim 8.1 with terminal support +2. `has('nvim') || has('terminal')` with terminal support +3. Optional `has('nvim-0.5') || has('popupwin')` for floating window ### Install @@ -26,9 +28,9 @@ Plug 'mcchrish/nnn.vim' ### Usage -To open n³ as a file picker in vim/neovim, use the command `:NnnPicker` or -`:Np` or the key-binding `n`. The command accepts an optional path -to open e.g. `:NnnPicker path/to/somewhere`. +To open n³ as a file picker in vim/neovim, use the command `:NnnPicker` or the +key-binding `n`. The command accepts an optional path to open e.g. +`:NnnPicker path/to/somewhere`. Run the plugin, [select file(s)](https://github.com/jarun/nnn/wiki/concepts#selection) and press Enter to quit the n³ window. Now vim will open the first @@ -42,9 +44,9 @@ instead of picking. To discard selection and exit, press ^G. -vim config `set hidden` may be required for the floating windows to work. +`set hidden` may be required for the floating windows to work. -Complete plugin documentation - `:help nnn`. +For complete plugin documentation see `:help nnn`. ### Configuration @@ -54,11 +56,9 @@ Complete plugin documentation - `:help nnn`. " Disable default mappings let g:nnn#set_default_mappings = 0 -" Set personalized mappings +" Set custom mappings nnoremap nn :NnnPicker - -" OR override " Start n³ in the current file's directory nnoremap n :NnnPicker %:p:h ``` @@ -72,7 +72,7 @@ let g:nnn#layout = 'new' " or vnew, tabnew etc. " Or pass a dictionary with window size let g:nnn#layout = { 'left': '~20%' } " or right, up, down -" Floating window (neovim latest and vim with patch 8.2.191) +" Floating window. let g:nnn#layout = { 'window': { 'width': 0.9, 'height': 0.6, 'highlight': 'Debug' } } ``` @@ -89,8 +89,9 @@ let g:nnn#action = { ``` With the above example, when inside an n³ window, pressing ^T will -open the selected file in a tab instead of the current window. ^X will -open in a split an so on. Multi-selected files will be loaded in the buffer list. +open the selected file in a tab instead of the current window. ^X +will open in a split an so on. Multi-selected files will be loaded in the +buffer list. #### Persistent session @@ -109,7 +110,8 @@ Note: If desired, an n³ session can be disabled temporarily by passing #### Command override -It's possible to override the default n³ command and add some extra program options. +It's possible to override the default n³ command and add some extra program +options. ```vim " to start n³ in detail mode: @@ -148,7 +150,7 @@ let $NNN_TRASH=1 Use the same option names as you would in Vimscript, e.g.: ```lua -require('nnn').setup{ +require('nnn').setup { set_default_mappings = false, session = 'global', layout = { left = '20%' } diff --git a/doc/nnn.txt b/doc/nnn.txt index e9309ee..9525063 100644 --- a/doc/nnn.txt +++ b/doc/nnn.txt @@ -33,7 +33,8 @@ terminal feature of vim and neovim. Requirements *nnn-req* 1. n³ -2. Neovim or Vim 8.1 with terminal support +2. `has('nvim') || has('terminal')` with terminal support +3. Optional `has('nvim-0.5') || has('popupwin')` for floating window ============================================================================= Usage *nnn-usage* @@ -96,10 +97,10 @@ g:nnn#set_default_mappings *g:nnn#set_default_mappings* g:nnn#layout *g:nnn#layout* Default: { 'window': { 'width': 0.9, 'height': 0.6 } } - Display type for the n³ buffer. Default is a floating window. |enew| - has a special behavior to act as a "split explorer" reusing - the current window and brings back the last buffer if - nothing is selected. + Display type for the n³ buffer. Default is a floating + window. |enew| has a special behavior to act as a + "split explorer" reusing the current window and brings back + the last buffer if nothing is selected. Examples: > " Opens the n³ window in a split @@ -108,7 +109,7 @@ g:nnn#layout *g:nnn#layout* " Or pass a dictionary with window size let g:nnn#layout = { 'left': '~20%' } " or right, up, down - " Floating window (neovim only for now) + " Floating window let g:nnn#layout = { 'window': { 'width': 0.9, 'height': 0.6, 'highlight': 'Debug' } } " Options: " width, height, yoffset, xoffset : number @@ -149,10 +150,10 @@ g:nnn#action *g:nnn#action* g:nnn#session *g:nnn#session* Default: 'none' - How n³ should utilize sessions. Default is 'none' meaning no - persistent sessions. Other options are 'local' for the same - n³ session across a vim session, or 'global' for the same n³ - session across everywhere. + How n³ should utilize sessions. Default is 'none' meaning + no persistent sessions. Other options are 'local' for the + same n³ session across a vim session, or 'global' for the + same n³ session across everywhere. > " use the same nnn session within a vim session, for " example, so that consecutive uses of :Np will remember @@ -209,8 +210,8 @@ nnn#pick([{dir}][,{opts}]) *nnn#pick()* {dir} : (string) a directory. {opts}: (dict) can be: edit : type of window the select file will be open. Or - pass a FuncRef and array of selected files will be - passed to that function. + pass a FuncRef and array of selected files will + be passed to that function. layout: same as |g:nnn#layout| and overrides it if specified. From b07108631ec4c8680d6facef16e38968fcd1553b Mon Sep 17 00:00:00 2001 From: Michael Chris Lopez Date: Thu, 29 Jul 2021 16:32:27 +0800 Subject: [PATCH 20/20] cleanup doc --- doc/nnn.txt | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/doc/nnn.txt b/doc/nnn.txt index 9525063..eb8d55b 100644 --- a/doc/nnn.txt +++ b/doc/nnn.txt @@ -45,14 +45,13 @@ buffer opens running an n³ process in picker mode. Once you select (see https://github.com/jarun/nnn/wiki/concepts#selection) one or more files and press enter, vim quits the n³ window and opens the first selected file and add the remaining files to the arg list/buffer -list. If |nnn#session| is enabled, then n³ will remember where you left off -of when you reopen it. +list. If |nnn#session| is enabled, then n³ will remember where you left off of +when you reopen it. -Pressing enter on a file in n³ will pick any earlier selection, pick -the file and exit n³. +Pressing enter on a file in n³ will pick any earlier selection, pick the file +and exit n³. -Note that pressing l or Right on a file would open it -instead of picking. +Note that pressing `l` or on a file would open it instead of picking. You may have to set `set hidden` to make floating window work.