From 7ef10e3d9192e8f2ec53188fdce0489a33462f3c Mon Sep 17 00:00:00 2001 From: lambdalisue Date: Tue, 26 May 2020 02:28:47 +0900 Subject: [PATCH] Add 'grep' action on 'file' scheme --- autoload/fern/internal/args.vim | 12 +++++ autoload/fern/scheme/file/mapping.vim | 1 + autoload/fern/scheme/file/mapping/grep.vim | 53 ++++++++++++++++++++++ 3 files changed, 66 insertions(+) create mode 100644 autoload/fern/scheme/file/mapping/grep.vim diff --git a/autoload/fern/internal/args.vim b/autoload/fern/internal/args.vim index cd12ee00..0044af9f 100644 --- a/autoload/fern/internal/args.vim +++ b/autoload/fern/internal/args.vim @@ -1,3 +1,15 @@ +function! fern#internal#args#split(cmd) abort + let sq = '''\zs[^'']\+\ze''' + let dq = '"\zs[^"]\+\ze"' + let bs = '\%(\\\s\|[^ ''"]\)\+' + let pp = printf( + \ '\%%(%s\)*\zs\%%(\s\+\|$\)\ze', + \ join([sq, dq, bs], '\|') + \) + let np = '^\%("\zs.*\ze"\|''\zs.*\ze''\|.*\)$' + return map(split(a:cmd, pp), { -> matchstr(v:val, np) }) +endfunction + function! fern#internal#args#index(args, pattern) abort for index in range(len(a:args)) if a:args[index] =~# a:pattern diff --git a/autoload/fern/scheme/file/mapping.vim b/autoload/fern/scheme/file/mapping.vim index bb8dbc2c..bcbcd70e 100644 --- a/autoload/fern/scheme/file/mapping.vim +++ b/autoload/fern/scheme/file/mapping.vim @@ -7,6 +7,7 @@ function! fern#scheme#file#mapping#init(disable_default_mappings) abort call fern#scheme#file#mapping#clipboard#init(a:disable_default_mappings) call fern#scheme#file#mapping#rename#init(a:disable_default_mappings) call fern#scheme#file#mapping#terminal#init(a:disable_default_mappings) + call fern#scheme#file#mapping#grep#init(a:disable_default_mappings) nnoremap (fern-action-new-file) :call call('new_file') nnoremap (fern-action-new-dir) :call call('new_dir') diff --git a/autoload/fern/scheme/file/mapping/grep.vim b/autoload/fern/scheme/file/mapping/grep.vim new file mode 100644 index 00000000..1c0b74b3 --- /dev/null +++ b/autoload/fern/scheme/file/mapping/grep.vim @@ -0,0 +1,53 @@ +let s:Config = vital#fern#import('Config') +let s:Promise = vital#fern#import('Async.Promise') +let s:Process = vital#fern#import('Async.Promise.Process') + +function! fern#scheme#file#mapping#grep#init(disable_default_mappings) abort + nnoremap (fern-action-grep) :call call('grep') +endfunction + +function! s:call(name, ...) abort + return call( + \ 'fern#mapping#call', + \ [funcref(printf('s:map_%s', a:name))] + a:000, + \) +endfunction + +function! s:map_grep(helper) abort + let pattern = input('Grep: ', '') + if empty(pattern) + return s:Promise.reject('Cancelled') + endif + let node = a:helper.sync.get_cursor_node() + let node = node.status isnot# a:helper.STATUS_EXPANDED ? node.__owner : node + let args = s:grepargs([pattern, fern#internal#filepath#from_slash(node._path)]) + let efm = g:fern#scheme#file#mapping#grep#grepformat + let title = printf('[fern] %s', join(map(copy(args), { _, v -> v =~# '\s' ? printf('"%s"', v) : v }), ' ')) + let token = a:helper.fern.source.token + return s:Process.start(args, { 'token': token }) + \.then({ v -> v.stdout }) + \.then({ v -> setqflist([], 'a', { 'efm': efm, 'lines': v, 'title': title }) }) + \.then({ -> execute('copen') }) +endfunction + +function! s:grepargs(args) abort + let args = fern#internal#args#split(g:fern#scheme#file#mapping#grep#grepprg) + let args = map(args, { _, v -> v =~# '^[%#]\%(:.*\)\?$' ? expand(v) : v }) + let index = index(args, '$*') + return index is# -1 + \ ? args + a:args + \ : args[:index - 1] + a:args + args[index + 1:] +endfunction + +function! s:default_grepprg() abort + if &grepprg =~# '^\%(grep -n \|grep -n $\* /dev/null\|internal\)$' + return has('unix') ? 'grep -rn $* /dev/null' : 'gren -rn' + endif + return &grepprg +endfunction + + +call s:Config.config(expand(':p'), { + \ 'grepprg': s:default_grepprg(), + \ 'grepformat': &grepformat, + \})