Support jump to file under cursor in :Git -p grep

This also adds support for :Git -p status, since we basically already
have an implementation for it.
This commit is contained in:
Tim Pope
2021-08-16 18:03:39 -04:00
parent 2d3e83abe3
commit 80e7c63fb1
2 changed files with 37 additions and 18 deletions

View File

@@ -5084,6 +5084,20 @@ function! s:GrepOptions(args, dir) abort
return options return options
endfunction endfunction
function! s:GrepCfile(result) abort
let options = s:GrepOptions(a:result.args, a:result)
let entry = s:GrepParseLine(options, a:result, getline('.'))
if get(entry, 'col')
return [entry.filename, entry.lnum, "norm!" . entry.col . "|"]
elseif has_key(entry, 'lnum')
return [entry.filename, entry.lnum]
elseif has_key(entry, 'filename')
return [entry.filename]
else
return []
endif
endfunction
function! s:GrepSubcommand(line1, line2, range, bang, mods, options) abort function! s:GrepSubcommand(line1, line2, range, bang, mods, options) abort
let args = copy(a:options.subcommand_args) let args = copy(a:options.subcommand_args)
let handle = -1 let handle = -1
@@ -7045,7 +7059,7 @@ endfunction
function! fugitive#GX() abort function! fugitive#GX() abort
try try
let results = &filetype ==# 'fugitive' ? s:StatusCfile() : &filetype ==# 'git' ? s:cfile() : [] let results = &filetype ==# 'fugitive' ? s:CfilePorcelain() : &filetype ==# 'git' ? s:cfile() : []
if len(results) && len(results[0]) if len(results) && len(results[0])
return FugitiveReal(s:Generate(results[0])) return FugitiveReal(s:Generate(results[0]))
endif endif
@@ -7054,7 +7068,7 @@ function! fugitive#GX() abort
return expand(get(g:, 'netrw_gx', expand('<cfile>'))) return expand(get(g:, 'netrw_gx', expand('<cfile>')))
endfunction endfunction
function! s:StatusCfile(...) abort function! s:CfilePorcelain(...) abort
let tree = s:Tree() let tree = s:Tree()
if empty(tree) if empty(tree)
return [''] return ['']
@@ -7081,42 +7095,47 @@ function! s:StatusCfile(...) abort
endif endif
endfunction endfunction
function! fugitive#StatusCfile() abort function! fugitive#PorcelainCfile() abort
let file = fugitive#Find(s:StatusCfile()[0]) let file = fugitive#Find(s:CfilePorcelain()[0])
return empty(file) ? fugitive#Cfile() : s:fnameescape(file) return empty(file) ? fugitive#Cfile() : s:fnameescape(file)
endfunction endfunction
function! s:MessageCfile(...) abort function! s:StatusCfile(...) abort
let tree = s:Tree() let tree = s:Tree()
if empty(tree) if empty(tree)
return '' return ''
endif endif
let lead = s:cpath(tree, getcwd()) ? './' : tree . '/' let lead = s:cpath(tree, getcwd()) ? './' : tree . '/'
if getline('.') =~# '^.\=\trenamed:.* -> ' if getline('.') =~# '^.\=\trenamed:.* -> '
return lead . matchstr(getline('.'),' -> \zs.*') return [lead . matchstr(getline('.'),' -> \zs.*')]
elseif getline('.') =~# '^.\=\t\(\k\| \)\+\p\?: *.' elseif getline('.') =~# '^.\=\t\(\k\| \)\+\p\?: *.'
return lead . matchstr(getline('.'),': *\zs.\{-\}\ze\%( ([^()[:digit:]]\+)\)\=$') return [lead . matchstr(getline('.'),': *\zs.\{-\}\ze\%( ([^()[:digit:]]\+)\)\=$')]
elseif getline('.') =~# '^.\=\t.' elseif getline('.') =~# '^.\=\t.'
return lead . matchstr(getline('.'),'\t\zs.*') return [lead . matchstr(getline('.'),'\t\zs.*')]
elseif getline('.') =~# ': needs merge$' elseif getline('.') =~# ': needs merge$'
return lead . matchstr(getline('.'),'.*\ze: needs merge$') return [lead . matchstr(getline('.'),'.*\ze: needs merge$')]
elseif getline('.') =~# '^\%(. \)\=Not currently on any branch.$' elseif getline('.') =~# '^\%(. \)\=Not currently on any branch.$'
return 'HEAD' return ['HEAD']
elseif getline('.') =~# '^\%(. \)\=On branch ' elseif getline('.') =~# '^\%(. \)\=On branch '
return 'refs/heads/'.getline('.')[12:] return ['refs/heads/'.getline('.')[12:]]
elseif getline('.') =~# "^\\%(. \\)\=Your branch .*'" elseif getline('.') =~# "^\\%(. \\)\=Your branch .*'"
return matchstr(getline('.'),"'\\zs\\S\\+\\ze'") return [matchstr(getline('.'),"'\\zs\\S\\+\\ze'")]
else else
return '' return []
endif endif
endfunction endfunction
function! fugitive#MessageCfile() abort function! fugitive#MessageCfile() abort
let file = fugitive#Find(s:MessageCfile()) let file = fugitive#Find(get(s:StatusCfile(), 0, ''))
return empty(file) ? fugitive#Cfile() : s:fnameescape(file) return empty(file) ? fugitive#Cfile() : s:fnameescape(file)
endfunction endfunction
function! s:cfile() abort function! s:cfile() abort
let temp_state = s:TempState()
let name = substitute(get(get(temp_state, 'args', []), 0, ''), '\%(^\|-\)\(\l\)', '\u\1', 'g')
if exists('*s:' . name . 'Cfile')
return s:{name}Cfile(temp_state)
endif
if empty(FugitiveGitDir()) if empty(FugitiveGitDir())
return [] return []
endif endif
@@ -7129,7 +7148,7 @@ function! s:cfile() abort
let myhash = '' let myhash = ''
endtry endtry
endif endif
if empty(myhash) && get(s:TempState(), 'filetype', '') ==# 'git' if empty(myhash) && get(temp_state, 'filetype', '') ==# 'git'
let lnum = line('.') let lnum = line('.')
while lnum > 0 while lnum > 0
if getline(lnum) =~# '^\%(commit\|tag\) \w' if getline(lnum) =~# '^\%(commit\|tag\) \w'
@@ -7282,13 +7301,13 @@ endfunction
function! s:GF(mode) abort function! s:GF(mode) abort
try try
let results = &filetype ==# 'fugitive' ? s:StatusCfile() : &filetype ==# 'gitcommit' ? [s:MessageCfile()] : s:cfile() let results = &filetype ==# 'fugitive' ? s:CfilePorcelain() : &filetype ==# 'gitcommit' ? s:StatusCfile() : s:cfile()
catch /^fugitive:/ catch /^fugitive:/
return 'echoerr ' . string(v:exception) return 'echoerr ' . string(v:exception)
endtry endtry
if len(results) > 1 if len(results) > 1
return 'G' . a:mode . return 'G' . a:mode .
\ ' +' . escape(results[1], ' ') . ' ' . \ ' +' . escape(results[1], ' |') . ' ' .
\ s:fnameescape(results[0]) . join(map(results[2:-1], '"|" . v:val'), '') \ s:fnameescape(results[0]) . join(map(results[2:-1], '"|" . v:val'), '')
elseif len(results) && len(results[0]) elseif len(results) && len(results[0])
return 'G' . a:mode . ' ' . s:fnameescape(results[0]) return 'G' . a:mode . ' ' . s:fnameescape(results[0])

View File

@@ -546,7 +546,7 @@ augroup fugitive
\ setlocal foldtext=fugitive#Foldtext() | \ setlocal foldtext=fugitive#Foldtext() |
\ endif \ endif
autocmd FileType fugitive autocmd FileType fugitive
\ call fugitive#MapCfile('fugitive#StatusCfile()') \ call fugitive#MapCfile('fugitive#PorcelainCfile()')
autocmd FileType gitrebase autocmd FileType gitrebase
\ let &l:include = '^\%(pick\|squash\|edit\|reword\|fixup\|drop\|[pserfd]\)\>' | \ let &l:include = '^\%(pick\|squash\|edit\|reword\|fixup\|drop\|[pserfd]\)\>' |
\ if &l:includeexpr !~# 'Fugitive' | \ if &l:includeexpr !~# 'Fugitive' |