-
-
Notifications
You must be signed in to change notification settings - Fork 9
/
buf.vim
101 lines (86 loc) · 2.36 KB
/
buf.vim
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
" buf.vim: Utilities for working with buffers.
" Get all lines in the buffer as a list.
fun! gopher#buf#lines() abort
return getline(1, '$')
endfun
" Get a list of all Go bufnrs.
fun! gopher#buf#list() abort
return filter(
\ range(1, bufnr('$')),
\ { i, v -> bufexists(l:v) && buflisted(l:v) && bufname(l:v)[-3:] is# '.go' })
endfun
" Run a command on every Go buffer and restore the position to the active
" buffer.
fun! gopher#buf#doall(cmd) abort
let l:s = bufnr('%')
let l:lz = &lazyredraw
try
set lazyredraw " Reduces a lot of flashing
for l:b in gopher#buf#list()
silent exe l:b . 'bufdo ' . a:cmd
endfor
finally
silent exe 'buffer ' . l:s
let &lazyredraw = l:lz
endtry
endfun
" Save all unwritten Go buffers.
fun! gopher#buf#write_all() abort
let l:s = bufnr('%')
let l:lz = &lazyredraw
try
set lazyredraw " Reduces a lot of flashing
for l:b in gopher#buf#list()
exe 'buffer ' . l:b
if &modified
silent w
endif
endfor
finally
silent exe 'buffer ' . l:s
let &lazyredraw = l:lz
endtry
endfun
" Returns the byte offset for the cursor.
"
" If the first argument is non-blank it will return filename:#offset
fun! gopher#buf#cursor(...) abort
let l:o = line2byte(line('.')) + (col('.') - 2)
if len(a:000) > 0 && a:000[0]
return printf('%s:#%d', expand('%:p'), l:o)
endif
return l:o
endfun
" Replace text from byte offset 'start' to offset 'end'.
fun! gopher#buf#replace(start, end, data) abort
let l:data = a:data
if type(l:data) is v:t_list
let l:data = join(l:data, "\n")
endif
try
let l:save = winsaveview()
let l:a = @a
let l:lastline = line('$')
let @a = l:data
keepjumps exe 'goto' a:start
" No end given, just paste at this location.
if a:end is 0
normal! "aP
else
normal! v
normal! m<
keepjumps exe 'goto' a:end
normal! m>
normal! gv"_d"ap
endif
finally
" Keep cursor on the same line as it was before.
" TODO: if lines were added below the cursor then this is borked; only works
" if lines were modified above the cursor.
let l:save['lnum'] += line('$') - l:lastline
let l:save['topline'] += line('$') - l:lastline
call winrestview(l:save)
let @a = l:a
" TODO: restore visual selection as well, but I don't think that's possible.
endtry
endfun