From de5c58104511db1464722d8ddddb9889afa9a34b Mon Sep 17 00:00:00 2001 From: lambdalisue Date: Fri, 30 Oct 2015 22:58:33 +0900 Subject: [PATCH 1/2] Add grep/git source --- autoload/unite/sources/grep_git.vim | 116 ++++++++++++++++++++++++++++ doc/unite.txt | 28 +++++++ 2 files changed, 144 insertions(+) create mode 100644 autoload/unite/sources/grep_git.vim diff --git a/autoload/unite/sources/grep_git.vim b/autoload/unite/sources/grep_git.vim new file mode 100644 index 00000000..d3929d92 --- /dev/null +++ b/autoload/unite/sources/grep_git.vim @@ -0,0 +1,116 @@ +"============================================================================= +" FILE: grep_git.vim +" AUTHOR: Alisue +" License: MIT license {{{ +" Permission is hereby granted, free of charge, to any person obtaining +" a copy of this software and associated documentation files (the +" "Software"), to deal in the Software without restriction, including +" without limitation the rights to use, copy, modify, merge, publish, +" distribute, sublicense, and/or sell copies of the Software, and to +" permit persons to whom the Software is furnished to do so, subject to +" the following conditions: +" +" The above copyright notice and this permission notice shall be included +" in all copies or substantial portions of the Software. +" +" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +" IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +" CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +" TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +" SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +" }}} +"============================================================================= + +function! unite#sources#grep_git#define() abort "{{{ + return s:source +endfunction "}}} + +function! unite#sources#grep_git#is_available() abort "{{{ + if !executable('git') + return 0 + endif + call unite#util#system('git rev-parse') + return (unite#util#get_last_status() == 0) ? 1 : 0 +endfunction "}}} +function! unite#sources#grep_git#repository_root() abort "{{{ + if !executable('git') + return '' + endif + let stdout = unite#util#system('git rev-parse --show-toplevel') + return (unite#util#get_last_status() == 0) ? stdout : '' +endfunction "}}} + +" Inherit from 'grep' source +let s:origin = unite#sources#grep#define() +let s:source = deepcopy(s:origin) +let s:source['name'] = 'grep/git' +let s:source['description'] = 'candidates from git grep' + +function! s:source.hooks.on_init(args, context) abort "{{{ + if get(a:args, 0, '') ==# '/' + let a:args[0] = unite#sources#grep_git#repository_root() + endif + return s:origin.hooks.on_init(a:args, a:context) +endfunction " }}} + + +function! s:source.gather_candidates(args, context) abort "{{{ + " + " Note: + " Most of code in this function was copied from unite.vim + " + if !executable('git') + call unite#print_source_message( + \ 'command "git" is not executable.', s:source.name) + let a:context.is_async = 0 + return [] + elseif !unite#sources#grep_git#is_available() + call unite#print_source_message( + \ 'the current working directory is not in a git repository.', s:source.name) + let a:context.is_async = 0 + return [] + endif + + if !unite#util#has_vimproc() + call unite#print_source_message( + \ 'vimproc plugin is not installed.', self.name) + let a:context.is_async = 0 + return [] + endif + + if empty(a:context.source__targets) + \ || a:context.source__input == '' + call unite#print_source_message('Canceled.', s:source.name) + let a:context.is_async = 0 + return [] + endif + + if a:context.is_redraw + let a:context.is_async = 1 + endif + + let cmdline = printf('git grep -n --no-color %s %s -- %s', + \ a:context.source__extra_opts, + \ string(a:context.source__input), + \ unite#helper#join_targets(a:context.source__targets), + \) + call unite#print_source_message('Command-line: ' . cmdline, s:source.name) + + " Note: + " --no-color is specified thus $TERM='dumb' is not required (actually git + " will blame if the $TERM value is not properly configured thus it should + " not be 'dumb'). + " + " Note: + " 'git grep' does not work properly with PTY + " + let a:context.source__proc = vimproc#plineopen3( + \ vimproc#util#iconv(cmdline, &encoding, 'char'), 0) + + return self.async_gather_candidates(a:args, a:context) +endfunction "}}} + + +" vim: foldmethod=marker diff --git a/doc/unite.txt b/doc/unite.txt index 06a89a2d..85d9916f 100644 --- a/doc/unite.txt +++ b/doc/unite.txt @@ -2317,6 +2317,34 @@ grep Nominates "grep" command output as candidates. let g:unite_source_grep_recursive_opt = '-R' endif < + *unite-source-grep-git* +grep/git Nominates "git grep" command output at the current + working directory as candidates. This source require to be + executed on a git repository. + + Note: This source requires |vimproc|. Please install. + http://github.com/Shougo/vimproc + + Source arguments: + 1. the target directories n the git repository splitted by + newlines. + 2. "git grep" options. + 3. the narrowing pattern (if you omit it, |unite-options-input| + or input prompt is used). + Max candidates: |g:unite_source_grep_max_candidates| + + Special Target: + % : Current buffer name + # : Alternate buffer name + $buffers : All buffer names + / : Git repository root + + Example: +> + :Unite grep/git:/:--cached:file +< + + *unite-source-find* *unite-source-vimgrep* vimgrep Nominates |vimgrep| command output as candidates. This source is slower than |unite-source-grep|, but it can From 1d93761f2b7d93076c03b4355c7481f554af9ae6 Mon Sep 17 00:00:00 2001 From: lambdalisue Date: Sat, 31 Oct 2015 15:47:01 +0900 Subject: [PATCH 2/2] Substitute ^/ of source__targets into the repository root path --- autoload/unite/sources/grep_git.vim | 17 ++++++++--------- doc/unite.txt | 5 +++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/autoload/unite/sources/grep_git.vim b/autoload/unite/sources/grep_git.vim index d3929d92..9d1704f0 100644 --- a/autoload/unite/sources/grep_git.vim +++ b/autoload/unite/sources/grep_git.vim @@ -39,7 +39,9 @@ function! unite#sources#grep_git#repository_root() abort "{{{ return '' endif let stdout = unite#util#system('git rev-parse --show-toplevel') - return (unite#util#get_last_status() == 0) ? stdout : '' + return (unite#util#get_last_status() == 0) + \ ? substitute(stdout, '\v\r?\n$', '', '') + \ : '' endfunction "}}} " Inherit from 'grep' source @@ -48,14 +50,6 @@ let s:source = deepcopy(s:origin) let s:source['name'] = 'grep/git' let s:source['description'] = 'candidates from git grep' -function! s:source.hooks.on_init(args, context) abort "{{{ - if get(a:args, 0, '') ==# '/' - let a:args[0] = unite#sources#grep_git#repository_root() - endif - return s:origin.hooks.on_init(a:args, a:context) -endfunction " }}} - - function! s:source.gather_candidates(args, context) abort "{{{ " " Note: @@ -87,6 +81,11 @@ function! s:source.gather_candidates(args, context) abort "{{{ return [] endif + " replace ^/ into the repository root + let root = unite#sources#grep_git#repository_root() + call map(a:context.source__targets, 'substitute(v:val, "^/", root . "/", "")') + echomsg string(a:context.source__targets) + if a:context.is_redraw let a:context.is_async = 1 endif diff --git a/doc/unite.txt b/doc/unite.txt index 85d9916f..eef80324 100644 --- a/doc/unite.txt +++ b/doc/unite.txt @@ -2326,8 +2326,9 @@ grep/git Nominates "git grep" command output at the current http://github.com/Shougo/vimproc Source arguments: - 1. the target directories n the git repository splitted by - newlines. + 1. the target directories in the git repository splitted by + newlines. If the directory starts from "/", the "/" will + be substituted to the repository root path. 2. "git grep" options. 3. the narrowing pattern (if you omit it, |unite-options-input| or input prompt is used).