diff options
Diffstat (limited to 'vim/bundle/vim-gitgutter/autoload/gitgutter/diff.vim')
| m--------- | vim/bundle/vim-gitgutter | 0 | ||||
| -rw-r--r-- | vim/bundle/vim-gitgutter/autoload/gitgutter/diff.vim | 342 | 
2 files changed, 0 insertions, 342 deletions
| diff --git a/vim/bundle/vim-gitgutter b/vim/bundle/vim-gitgutter new file mode 160000 +Subproject b5f23e986747a6f4b1dc1196d2a5bd3dc7c8c2b diff --git a/vim/bundle/vim-gitgutter/autoload/gitgutter/diff.vim b/vim/bundle/vim-gitgutter/autoload/gitgutter/diff.vim deleted file mode 100644 index 170193b..0000000 --- a/vim/bundle/vim-gitgutter/autoload/gitgutter/diff.vim +++ /dev/null @@ -1,342 +0,0 @@ -if exists('g:gitgutter_grep_command') -  let s:grep_available = 1 -  let s:grep_command = g:gitgutter_grep_command -else -  let s:grep_available = executable('grep') -  if s:grep_available -    let s:grep_command = 'grep --color=never -e' -  endif -endif -let s:hunk_re = '^@@ -\(\d\+\),\?\(\d*\) +\(\d\+\),\?\(\d*\) @@' - -let s:c_flag = gitgutter#utility#git_supports_command_line_config_override() - -let s:temp_index = tempname() -let s:temp_buffer = tempname() - -" Returns a diff of the buffer. -" -" The way to get the diff depends on whether the buffer is saved or unsaved. -" -" * Saved: the buffer contents is the same as the file on disk in the working -"   tree so we simply do: -" -"       git diff myfile -" -" * Unsaved: the buffer contents is not the same as the file on disk so we -"   need to pass two instances of the file to git-diff: -" -"       git diff myfileA myfileB -" -"   The first instance is the file in the index which we obtain with: -" -"       git show :myfile > myfileA -" -"   The second instance is the buffer contents.  Ideally we would pass this to -"   git-diff on stdin via the second argument to vim's system() function. -"   Unfortunately git-diff does not do CRLF conversion for input received on -"   stdin, and git-show never performs CRLF conversion, so repos with CRLF -"   conversion report that every line is modified due to mismatching EOLs. -" -"   Instead, we write the buffer contents to a temporary file - myfileB in this -"   example.  Note the file extension must be preserved for the CRLF -"   conversion to work. -" -" Before diffing a buffer for the first time, we check whether git knows about -" the file: -" -"     git ls-files --error-unmatch myfile -" -" After running the diff we pass it through grep where available to reduce -" subsequent processing by the plugin.  If grep is not available the plugin -" does the filtering instead. -function! gitgutter#diff#run_diff(realtime, preserve_full_diff) abort -  " Wrap compound commands in parentheses to make Windows happy. -  " bash doesn't mind the parentheses. -  let cmd = '(' - -  let bufnr = gitgutter#utility#bufnr() -  let tracked = getbufvar(bufnr, 'gitgutter_tracked')  " i.e. tracked by git -  if !tracked -    " Don't bother trying to realtime-diff an untracked file. -    " NOTE: perhaps we should pull this guard up to the caller? -    if a:realtime -      throw 'diff failed' -    else -      let cmd .= g:gitgutter_git_executable.' ls-files --error-unmatch '.gitgutter#utility#shellescape(gitgutter#utility#filename()).' && (' -    endif -  endif - -  if a:realtime -    let blob_name = g:gitgutter_diff_base.':'.gitgutter#utility#shellescape(gitgutter#utility#file_relative_to_repo_root()) -    let blob_file = s:temp_index -    let buff_file = s:temp_buffer -    let extension = gitgutter#utility#extension() -    if !empty(extension) -      let blob_file .= '.'.extension -      let buff_file .= '.'.extension -    endif -    let cmd .= g:gitgutter_git_executable.' show '.blob_name.' > '.blob_file.' && ' - -    " Writing the whole buffer resets the '[ and '] marks and also the -    " 'modified' flag (if &cpoptions includes '+').  These are unwanted -    " side-effects so we save and restore the values ourselves. -    let modified      = getbufvar(bufnr, "&mod") -    let op_mark_start = getpos("'[") -    let op_mark_end   = getpos("']") - -    execute 'keepalt noautocmd silent write!' buff_file - -    call setbufvar(bufnr, "&mod", modified) -    call setpos("'[", op_mark_start) -    call setpos("']", op_mark_end) -  endif - -  let cmd .= g:gitgutter_git_executable -  if s:c_flag -    let cmd .= ' -c "diff.autorefreshindex=0"' -  endif -  let cmd .= ' diff --no-ext-diff --no-color -U0 '.g:gitgutter_diff_args.' ' - -  if a:realtime -    let cmd .= ' -- '.blob_file.' '.buff_file -  else -    let cmd .= g:gitgutter_diff_base.' -- '.gitgutter#utility#shellescape(gitgutter#utility#filename()) -  endif - -  if !a:preserve_full_diff && s:grep_available -    let cmd .= ' | '.s:grep_command.' '.gitgutter#utility#shellescape('^@@ ') -  endif - -  if (!a:preserve_full_diff && s:grep_available) || a:realtime -    " grep exits with 1 when no matches are found; diff exits with 1 when -    " differences are found.  However we want to treat non-matches and -    " differences as non-erroneous behaviour; so we OR the command with one -    " which always exits with success (0). -    let cmd .= ' || exit 0' -  endif - -  let cmd .= ')' - -  if !tracked -    let cmd .= ')' -  endif - -  let cmd = gitgutter#utility#command_in_directory_of_file(cmd) - -  if g:gitgutter_async && gitgutter#async#available() && !a:preserve_full_diff -    call gitgutter#async#execute(cmd) -    return 'async' - -  else -    let diff = gitgutter#utility#system(cmd) - -    if gitgutter#utility#shell_error() -      " A shell error indicates the file is not tracked by git (unless something bizarre is going on). -      throw 'diff failed' -    endif - -    return diff -  endif -endfunction - -function! gitgutter#diff#parse_diff(diff) abort -  let hunks = [] -  for line in split(a:diff, '\n') -    let hunk_info = gitgutter#diff#parse_hunk(line) -    if len(hunk_info) == 4 -      call add(hunks, hunk_info) -    endif -  endfor -  return hunks -endfunction - -function! gitgutter#diff#parse_hunk(line) abort -  let matches = matchlist(a:line, s:hunk_re) -  if len(matches) > 0 -    let from_line  = str2nr(matches[1]) -    let from_count = (matches[2] == '') ? 1 : str2nr(matches[2]) -    let to_line    = str2nr(matches[3]) -    let to_count   = (matches[4] == '') ? 1 : str2nr(matches[4]) -    return [from_line, from_count, to_line, to_count] -  else -    return [] -  end -endfunction - -function! gitgutter#diff#process_hunks(hunks) abort -  call gitgutter#hunk#reset() -  let modified_lines = [] -  for hunk in a:hunks -    call extend(modified_lines, gitgutter#diff#process_hunk(hunk)) -  endfor -  return modified_lines -endfunction - -" Returns [ [<line_number (number)>, <name (string)>], ...] -function! gitgutter#diff#process_hunk(hunk) abort -  let modifications = [] -  let from_line  = a:hunk[0] -  let from_count = a:hunk[1] -  let to_line    = a:hunk[2] -  let to_count   = a:hunk[3] - -  if gitgutter#diff#is_added(from_count, to_count) -    call gitgutter#diff#process_added(modifications, from_count, to_count, to_line) -    call gitgutter#hunk#increment_lines_added(to_count) - -  elseif gitgutter#diff#is_removed(from_count, to_count) -    call gitgutter#diff#process_removed(modifications, from_count, to_count, to_line) -    call gitgutter#hunk#increment_lines_removed(from_count) - -  elseif gitgutter#diff#is_modified(from_count, to_count) -    call gitgutter#diff#process_modified(modifications, from_count, to_count, to_line) -    call gitgutter#hunk#increment_lines_modified(to_count) - -  elseif gitgutter#diff#is_modified_and_added(from_count, to_count) -    call gitgutter#diff#process_modified_and_added(modifications, from_count, to_count, to_line) -    call gitgutter#hunk#increment_lines_added(to_count - from_count) -    call gitgutter#hunk#increment_lines_modified(from_count) - -  elseif gitgutter#diff#is_modified_and_removed(from_count, to_count) -    call gitgutter#diff#process_modified_and_removed(modifications, from_count, to_count, to_line) -    call gitgutter#hunk#increment_lines_modified(to_count) -    call gitgutter#hunk#increment_lines_removed(from_count - to_count) - -  endif -  return modifications -endfunction - -function! gitgutter#diff#is_added(from_count, to_count) abort -  return a:from_count == 0 && a:to_count > 0 -endfunction - -function! gitgutter#diff#is_removed(from_count, to_count) abort -  return a:from_count > 0 && a:to_count == 0 -endfunction - -function! gitgutter#diff#is_modified(from_count, to_count) abort -  return a:from_count > 0 && a:to_count > 0 && a:from_count == a:to_count -endfunction - -function! gitgutter#diff#is_modified_and_added(from_count, to_count) abort -  return a:from_count > 0 && a:to_count > 0 && a:from_count < a:to_count -endfunction - -function! gitgutter#diff#is_modified_and_removed(from_count, to_count) abort -  return a:from_count > 0 && a:to_count > 0 && a:from_count > a:to_count -endfunction - -function! gitgutter#diff#process_added(modifications, from_count, to_count, to_line) abort -  let offset = 0 -  while offset < a:to_count -    let line_number = a:to_line + offset -    call add(a:modifications, [line_number, 'added']) -    let offset += 1 -  endwhile -endfunction - -function! gitgutter#diff#process_removed(modifications, from_count, to_count, to_line) abort -  if a:to_line == 0 -    call add(a:modifications, [1, 'removed_first_line']) -  else -    call add(a:modifications, [a:to_line, 'removed']) -  endif -endfunction - -function! gitgutter#diff#process_modified(modifications, from_count, to_count, to_line) abort -  let offset = 0 -  while offset < a:to_count -    let line_number = a:to_line + offset -    call add(a:modifications, [line_number, 'modified']) -    let offset += 1 -  endwhile -endfunction - -function! gitgutter#diff#process_modified_and_added(modifications, from_count, to_count, to_line) abort -  let offset = 0 -  while offset < a:from_count -    let line_number = a:to_line + offset -    call add(a:modifications, [line_number, 'modified']) -    let offset += 1 -  endwhile -  while offset < a:to_count -    let line_number = a:to_line + offset -    call add(a:modifications, [line_number, 'added']) -    let offset += 1 -  endwhile -endfunction - -function! gitgutter#diff#process_modified_and_removed(modifications, from_count, to_count, to_line) abort -  let offset = 0 -  while offset < a:to_count -    let line_number = a:to_line + offset -    call add(a:modifications, [line_number, 'modified']) -    let offset += 1 -  endwhile -  let a:modifications[-1] = [a:to_line + offset - 1, 'modified_removed'] -endfunction - -" Generates a zero-context diff for the current hunk. -" -" diff - the full diff for the buffer -" type - stage | undo | preview -function! gitgutter#diff#generate_diff_for_hunk(diff, type) abort -  let diff_for_hunk = gitgutter#diff#discard_hunks(a:diff, a:type == 'stage' || a:type == 'undo') - -  if a:type == 'stage' || a:type == 'undo' -    let diff_for_hunk = gitgutter#diff#adjust_hunk_summary(diff_for_hunk, a:type == 'stage') -  endif - -  return diff_for_hunk -endfunction - -" Returns the diff with all hunks discarded except the current. -" -" diff        - the diff to process -" keep_header - truthy to keep the diff header and hunk summary, falsy to discard it -function! gitgutter#diff#discard_hunks(diff, keep_header) abort -  let modified_diff = [] -  let keep_line = a:keep_header -  for line in split(a:diff, '\n') -    let hunk_info = gitgutter#diff#parse_hunk(line) -    if len(hunk_info) == 4  " start of new hunk -      let keep_line = gitgutter#hunk#cursor_in_hunk(hunk_info) -    endif -    if keep_line -      call add(modified_diff, line) -    endif -  endfor - -  if a:keep_header -    return gitgutter#utility#stringify(modified_diff) -  else -    " Discard hunk summary too. -    return gitgutter#utility#stringify(modified_diff[1:]) -  endif -endfunction - -" Adjust hunk summary (from's / to's line number) to ignore changes above/before this one. -" -" diff_for_hunk - a diff containing only the hunk of interest -" staging       - truthy if the hunk is to be staged, falsy if it is to be undone -" -" TODO: push this down to #discard_hunks? -function! gitgutter#diff#adjust_hunk_summary(diff_for_hunk, staging) abort -  let line_adjustment = gitgutter#hunk#line_adjustment_for_current_hunk() -  let adj_diff = [] -  for line in split(a:diff_for_hunk, '\n') -    if match(line, s:hunk_re) != -1 -      if a:staging -        " increment 'to' line number -        let line = substitute(line, '+\@<=\(\d\+\)', '\=submatch(1)+line_adjustment', '') -      else -        " decrement 'from' line number -        let line = substitute(line, '-\@<=\(\d\+\)', '\=submatch(1)-line_adjustment', '') -      endif -    endif -    call add(adj_diff, line) -  endfor -  return gitgutter#utility#stringify(adj_diff) -endfunction - | 
