aboutsummaryrefslogtreecommitdiff
path: root/vim/bundle/vim-gitgutter/autoload/gitgutter/hunk.vim
blob: 0fd024682c27d006cef043d3fde09f3324af95d7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
let s:hunks = []

function! gitgutter#hunk#set_hunks(hunks) abort
  let s:hunks = a:hunks
endfunction

function! gitgutter#hunk#hunks() abort
  return s:hunks
endfunction

function! gitgutter#hunk#summary(bufnr) abort
  return get(getbufvar(a:bufnr,''), 'gitgutter_summary', [0,0,0])
endfunction

function! gitgutter#hunk#reset() abort
  call setbufvar(gitgutter#utility#bufnr(), 'gitgutter_summary', [0,0,0])
endfunction

function! gitgutter#hunk#increment_lines_added(count) abort
  let bufnr = gitgutter#utility#bufnr()
  let summary = gitgutter#hunk#summary(bufnr)
  let summary[0] += a:count
  call setbufvar(bufnr, 'gitgutter_summary', summary)
endfunction

function! gitgutter#hunk#increment_lines_modified(count) abort
  let bufnr = gitgutter#utility#bufnr()
  let summary = gitgutter#hunk#summary(bufnr)
  let summary[1] += a:count
  call setbufvar(bufnr, 'gitgutter_summary', summary)
endfunction

function! gitgutter#hunk#increment_lines_removed(count) abort
  let bufnr = gitgutter#utility#bufnr()
  let summary = gitgutter#hunk#summary(bufnr)
  let summary[2] += a:count
  call setbufvar(bufnr, 'gitgutter_summary', summary)
endfunction

function! gitgutter#hunk#next_hunk(count) abort
  if gitgutter#utility#is_active()
    let current_line = line('.')
    let hunk_count = 0
    for hunk in s:hunks
      if hunk[2] > current_line
        let hunk_count += 1
        if hunk_count == a:count
          execute 'normal!' hunk[2] . 'G'
          return
        endif
      endif
    endfor
    call gitgutter#utility#warn('No more hunks')
  endif
endfunction

function! gitgutter#hunk#prev_hunk(count) abort
  if gitgutter#utility#is_active()
    let current_line = line('.')
    let hunk_count = 0
    for hunk in reverse(copy(s:hunks))
      if hunk[2] < current_line
        let hunk_count += 1
        if hunk_count == a:count
          let target = hunk[2] == 0 ? 1 : hunk[2]
          execute 'normal!' target . 'G'
          return
        endif
      endif
    endfor
    call gitgutter#utility#warn('No previous hunks')
  endif
endfunction

" Returns the hunk the cursor is currently in or an empty list if the cursor
" isn't in a hunk.
function! gitgutter#hunk#current_hunk() abort
  let current_hunk = []

  for hunk in s:hunks
    if gitgutter#hunk#cursor_in_hunk(hunk)
      let current_hunk = hunk
      break
    endif
  endfor

  return current_hunk
endfunction

function! gitgutter#hunk#cursor_in_hunk(hunk) abort
  let current_line = line('.')

  if current_line == 1 && a:hunk[2] == 0
    return 1
  endif

  if current_line >= a:hunk[2] && current_line < a:hunk[2] + (a:hunk[3] == 0 ? 1 : a:hunk[3])
    return 1
  endif

  return 0
endfunction

" Returns the number of lines the current hunk is offset from where it would
" be if any changes above it in the file didn't exist.
function! gitgutter#hunk#line_adjustment_for_current_hunk() abort
  let adj = 0
  for hunk in s:hunks
    if gitgutter#hunk#cursor_in_hunk(hunk)
      break
    else
      let adj += hunk[1] - hunk[3]
    endif
  endfor
  return adj
endfunction

function! gitgutter#hunk#text_object(inner) abort
  let hunk = gitgutter#hunk#current_hunk()

  if empty(hunk)
    return
  endif

  let [first_line, last_line] = [hunk[2], hunk[2] + hunk[3] - 1]

  if ! a:inner
    let lnum = last_line
    let eof = line('$')
    while lnum < eof && empty(getline(lnum + 1))
      let lnum +=1
    endwhile
    let last_line = lnum
  endif

  execute 'normal! 'first_line.'GV'.last_line.'G'
endfunction