gitgutter.vim 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. " Primary functions {{{
  2. function! gitgutter#all()
  3. for buffer_id in tabpagebuflist()
  4. let file = expand('#' . buffer_id . ':p')
  5. if !empty(file)
  6. call gitgutter#process_buffer(buffer_id, 0)
  7. endif
  8. endfor
  9. endfunction
  10. " bufnr: (integer) the buffer to process.
  11. " realtime: (boolean) when truthy, do a realtime diff; otherwise do a disk-based diff.
  12. function! gitgutter#process_buffer(bufnr, realtime)
  13. call gitgutter#utility#set_buffer(a:bufnr)
  14. if gitgutter#utility#is_active()
  15. if g:gitgutter_sign_column_always
  16. call gitgutter#sign#add_dummy_sign()
  17. endif
  18. try
  19. if !a:realtime || gitgutter#utility#has_fresh_changes()
  20. let diff = gitgutter#diff#run_diff(a:realtime || gitgutter#utility#has_unsaved_changes(), 1)
  21. call gitgutter#hunk#set_hunks(gitgutter#diff#parse_diff(diff))
  22. let modified_lines = gitgutter#diff#process_hunks(gitgutter#hunk#hunks())
  23. if len(modified_lines) > g:gitgutter_max_signs
  24. call gitgutter#utility#warn('exceeded maximum number of signs (configured by g:gitgutter_max_signs).')
  25. call gitgutter#sign#clear_signs()
  26. return
  27. endif
  28. if g:gitgutter_signs || g:gitgutter_highlight_lines
  29. call gitgutter#sign#update_signs(modified_lines)
  30. endif
  31. call gitgutter#utility#save_last_seen_change()
  32. endif
  33. catch /diff failed/
  34. call gitgutter#hunk#reset()
  35. endtry
  36. else
  37. call gitgutter#hunk#reset()
  38. endif
  39. endfunction
  40. function! gitgutter#disable()
  41. " get list of all buffers (across all tabs)
  42. let buflist = []
  43. for i in range(tabpagenr('$'))
  44. call extend(buflist, tabpagebuflist(i + 1))
  45. endfor
  46. for buffer_id in buflist
  47. let file = expand('#' . buffer_id . ':p')
  48. if !empty(file)
  49. call gitgutter#utility#set_buffer(buffer_id)
  50. call gitgutter#sign#clear_signs()
  51. call gitgutter#sign#remove_dummy_sign(1)
  52. call gitgutter#hunk#reset()
  53. endif
  54. endfor
  55. let g:gitgutter_enabled = 0
  56. endfunction
  57. function! gitgutter#enable()
  58. let g:gitgutter_enabled = 1
  59. call gitgutter#all()
  60. endfunction
  61. function! gitgutter#toggle()
  62. if g:gitgutter_enabled
  63. call gitgutter#disable()
  64. else
  65. call gitgutter#enable()
  66. endif
  67. endfunction
  68. " }}}
  69. " Line highlights {{{
  70. function! gitgutter#line_highlights_disable()
  71. let g:gitgutter_highlight_lines = 0
  72. call gitgutter#highlight#define_sign_line_highlights()
  73. if !g:gitgutter_signs
  74. call gitgutter#sign#clear_signs()
  75. call gitgutter#sign#remove_dummy_sign(0)
  76. endif
  77. redraw!
  78. endfunction
  79. function! gitgutter#line_highlights_enable()
  80. let old_highlight_lines = g:gitgutter_highlight_lines
  81. let g:gitgutter_highlight_lines = 1
  82. call gitgutter#highlight#define_sign_line_highlights()
  83. if !old_highlight_lines && !g:gitgutter_signs
  84. call gitgutter#all()
  85. endif
  86. redraw!
  87. endfunction
  88. function! gitgutter#line_highlights_toggle()
  89. if g:gitgutter_highlight_lines
  90. call gitgutter#line_highlights_disable()
  91. else
  92. call gitgutter#line_highlights_enable()
  93. endif
  94. endfunction
  95. " }}}
  96. " Signs {{{
  97. function! gitgutter#signs_enable()
  98. let old_signs = g:gitgutter_signs
  99. let g:gitgutter_signs = 1
  100. call gitgutter#highlight#define_sign_text_highlights()
  101. if !old_signs && !g:gitgutter_highlight_lines
  102. call gitgutter#all()
  103. endif
  104. endfunction
  105. function! gitgutter#signs_disable()
  106. let g:gitgutter_signs = 0
  107. call gitgutter#highlight#define_sign_text_highlights()
  108. if !g:gitgutter_highlight_lines
  109. call gitgutter#sign#clear_signs()
  110. call gitgutter#sign#remove_dummy_sign(0)
  111. endif
  112. endfunction
  113. function! gitgutter#signs_toggle()
  114. if g:gitgutter_signs
  115. call gitgutter#signs_disable()
  116. else
  117. call gitgutter#signs_enable()
  118. endif
  119. endfunction
  120. " }}}
  121. " Hunks {{{
  122. function! gitgutter#stage_hunk()
  123. if gitgutter#utility#is_active()
  124. " Ensure the working copy of the file is up to date.
  125. " It doesn't make sense to stage a hunk otherwise.
  126. silent write
  127. if empty(gitgutter#hunk#current_hunk())
  128. call gitgutter#utility#warn('cursor is not in a hunk')
  129. else
  130. let diff_for_hunk = gitgutter#diff#generate_diff_for_hunk('stage')
  131. call gitgutter#utility#system(gitgutter#utility#command_in_directory_of_file('git apply --cached --unidiff-zero - '), diff_for_hunk)
  132. " refresh gitgutter's view of buffer
  133. silent execute "GitGutter"
  134. endif
  135. silent! call repeat#set("\<Plug>GitGutterStageHunk", -1)<CR>
  136. endif
  137. endfunction
  138. function! gitgutter#revert_hunk()
  139. if gitgutter#utility#is_active()
  140. " Ensure the working copy of the file is up to date.
  141. " It doesn't make sense to stage a hunk otherwise.
  142. silent write
  143. if empty(gitgutter#hunk#current_hunk())
  144. call gitgutter#utility#warn('cursor is not in a hunk')
  145. else
  146. let diff_for_hunk = gitgutter#diff#generate_diff_for_hunk('revert')
  147. call gitgutter#utility#system(gitgutter#utility#command_in_directory_of_file('git apply --reverse --unidiff-zero - '), diff_for_hunk)
  148. " reload file
  149. silent edit
  150. endif
  151. silent! call repeat#set("\<Plug>GitGutterRevertHunk", -1)<CR>
  152. endif
  153. endfunction
  154. function! gitgutter#preview_hunk()
  155. if gitgutter#utility#is_active()
  156. silent write
  157. if empty(gitgutter#hunk#current_hunk())
  158. call gitgutter#utility#warn('cursor is not in a hunk')
  159. else
  160. let diff_for_hunk = gitgutter#diff#generate_diff_for_hunk('preview')
  161. silent! wincmd P
  162. if !&previewwindow
  163. execute 'bo ' . &previewheight . ' new'
  164. set previewwindow
  165. endif
  166. setlocal noro modifiable filetype=diff buftype=nofile bufhidden=delete noswapfile
  167. execute "%delete_"
  168. call append(0, split(diff_for_hunk, "\n"))
  169. wincmd p
  170. endif
  171. endif
  172. endfunction
  173. " }}}