diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6103852 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +dirvish_git.log diff --git a/autoload/dirvish_git.vim b/autoload/dirvish_git.vim new file mode 100644 index 0000000..b1c4e28 --- /dev/null +++ b/autoload/dirvish_git.vim @@ -0,0 +1,44 @@ +let dirvish_git#sep = exists('+shellslash') && !&shellslash ? '\' : '/' +let dirvish_git#escape_chars = '.#~'. dirvish_git#sep + + +function! dirvish_git#jump_to_next_file() abort + if len(b:git_files) <=? 0 + return + endif + + let l:current_line = line('.') + let l:git_files_line_number = sort(keys(b:git_files), 'N') + + for l:line in l:git_files_line_number + if l:line > l:current_line + return cursor(l:line, 0) + endif + endfor + + return cursor(l:git_files_line_number[0], 0) +endfunction + + +function! dirvish_git#jump_to_prev_file() abort + if len(b:git_files) <=? 0 + return + endif + + let l:current_line = line('.') + let l:git_files_line_number = reverse(sort(keys(b:git_files), 'N')) + + for l:line in l:git_files_line_number + if l:line < l:current_line + return cursor(l:line, 0) + endif + endfor + + return cursor(l:git_files_line_number[0], 0) +endfunction + +function! dirvish_git#reload() abort + if &filetype ==? 'dirvish' + Dirvish % + endif +endfunction diff --git a/autoload/dirvish_git/async.vim b/autoload/dirvish_git/async.vim new file mode 100644 index 0000000..0d8bfc5 --- /dev/null +++ b/autoload/dirvish_git/async.vim @@ -0,0 +1,109 @@ +" This file is an copy of https://github.com/airblade/vim-gitgutter/blob/719d4ec06a0fb0aa9f1dfaebcf4f9691e8dc3f73/autoload/gitgutter/async.vim +" +let s:available = has('nvim') || ( + \ has('job') && ( + \ (has('patch-7-4-1826') && !has('gui_running')) || + \ (has('patch-7-4-1850') && has('gui_running')) || + \ (has('patch-7-4-1832') && has('gui_macvim')) + \ ) + \ ) + +let s:jobs = {} + +function! dirvish_git#async#available() + return s:available +endfunction + + +function! dirvish_git#async#execute(cmd, bufnr, handler) abort + call dirvish_git#debug#log('[async] '.a:cmd) + + let options = { + \ 'stdoutbuffer': [], + \ 'buffer': a:bufnr, + \ 'handler': a:handler + \ } + let command = s:build_command(a:cmd) + + if has('nvim') + call jobstart(command, extend(options, { + \ 'on_stdout': function('s:on_stdout_nvim'), + \ 'on_stderr': function('s:on_stderr_nvim'), + \ 'on_exit': function('s:on_exit_nvim') + \ })) + else + let job = job_start(command, { + \ 'out_cb': function('s:on_stdout_vim', options), + \ 'err_cb': function('s:on_stderr_vim', options), + \ 'close_cb': function('s:on_exit_vim', options) + \ }) + let s:jobs[s:job_id(job)] = 1 + endif +endfunction + + +function! s:build_command(cmd) + if has('unix') + return ['sh', '-c', a:cmd] + endif + + if has('win32') + return has('nvim') ? ['cmd.exe', '/c', a:cmd] : 'cmd.exe /c '.a:cmd + endif + + throw 'unknown os' +endfunction + + +function! s:on_stdout_nvim(_job_id, data, _event) dict abort + if empty(self.stdoutbuffer) + let self.stdoutbuffer = a:data + else + let self.stdoutbuffer = self.stdoutbuffer[:-2] + + \ [self.stdoutbuffer[-1] . a:data[0]] + + \ a:data[1:] + endif +endfunction + +function! s:on_stderr_nvim(_job_id, data, _event) dict abort + if a:data != [''] " With Neovim there is always [''] reported on stderr. + call self.handler.err(self.buffer) + endif +endfunction + +function! s:on_exit_nvim(_job_id, exit_code, _event) dict abort + if !a:exit_code + call self.handler.out(self.buffer, join(self.stdoutbuffer, "\n")) + endif +endfunction + + +function! s:on_stdout_vim(_channel, data) dict abort + call add(self.stdoutbuffer, a:data) +endfunction + +function! s:on_stderr_vim(channel, _data) dict abort + call self.handler.err(self.buffer) +endfunction + +function! s:on_exit_vim(channel) dict abort + let job = ch_getjob(a:channel) + let jobid = s:job_id(job) + if has_key(s:jobs, jobid) | unlet s:jobs[jobid] | endif + while 1 + if job_status(job) == 'dead' + let exit_code = job_info(job).exitval + break + endif + sleep 5m + endwhile + + if !exit_code + call self.handler.out(self.buffer, join(self.stdoutbuffer, "\n")) + endif +endfunction + +function! s:job_id(job) + " Vim + return job_info(a:job).process +endfunction diff --git a/autoload/dirvish_git/debug.vim b/autoload/dirvish_git/debug.vim new file mode 100644 index 0000000..35ac2e0 --- /dev/null +++ b/autoload/dirvish_git/debug.vim @@ -0,0 +1,45 @@ +let s:plugin_dir = expand(':p:h:h:h').'/' +let s:log_file = s:plugin_dir.'dirvish_git.log' +let s:channel_log = s:plugin_dir.'channel.log' +let s:new_log_session = 1" + +" From vim-gitgutter +function dirvish_git#debug#log(message, ...) abort + if g:dirvish_git_debug + if s:new_log_session && dirvish_git#async#available() + if exists('*ch_logfile') + call ch_logfile(s:channel_log, 'w') + endif + endif + + execute 'redir >> '.s:log_file + if s:new_log_session + let s:start = reltime() + silent echo "\n==== start log session ====" + endif + + let elapsed = reltimestr(reltime(s:start)).' ' + silent echo '' + " callers excluding this function + silent echo elapsed.expand('')[:-22].':' + silent echo elapsed.s:format_for_log(a:message) + if a:0 && !empty(a:1) + for msg in a:000 + silent echo elapsed.s:format_for_log(msg) + endfor + endif + redir END + + let s:new_log_session = 0 + endif +endfunction + +function! s:format_for_log(data) abort + if type(a:data) == 1 + return join(split(a:data,'\n'),"\n") + elseif type(a:data) == 3 + return '['.join(a:data,"\n").']' + else + return a:data + endif +endfunction diff --git a/autoload/dirvish_git/highlight.vim b/autoload/dirvish_git/highlight.vim new file mode 100644 index 0000000..b54f48d --- /dev/null +++ b/autoload/dirvish_git/highlight.vim @@ -0,0 +1,93 @@ +if !exists('g:dirvish_git_indicators') + let g:dirvish_git_indicators = { + \ 'Modified' : '✹', + \ 'Staged' : '✚', + \ 'Untracked' : '✭', + \ 'Renamed' : '➜', + \ 'Unmerged' : '═', + \ 'Ignored' : '☒', + \ 'Unknown' : '?' + \ } +endif + +let s:dirvish_git_highlight_groups = { +\ 'Modified' : 'DirvishGitModified', +\ 'Staged' : 'DirvishGitStaged', +\ 'Untracked' : 'DirvishGitUntracked', +\ 'Renamed' : 'DirvishGitRenamed', +\ 'Unmerged' : 'DirvishGitUnmerged', +\ 'Ignored' : 'DirvishGitIgnored', +\ 'Unknown' : 'DirvishGitModified' +\ } + +let s:sep = dirvish_git#sep +let s:escape_chars = dirvish_git#escape_chars + +function dirvish_git#highlight#get_highlight_groups() abort + return s:dirvish_git_highlight_groups +endfunction + +function! s:get_indicator_name(us, them) abort + if a:us ==# '?' && a:them ==# '?' + return 'Untracked' + elseif a:us ==# ' ' && a:them ==# 'M' + return 'Modified' + elseif a:us =~# '[MAC]' + return 'Staged' + elseif a:us ==# 'R' + return 'Renamed' + elseif a:us ==# 'U' || a:them ==# 'U' || a:us ==# 'A' && a:them ==# 'A' || a:us ==# 'D' && a:them ==# 'D' + return 'Unmerged' + elseif a:us ==# '!' + return 'Ignored' + else + return 'Unknown' + endif +endfunction + +function! dirvish_git#highlight#get_indicator(us, them) abort + return get(g:dirvish_git_indicators, s:get_indicator_name(a:us, a:them), '') +endfunction + +function! dirvish_git#highlight#get_highlight_group(us, them, is_directory) abort + let l:group = get(s:dirvish_git_highlight_groups, s:get_indicator_name(a:us, a:them), 'DirvishGitModified') + if !a:is_directory || l:group !=? 'DirvishGitUntracked' + return l:group + endif + + return 'DirvishGitUntrackedDir' +endfunction + +function! dirvish_git#highlight#highlight_file(dir, file_name, us, them, is_directory) abort + let l:file_rgx = escape(printf('\(%s\)\@<=%s%s', a:dir, s:sep, a:file_name), s:escape_chars) + let l:dir_rgx = escape(printf('%s\(%s%s\)\@=', a:dir, s:sep, a:file_name), s:escape_chars) + let l:slash_rgx = escape(printf('\(%s\)\@<=%s\(%s\)\@=', a:dir, s:sep, a:file_name), s:escape_chars) + + call dirvish_git#debug#log('[l:file_rgx] '. l:file_rgx) + call dirvish_git#debug#log('[l:dir_rgx] '. l:dir_rgx) + " Check if icons should be shown + let l:conceal_char = g:dirvish_git_show_icons ? (' cchar=' . dirvish_git#highlight#get_indicator(a:us, a:them)) : '' + let l:conceal_last_folder_char = g:dirvish_git_show_icons ? ' cchar= ' : '' + + silent exe 'syn match DirvishGitDir "'.l:dir_rgx.'" conceal ' . l:conceal_char + silent exe 'syn match '. dirvish_git#highlight#get_highlight_group(a:us, a:them, a:is_directory).' "'.l:file_rgx.'" contains=DirvishGitSlash' + silent exe 'syn match DirvishGitSlash "'.l:slash_rgx.'" conceal contained' . l:conceal_last_folder_char +endfunction + +function! dirvish_git#highlight#setup_highlighting() abort + for l:highlight_group in values(s:dirvish_git_highlight_groups) + silent! exe 'syntax clear '.l:highlight_group + endfor + + let l:modified = 'guifg=#fabd2f ctermfg=214' + let l:added = 'guifg=#b8bb26 ctermfg=142' + let l:unmerged = 'guifg=#fb4934 ctermfg=167' + + silent exe 'hi default DirvishGitModified '.l:modified + silent exe 'hi default DirvishGitStaged '.l:added + silent exe 'hi default DirvishGitRenamed '.l:modified + silent exe 'hi default DirvishGitUnmerged '.l:unmerged + silent exe 'hi default link DirvishGitUntrackedDir DirvishPathTail' + silent exe 'hi default DirvishGitIgnored guifg=NONE guibg=NONE gui=NONE cterm=NONE ctermfg=NONE ctermbg=NONE' + silent exe 'hi default DirvishGitUntracked guifg=NONE guibg=NONE gui=NONE cterm=NONE ctermfg=NONE ctermbg=NONE' +endfunction diff --git a/autoload/dirvish_git/utils.vim b/autoload/dirvish_git/utils.vim new file mode 100644 index 0000000..191f3e9 --- /dev/null +++ b/autoload/dirvish_git/utils.vim @@ -0,0 +1,143 @@ +let s:sep = dirvish_git#sep +let s:escape_chars = dirvish_git#escape_chars + +" handler for execute async job +let s:update_status_handler = {} + +function s:update_status_handler.out(bufnr, output) abort + let l:status = split(a:output, '\n') + if len(l:status) ==? 0 || (len(l:status) ==? 1 && l:status[0] =~? '^fatal') + return + endif + + let l:status = sort(l:status, "s:unmerged_status_comparator") + + let l:current_dir = expand('%:p:h') + + setlocal conceallevel=2 + + for l:item in l:status + let l:data = matchlist(l:item, '\(.\)\(.\)\s\(.*\)') + if len(l:data) <=? 0 + continue + endif + + let l:us = l:data[1] + let l:them = l:data[2] + let l:file = l:data[3] + + if stridx(l:file, ' ') > -1 && l:file[0] ==? '"' + let l:file = trim(l:file, '"') + endif + + " Rename status returns both old and new filename "old_name.ext -> new_name.ext + " but only new name is needed here + if l:us ==# 'R' + let l:file = get(split(l:file, ' -> '), 1, l:file) + endif + + let l:file = fnamemodify(b:git_repo_path . s:sep . l:file, ':p') + " let l:file = fnamemodify(l:current_dir . s:sep . l:file, ':p') + + if s:is_in_arglist(l:file) + continue + endif + + " let l:file = matchstr(l:file, escape(l:current_dir.'[^'.s:sep.']*'.s:sep.'\?', s:escape_chars)) + " call dirvish_git#debug#log('[l:file] '. l:file) + + " if index(values(b:git_files), l:file) > -1 + " continue + " endif + + let l:line_number = search(escape(l:file, s:escape_chars), 'n') + let b:git_files[l:line_number] = l:file + + + if isdirectory(l:file) + let l:file_name = substitute(l:file, l:current_dir, '', 'g') + call dirvish_git#highlight#highlight_file(l:current_dir[:-2], l:file_name, l:us, l:them, 1) + else + let l:dir = fnamemodify(l:file, ':h') + let l:file_name = fnamemodify(l:file, ':t') + call dirvish_git#debug#log('[l:file_name] '. l:file_name) + call dirvish_git#highlight#highlight_file(l:dir, l:file_name, l:us, l:them, 0) + endif + endfor + + "Set argument list highlight again to override git highlights + let l:pat = join(map(argv(), 'escape(fnamemodify(v:val[-1:]==#s:sep?v:val[:-2]:v:val, ":t"), "*.^$~\\")'), '\|') + exe 'syntax match DirvishArg /\'.s:sep.'\@<=\%\('.l:pat.'\)\'.s:sep.'\?$/' +endfunction + +function s:update_status_handler.err(bufnr) abort + " TODO: handle error +endfunction + +function dirvish_git#utils#update_status(current_dir) abort + let repo_path = dirvish_git#utils#get_repo_path(a:current_dir, function('dirvish_git#utils#update_status', [ a:current_dir ])) + if repo_path == '[async]' + return + endif + let l:ignored = g:dirvish_git_show_ignored ? '--ignored' : '' + let cmd = printf('git status --porcelain %s %s', l:ignored, a:current_dir) + let handler = copy(s:update_status_handler) + call dirvish_git#async#execute(cmd, bufnr(), handler) +endfunction +" +function dirvish_git#utils#get_repo_path(current_dir, callback) abort + if empty(b:git_repo_path) + let cmd = printf('git -C %s rev-parse --show-toplevel', a:current_dir) + let handler = copy(s:get_repo_path_handler) + if !empty(a:callback) + let handler.callback = a:callback + endif + call dirvish_git#async#execute(cmd, bufnr(), handler) + return '[async]' + endif + return b:git_repo_path +endfunction + +let s:get_repo_path_handler = {} +function s:get_repo_path_handler.out(bufnr, output) abort + let b:git_repo_path = trim(a:output) + if !empty(self.callback) + call self.callback() + endif +endfunction + +function s:get_repo_path_handler.err(bufnr) abort + " TODO: handle error +endfunction + + +" Get rid of any trailing new line or SOH character. +" +" git ls-files -z produces output with null line termination. +" Vim's system() replaces any null characters in the output +" with SOH (start of header), i.e. ^A. +function! s:strip_trailing_new_line(line) abort + return substitute(a:line, '[[:cntrl:]]$', '', '') +endfunction + +" move all strings beginning with U or .U to the beginning of the list +function! s:unmerged_status_comparator(a, b) abort + if (a:a =~? '^U') || (a:a =~? '^.U') + return -1 + endif + return 1 +endfunction + +function s:is_in_arglist(file) abort + let l:file = fnamemodify(a:file, ':p') + let l:cwd = printf('%s%s', getcwd(), s:sep) + for l:arg in argv() + if l:arg ==# l:cwd + continue + endif + if l:file =~? l:arg + return 1 + endif + endfor + return 0 +endfunction diff --git a/plugin/dirvish_git.vim b/plugin/dirvish_git.vim index adcfc5a..8656acc 100644 --- a/plugin/dirvish_git.vim +++ b/plugin/dirvish_git.vim @@ -1,36 +1,19 @@ +" check async +if !dirvish_git#async#available() + echoe 'Need vim 7.4.1826 or nvim!' + finish +endif + if exists('g:loaded_dirvish_git') finish endif + let g:loaded_dirvish_git = 1 let g:dirvish_git_show_ignored = get(g:, 'dirvish_git_show_ignored', 0) let g:dirvish_git_show_icons = get(g:, 'dirvish_git_show_icons', 1) +let g:dirvish_git_debug = get(g:, 'dirvish_git_debug', 0) -if !exists('g:dirvish_git_indicators') - let g:dirvish_git_indicators = { - \ 'Modified' : '✹', - \ 'Staged' : '✚', - \ 'Untracked' : '✭', - \ 'Renamed' : '➜', - \ 'Unmerged' : '═', - \ 'Ignored' : '☒', - \ 'Unknown' : '?' - \ } -endif - -let s:dirvish_git_highlight_groups = { -\ 'Modified' : 'DirvishGitModified', -\ 'Staged' : 'DirvishGitStaged', -\ 'Untracked' : 'DirvishGitUntracked', -\ 'Renamed' : 'DirvishGitRenamed', -\ 'Unmerged' : 'DirvishGitUnmerged', -\ 'Ignored' : 'DirvishGitIgnored', -\ 'Unknown' : 'DirvishGitModified' -\ } - -let s:sep = exists('+shellslash') && !&shellslash ? '\' : '/' -let s:escape_chars = '.#~'.s:sep -let s:git_files = {} function! dirvish_git#init() abort if get(g:, 'dirvish_relative_paths', 0) @@ -40,217 +23,15 @@ function! dirvish_git#init() abort return 0 endif - let l:current_dir = expand('%') - let s:git_files = {} - for l:highlight_group in values(s:dirvish_git_highlight_groups) - silent! exe 'syntax clear '.l:highlight_group - endfor + let b:git_files = get(b:, 'git_files', {}) + let b:git_repo_path = '' - let l:git_root = s:get_git_root(l:current_dir) + call dirvish_git#highlight#setup_highlighting() - if empty(l:git_root) - return 0 - endif - - let l:status = s:get_status_list(l:current_dir) - - if empty(l:status) - return 0 - endif - - call s:setup_highlighting() call s:set_mappings() - setlocal conceallevel=2 - - for l:item in l:status - let l:data = matchlist(l:item, '\(.\)\(.\)\s\(.*\)') - if len(l:data) <=? 0 - continue - endif - let l:us = l:data[1] - let l:them = l:data[2] - let l:file = l:data[3] - if stridx(l:file, ' ') > -1 && l:file[0] ==? '"' - let l:file = trim(l:file, '"') - endif - - " Rename status returns both old and new filename "old_name.ext -> new_name.ext - " but only new name is needed here - if l:us ==# 'R' - let l:file = get(split(l:file, ' -> '), 1, l:file) - endif - - let l:file = fnamemodify(l:git_root.s:sep.l:file, ':p') - if s:is_in_arglist(l:file) - continue - endif - - let l:file = matchstr(l:file, escape(l:current_dir.'[^'.s:sep.']*'.s:sep.'\?', s:escape_chars)) - - if index(values(s:git_files), l:file) > -1 - continue - endif - - let l:line_number = search(escape(l:file, s:escape_chars), 'n') - let s:git_files[l:line_number] = l:file - - if isdirectory(l:file) - let l:file_name = substitute(l:file, l:current_dir, '', 'g') - call s:highlight_file(l:current_dir[:-2], l:file_name, l:us, l:them, 1) - else - let l:dir = fnamemodify(l:file, ':h') - let l:file_name = fnamemodify(l:file, ':t') - call s:highlight_file(l:dir, l:file_name, l:us, l:them, 0) - endif - endfor - - "Set argument list highlight again to override git highlights - let l:pat = join(map(argv(), 'escape(fnamemodify(v:val[-1:]==#s:sep?v:val[:-2]:v:val, ":t"), "*.^$~\\")'), '\|') - exe 'syntax match DirvishArg /\'.s:sep.'\@<=\%\('.l:pat.'\)\'.s:sep.'\?$/' -endfunction - -" move all strings beginning with U or .U to the beginning of the list -function! s:unmerged_status_comparator(a, b) abort - if (a:a =~? '^U') || (a:a =~? '^.U') - return -1 - endif - return 1 -endfunction - -function! s:get_git_root(current_dir) abort - let l:git_root = systemlist(printf('git -C %s rev-parse --show-toplevel', a:current_dir)) - - if len(l:git_root) == 0 || (len(l:git_root) == 1 && l:git_root[0] =~? '^fatal') - return '' - endif - - return l:git_root[0] -endfunction - -function! s:get_status_list(current_dir) abort - let l:ignored = g:dirvish_git_show_ignored ? '--ignored' : '' - let l:status = systemlist(printf('git status --porcelain %s %s', l:ignored, a:current_dir)) - - if len(l:status) ==? 0 || (len(l:status) ==? 1 && l:status[0] =~? '^fatal') - return [] - endif + call dirvish_git#utils#update_status(expand('%:p:h')) - "Put unmerged first to get proper status on directories - return sort(l:status, "s:unmerged_status_comparator") -endfunction - -function! s:get_indicator_name(us, them) abort - if a:us ==# '?' && a:them ==# '?' - return 'Untracked' - elseif a:us ==# ' ' && a:them ==# 'M' - return 'Modified' - elseif a:us =~# '[MAC]' - return 'Staged' - elseif a:us ==# 'R' - return 'Renamed' - elseif a:us ==# 'U' || a:them ==# 'U' || a:us ==# 'A' && a:them ==# 'A' || a:us ==# 'D' && a:them ==# 'D' - return 'Unmerged' - elseif a:us ==# '!' - return 'Ignored' - else - return 'Unknown' - endif -endfunction - -function! s:get_indicator(us, them) abort - return get(g:dirvish_git_indicators, s:get_indicator_name(a:us, a:them), '') -endfunction - -function! s:get_highlight_group(us, them, is_directory) abort - let l:group = get(s:dirvish_git_highlight_groups, s:get_indicator_name(a:us, a:them), 'DirvishGitModified') - if !a:is_directory || l:group !=? 'DirvishGitUntracked' - return l:group - endif - - return 'DirvishGitUntrackedDir' -endfunction - -function! s:highlight_file(dir, file_name, us, them, is_directory) abort - let l:file_rgx = escape(printf('\(%s\)\@<=%s%s', a:dir, s:sep, a:file_name), s:escape_chars) - let l:dir_rgx = escape(printf('%s\(%s%s\)\@=', a:dir, s:sep, a:file_name), s:escape_chars) - let l:slash_rgx = escape(printf('\(%s\)\@<=%s\(%s\)\@=', a:dir, s:sep, a:file_name), s:escape_chars) - - " Check if icons should be shown - let l:conceal_char = g:dirvish_git_show_icons ? (' cchar=' . s:get_indicator(a:us, a:them)) : '' - let l:conceal_last_folder_char = g:dirvish_git_show_icons ? ' cchar= ' : '' - - silent exe 'syn match DirvishGitDir "'.l:dir_rgx.'" conceal' . l:conceal_char - silent exe 'syn match '.s:get_highlight_group(a:us, a:them, a:is_directory).' "'.l:file_rgx.'" contains=DirvishGitSlash' - silent exe 'syn match DirvishGitSlash "'.l:slash_rgx.'" conceal contained' . l:conceal_last_folder_char -endfunction - -function! s:setup_highlighting() abort - let l:modified = 'guifg=#fabd2f ctermfg=214' - let l:added = 'guifg=#b8bb26 ctermfg=142' - let l:unmerged = 'guifg=#fb4934 ctermfg=167' - - silent exe 'hi default DirvishGitModified '.l:modified - silent exe 'hi default DirvishGitStaged '.l:added - silent exe 'hi default DirvishGitRenamed '.l:modified - silent exe 'hi default DirvishGitUnmerged '.l:unmerged - silent exe 'hi default link DirvishGitUntrackedDir DirvishPathTail' - silent exe 'hi default DirvishGitIgnored guifg=NONE guibg=NONE gui=NONE cterm=NONE ctermfg=NONE ctermbg=NONE' - silent exe 'hi default DirvishGitUntracked guifg=NONE guibg=NONE gui=NONE cterm=NONE ctermfg=NONE ctermbg=NONE' -endfunction - -function s:is_in_arglist(file) abort - let l:file = fnamemodify(a:file, ':p') - let l:cwd = printf('%s%s', getcwd(), s:sep) - for l:arg in argv() - if l:arg ==# l:cwd - continue - endif - if l:file =~? l:arg - return 1 - endif - endfor - return 0 -endfunction - -function! dirvish_git#jump_to_next_file() abort - if len(s:git_files) <=? 0 - return - endif - - let l:current_line = line('.') - let l:git_files_line_number = sort(keys(s:git_files), 'N') - - for l:line in l:git_files_line_number - if l:line > l:current_line - return cursor(l:line, 0) - endif - endfor - - return cursor(l:git_files_line_number[0], 0) -endfunction - -function! dirvish_git#jump_to_prev_file() abort - if len(s:git_files) <=? 0 - return - endif - - let l:current_line = line('.') - let l:git_files_line_number = reverse(sort(keys(s:git_files), 'N')) - - for l:line in l:git_files_line_number - if l:line < l:current_line - return cursor(l:line, 0) - endif - endfor - - return cursor(l:git_files_line_number[0], 0) -endfunction - -function! dirvish_git#reload() abort - if &filetype ==? 'dirvish' - Dirvish % - endif endfunction function! s:set_mappings() abort @@ -276,6 +57,6 @@ nnoremap (dirvish_git_prev_file) :call dirvish_git#jump_to_prev_file( augroup dirvish_git autocmd! autocmd FileType dirvish call dirvish_git#init() - autocmd BufEnter,FocusGained * call dirvish_git#reload() + autocmd BufEnter,FocusGained dirvish call dirvish_git#reload() augroup END