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
1 change: 1 addition & 0 deletions autoload/fern/helper/async.vim
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ function! s:async_redraw() abort dict
\ )
\})
\.then({ v -> fern#internal#buffer#replace(helper.bufnr, v) })
\.then({ -> fern#hook#emit('viewer:redraw', helper) })
\.finally({ -> Profile() })
endfunction
let s:async.redraw = funcref('s:async_redraw')
Expand Down
2 changes: 2 additions & 0 deletions autoload/fern/internal/core.vim
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ function! fern#internal#core#new(url, provider, ...) abort
\ 'comparator': g:fern#comparator,
\}, a:0 ? a:1 : {},
\)
let scheme = fern#fri#parse(a:url).scheme
let root = fern#internal#node#root(a:url, a:provider)
let fern = {
\ 'scheme': scheme,
\ 'source': s:CancellationTokenSource.new(),
\ 'provider': a:provider,
\ 'renderer': s:get_renderer(options.renderer),
Expand Down
3 changes: 3 additions & 0 deletions autoload/fern/internal/viewer.vim
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,9 @@ endfunction

function! s:BufReadCmd() abort
let helper = fern#helper#new()
setlocal filetype=fern
call helper.fern.renderer.syntax()
call fern#hook#emit('renderer:syntax', helper)
let root = helper.sync.get_root_node()
let cursor = get(b:, 'fern_cursor', getcurpos())
call s:Promise.resolve()
Expand All @@ -119,4 +121,5 @@ endfunction
function! s:ColorScheme() abort
let helper = fern#helper#new()
call helper.fern.renderer.highlight()
call fern#hook#emit('renderer:highlight', helper)
endfunction
2 changes: 1 addition & 1 deletion autoload/vital/_fern/Async/CancellationTokenSource.vim
Original file line number Diff line number Diff line change
Expand Up @@ -82,5 +82,5 @@ function! s:_unlink(source) abort
endfunction

function! s:_throw(exception) abort
throw a:exception
throw substitute(a:exception, '^Vim(.*):', '', '')
endfunction
2 changes: 1 addition & 1 deletion autoload/vital/_fern/Async/Promise/Process.vim
Original file line number Diff line number Diff line change
Expand Up @@ -92,5 +92,5 @@ endfunction

function! s:_on_cancel(ns, ...) abort
call a:ns.job.stop()
call a:ns.reject(s:CancellationToken.CancellationError)
call a:ns.reject(s:CancellationToken.CancelledError)
endfunction
55 changes: 38 additions & 17 deletions autoload/vital/fern.vim
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ function! s:_import(name) abort dict
call module._vital_created(module)
endif
let export_module = filter(copy(module), 'v:key =~# "^\\a"')
" Cache module before calling module.vital_loaded() to avoid cyclic
" Cache module before calling module._vital_loaded() to avoid cyclic
" dependences but remove the cache if module._vital_loaded() fails.
" let s:loaded[a:name] = export_module
let s:loaded[a:name] = export_module
Expand All @@ -167,30 +167,51 @@ let s:Vital._import = function('s:_import')

function! s:_format_throwpoint(throwpoint) abort
let funcs = []
let stack = matchstr(a:throwpoint, '^function \zs.*\ze, line \d\+$')
let stack = matchstr(a:throwpoint, '^function \zs.*, .\{-} \d\+$')
for line in split(stack, '\.\.')
let m = matchlist(line, '^\%(<SNR>\(\d\+\)_\)\?\(.\+\)\[\(\d\+\)\]$')
if empty(m)
call add(funcs, line)
continue
endif
let [sid, name, lnum] = m[1:3]
let attr = ''
if !empty(sid)
let name = printf('<SNR>%d_%s', sid, name)
let m = matchlist(line, '^\(.\+\)\%(\[\(\d\+\)\]\|, .\{-} \(\d\+\)\)$')
if !empty(m)
let [name, lnum, lnum2] = m[1:3]
if empty(lnum)
let lnum = lnum2
endif
let info = s:_get_func_info(name)
if !empty(info)
let attrs = empty(info.attrs) ? '' : join([''] + info.attrs)
let flnum = info.lnum == 0 ? '' : printf(' Line:%d', info.lnum + lnum)
call add(funcs, printf('function %s(...)%s Line:%d (%s%s)',
\ info.funcname, attrs, lnum, info.filename, flnum))
continue
endif
endif
let file = s:_get_file_by_func_name(name)
call add(funcs, printf('function %s(...)%s Line:%d (%s)', name, attr, lnum, file))
" fallback when function information cannot be detected
call add(funcs, line)
endfor
return join(funcs, "\n")
endfunction

function! s:_get_file_by_func_name(name) abort
let body = execute(printf('verbose function %s', a:name))
function! s:_get_func_info(name) abort
let name = a:name
if a:name =~# '^\d\+$' " is anonymous-function
let name = printf('{%s}', a:name)
elseif a:name =~# '^<lambda>\d\+$' " is lambda-function
let name = printf("{'%s'}", a:name)
endif
if !exists('*' . name)
return {}
endif
let body = execute(printf('verbose function %s', name))
let lines = split(body, "\n")
let signature = matchstr(lines[0], '^\s*\zs.*')
let file = matchstr(lines[1], '^\t\%(Last set from\|.\{-}:\)\s*\zs.*$')
return substitute(file, '[/\\]\+', '/', 'g')
let [_, file, lnum; __] = matchlist(lines[1],
\ '^\t\%(Last set from\|.\{-}:\)\s*\zs\(.\{-}\)\%( \S\+ \(\d\+\)\)\?$')
return {
\ 'filename': substitute(file, '[/\\]\+', '/', 'g'),
\ 'lnum': 0 + lnum,
\ 'funcname': a:name,
\ 'arguments': split(matchstr(signature, '(\zs.*\ze)'), '\s*,\s*'),
\ 'attrs': filter(['dict', 'abort', 'range', 'closure'], 'signature =~# (").*" . v:val)'),
\ }
endfunction

" s:_get_module() returns module object wihch has all script local functions.
Expand Down
2 changes: 1 addition & 1 deletion autoload/vital/fern.vital
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
fern
8043f4d0f577ffb654cab9cfe629312b36c5342d
80887bd366c925887a40829eae73e86d7bb63ecc

App.Spinner
Async.CancellationTokenSource
Expand Down
25 changes: 25 additions & 0 deletions doc/fern-develop.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ RENDERER |fern-develop-renderer|
SCHEME |fern-develop-scheme|
PROVIDER |fern-develop-scheme-provider|
MAPPING |fern-develop-scheme-provider|
HOOK |fern-develop-hook|
HELPER |fern-develop-helper|
LOGGER |fern-develop-logger|
UTILITY |fern-develop-utility|
Expand Down Expand Up @@ -303,6 +304,7 @@ VARIABLE *fern-develop-helper-variable*
.fern
A fern instance which has the following attributes:

"scheme" A scheme name used to determine "provider"
"source" A cancellation token source to cancel requests
"provider" A provider instance for the fren tree
"renderer" A renderer instance to sort nodes
Expand Down Expand Up @@ -500,6 +502,29 @@ Following methods are executed asynchronously and return a promise.
It is used to collapse modified nodes to solve issue #103.


=============================================================================
HOOK *fern-develop-hook*

Following hook will be emitted by |fern#hook#emit()| from fern itself.

"renderer:syntax" ({helper})
Called when fern renderer has register its syntax.
The {helper} is a helper instance described in |fern-develop-helper|.

"renderer:highlight" ({helper})
Called when fern renderer has register its highlight.
The {helper} is a helper instance described in |fern-develop-helper|.

"viewer:redraw" ({helper})
Called when fern viewer has redrawed.
The {helper} is a helper instance described in |fern-develop-helper|.

"viewer:ready" ({helper})
Called when fern viewer has ready, mean that the buffer has opened and
all content has rendererd.
The {helper} is a helper instance described in |fern-develop-helper|.


=============================================================================
LOGGER *fern-develop-logger*

Expand Down
9 changes: 7 additions & 2 deletions plugin/fern.vim
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
if exists('g:fern_loaded')
if exists('g:loaded_fern')
finish
endif
let g:fern_loaded = 1
let g:loaded_fern = 1
let g:fern_loaded = 1 " Obsolete: For backward compatibility

command! -bar -nargs=*
\ -complete=customlist,fern#internal#command#fern#complete
Expand Down Expand Up @@ -30,4 +31,8 @@ augroup fern_internal
autocmd! *
autocmd BufReadCmd fern://* ++nested call s:BufReadCmd()
autocmd SessionLoadPost fern://* ++nested call s:BufReadCmd()
autocmd User FernInit ++once :
augroup END

" Tell 3rd parties that fern has initialized
doautocmd <nomodeline> User FernInit
1 change: 1 addition & 0 deletions test/fern/internal/core.vimspec
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Describe fern#internal#core
Describe #new()
It returns a fern instance of given url and provider
let fern = fern#internal#core#new('debug:///', provider)
Assert KeyExists(fern, 'scheme')
Assert KeyExists(fern, 'source')
Assert KeyExists(fern, 'provider')
Assert KeyExists(fern, 'comparator')
Expand Down