mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-02-03 16:50:05 +08:00
165 lines
5.0 KiB
VimL
Vendored
165 lines
5.0 KiB
VimL
Vendored
let s:Git = vital#gina#import('Git')
|
|
let s:Path = vital#gina#import('System.Filepath')
|
|
let s:Store = vital#gina#import('System.Store')
|
|
let s:String = vital#gina#import('Data.String')
|
|
|
|
|
|
function! gina#complete#filename#directory(arglead, cmdline, cursorpos) abort
|
|
let separator = s:Path.separator()
|
|
return filter(
|
|
\ gina#complete#filename#any(a:arglead, a:cmdline, a:cursorpos),
|
|
\ 'v:val =~# separator . ''$'''
|
|
\)
|
|
endfunction
|
|
|
|
function! gina#complete#filename#any(arglead, cmdline, cursorpos) abort
|
|
let git = gina#core#get_or_fail()
|
|
let candidates = s:get_available_filenames(git, [
|
|
\ '--cached', '--others', '--', a:arglead . '*',
|
|
\])
|
|
return s:filter(a:arglead, candidates)
|
|
endfunction
|
|
|
|
function! gina#complete#filename#tracked(arglead, cmdline, cursorpos, ...) abort
|
|
let rev = a:0 ? a:1 : ''
|
|
let git = gina#core#get_or_fail()
|
|
let slug = eval(s:Store.get_slug_expr()) . rev
|
|
let store = s:Store.of([
|
|
\ s:Git.resolve(git, 'HEAD'),
|
|
\ s:Git.resolve(git, 'index'),
|
|
\])
|
|
let candidates = store.get(slug, [])
|
|
if empty(candidates)
|
|
let candidates = s:get_available_filenames(git, [], rev)
|
|
call store.set(slug, candidates)
|
|
endif
|
|
return s:filter(a:arglead, candidates)
|
|
endfunction
|
|
|
|
function! gina#complete#filename#cached(arglead, cmdline, cursorpos) abort
|
|
let git = gina#core#get_or_fail()
|
|
let slug = eval(s:Store.get_slug_expr())
|
|
let store = s:Store.of([
|
|
\ s:Git.resolve(git, 'HEAD'),
|
|
\ s:Git.resolve(git, 'index'),
|
|
\])
|
|
let candidates = store.get(slug, [])
|
|
if empty(candidates)
|
|
let candidates = s:get_available_filenames(git, ['--cached'])
|
|
call store.set(slug, candidates)
|
|
endif
|
|
return s:filter(a:arglead, candidates)
|
|
endfunction
|
|
|
|
function! gina#complete#filename#deleted(arglead, cmdline, cursorpos) abort
|
|
let git = gina#core#get_or_fail()
|
|
let slug = eval(s:Store.get_slug_expr())
|
|
let store = s:Store.of([
|
|
\ s:Git.resolve(git, 'HEAD'),
|
|
\ s:Git.resolve(git, 'index'),
|
|
\])
|
|
let candidates = store.get(slug, [])
|
|
if empty(candidates)
|
|
let candidates = s:get_available_filenames(git, ['--deleted'])
|
|
call store.set(slug, candidates)
|
|
endif
|
|
return s:filter(a:arglead, candidates)
|
|
endfunction
|
|
|
|
function! gina#complete#filename#modified(arglead, cmdline, cursorpos) abort
|
|
let git = gina#core#get_or_fail()
|
|
let slug = eval(s:Store.get_slug_expr())
|
|
let store = s:Store.of([
|
|
\ s:Git.resolve(git, 'HEAD'),
|
|
\ s:Git.resolve(git, 'index'),
|
|
\])
|
|
let candidates = store.get(slug, [])
|
|
if empty(candidates)
|
|
let candidates = s:get_available_filenames(git, ['--modified'])
|
|
call store.set(slug, candidates)
|
|
endif
|
|
return s:filter(a:arglead, candidates)
|
|
endfunction
|
|
|
|
function! gina#complete#filename#others(arglead, cmdline, cursorpos) abort
|
|
let git = gina#core#get_or_fail()
|
|
let candidates = s:get_available_filenames(git, [
|
|
\ '--others', '--', a:arglead . '*',
|
|
\])
|
|
return s:filter(a:arglead, candidates)
|
|
endfunction
|
|
|
|
function! gina#complete#filename#unstaged(arglead, cmdline, cursorpos) abort
|
|
let git = gina#core#get_or_fail()
|
|
let candidates = s:get_available_filenames(git, [
|
|
\ '--others',
|
|
\ '--modified',
|
|
\ '--',
|
|
\ a:arglead . '*',
|
|
\])
|
|
return s:filter(a:arglead, candidates)
|
|
endfunction
|
|
|
|
function! gina#complete#filename#conflicted(arglead, cmdline, cursorpos) abort
|
|
let git = gina#core#get_or_fail()
|
|
let slug = eval(s:Store.get_slug_expr())
|
|
let store = s:Store.of([
|
|
\ s:Git.resolve(git, 'HEAD'),
|
|
\ s:Git.resolve(git, 'index'),
|
|
\])
|
|
let candidates = store.get(slug, [])
|
|
if empty(candidates)
|
|
let result = gina#process#call(git, [
|
|
\ 'status',
|
|
\ '--porcelain',
|
|
\ '--ignore-submodules',
|
|
\])
|
|
if result.status
|
|
return []
|
|
endif
|
|
call filter(
|
|
\ candidates,
|
|
\ 'v:val[:1] =~# ''^\%(DD\|AU\|UD\|UA\|DU\|AA\|UU\)'''
|
|
\)
|
|
call map(candidates, 'matchstr(v:val, ''.. \zs.*'')')
|
|
call store.set(slug, candidates)
|
|
endif
|
|
return s:filter(a:arglead, candidates)
|
|
endfunction
|
|
|
|
" Private --------------------------------------------------------------------
|
|
function! s:filter(arglead, candidates) abort
|
|
let pattern = s:String.escape_pattern(a:arglead)
|
|
let separator = s:Path.separator()
|
|
let candidates = gina#util#filter(a:arglead, a:candidates, '^\.')
|
|
call map(
|
|
\ candidates,
|
|
\ printf(
|
|
\ 'matchstr(v:val, ''^%s[^%s]*%s\?\ze'')',
|
|
\ pattern, separator, separator
|
|
\ ),
|
|
\)
|
|
return uniq(candidates)
|
|
endfunction
|
|
|
|
function! s:get_available_filenames(git, args, ...) abort
|
|
let rev = a:0 ? a:1 : ''
|
|
if empty(rev)
|
|
let args = ['ls-files', '--full-name']
|
|
else
|
|
let args = [
|
|
\ 'ls-tree',
|
|
\ '--full-name',
|
|
\ '--full-tree',
|
|
\ '--name-only',
|
|
\ '-r',
|
|
\ rev,
|
|
\]
|
|
endif
|
|
let result = gina#process#call(a:git, args + a:args)
|
|
if result.status
|
|
return []
|
|
endif
|
|
return map(result.stdout, 'gina#core#repo#relpath(a:git, v:val)')
|
|
endfunction
|