forked from jdhao/nvim-config
-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils.vim
194 lines (167 loc) · 5.67 KB
/
utils.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
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
" Create command alias safely, see https://stackoverflow.com/q/3878692/6064933
" The following two functions are taken from answer below on SO:
" https://stackoverflow.com/a/10708687/6064933
function! utils#Cabbrev(key, value) abort
execute printf('cabbrev <expr> %s (getcmdtype() == ":" && getcmdpos() <= %d) ? %s : %s',
\ a:key, 1+len(a:key), <SID>Single_quote(a:value), <SID>Single_quote(a:key))
endfunction
function! s:Single_quote(str) abort
return "'" . substitute(copy(a:str), "'", "''", 'g') . "'"
endfunction
" Check the syntax group in the current cursor position, see
" https://stackoverflow.com/q/9464844/6064933 and
" https://jordanelver.co.uk/blog/2015/05/27/working-with-vim-colorschemes/
function! utils#SynGroup() abort
if !exists('*synstack')
return
endif
echo map(synstack(line('.'), col('.')), 'synIDattr(v:val, "name")')
endfunction
" Check if a colorscheme exists in runtimepath.
" The following two functions are inspired by https://stackoverflow.com/a/5703164/6064933.
function! utils#HasColorscheme(name) abort
let l:pat = printf('colors/%s.vim', a:name)
return !empty(globpath(&runtimepath, l:pat))
endfunction
" Custom fold expr, adapted from https://vi.stackexchange.com/a/9094/15292
function! utils#VimFolds(lnum) abort
" get content of current line and the line below
let l:cur_line = getline(a:lnum)
let l:next_line = getline(a:lnum+1)
if l:cur_line =~# '^"{'
return '>' . (matchend(l:cur_line, '"{*') - 1)
endif
if l:cur_line ==# '' && (matchend(l:next_line, '"{*') - 1) == 1
return 0
endif
return '='
endfunction
" Custom fold text, adapted from https://vi.stackexchange.com/a/3818/15292
" and https://vi.stackexchange.com/a/6608/15292
function! utils#MyFoldText() abort
let l:line = getline(v:foldstart)
let l:fold_line_num = v:foldend - v:foldstart
let l:fold_text = substitute(l:line, '^"{\+', '', 'g')
let l:fill_char_num = &textwidth - len(l:fold_text) - len(l:fold_line_num) - 10
return printf('+%s%s %s (%s L)', repeat('-', 4), l:fold_text, repeat('-', l:fill_char_num), l:fold_line_num)
endfunction
" Toggle cursor column
function! utils#ToggleCursorCol() abort
if &cursorcolumn
set nocursorcolumn
echo 'cursorcolumn: OFF'
else
set cursorcolumn
echo 'cursorcolumn: ON'
endif
endfunction
function! utils#SwitchLine(src_line_idx, direction) abort
if a:direction ==# 'up'
if a:src_line_idx == 1
return
endif
move-2
elseif a:direction ==# 'down'
if a:src_line_idx == line('$')
return
endif
move+1
endif
endfunction
function! utils#MoveSelection(direction) abort
" only do this if previous mode is visual line mode. Once we press some keys in
" visual line mode, we will leave this mode. So the output of `mode()` will be
" `n` instead of `V`. We can use `visualmode()` instead to check the previous
" mode, see also https://stackoverflow.com/a/61486601/6064933
if visualmode() !=# 'V'
return
endif
let l:start_line = line("'<")
let l:end_line = line("'>")
let l:num_line = l:end_line - l:start_line + 1
if a:direction ==# 'up'
if l:start_line == 1
" we can also directly use `normal gv`, see https://stackoverflow.com/q/9724123/6064933
normal! gv
return
endif
silent execute printf('%s,%smove-2', l:start_line, l:end_line)
normal! gv
elseif a:direction ==# 'down'
if l:end_line == line('$')
normal! gv
return
endif
silent execute printf('%s,%smove+%s', l:start_line, l:end_line, l:num_line)
normal! gv
endif
endfunction
function! utils#Get_titlestr() abort
let l:title_str = ''
if g:is_linux
let l:title_str = hostname() . ' '
endif
let l:buf_path = expand('%:p:~')
let l:title_str = l:title_str . l:buf_path . ' '
if &buflisted && l:buf_path != ""
let l:title_str = l:title_str . strftime('%Y-%m-%d %H:%M:%S%z', getftime(expand('%')))
endif
return l:title_str
endfunction
" Output current time or unix timestamp in human-readable format.
function! utils#iso_time(timestamp) abort
" Get current datetime
if !a:timestamp
return strftime('%Y-%m-%d %H:%M:%S%z')
endif
" this timestamp in expressed in milliseconds
if len(a:timestamp) == 13
let l:timestamp = a:timestamp[:-4]
" this timestamp in expressed in microseconds
elseif len(a:timestamp) == 16
let l:timestamp = a:timestamp[:-7]
else
let l:timestamp = a:timestamp
endif
return strftime('%Y-%m-%d %H:%M:%S%z', l:timestamp)
endfunction
" Check if we are inside a Git repo.
function! utils#Inside_git_repo() abort
let res = system('git rev-parse --is-inside-work-tree')
if match(res, 'true') == -1
return v:false
else
" Manually trigger a special user autocmd InGitRepo (used lazyloading.
doautocmd User InGitRepo
return v:true
endif
endfunction
function! utils#GetGitBranch()
let l:res = systemlist('git rev-parse --abbrev-ref HEAD')[0]
if match(l:res, 'fatal') != -1
return ''
else
return l:res
endif
endfunction
" Redirect command output to a register for later processing.
" Ref: https://stackoverflow.com/q/2573021/6064933 and https://unix.stackexchange.com/q/8101/221410 .
function! utils#CaptureCommandOutput(command) abort
let l:tmp = @m
redir @m
silent! execute a:command
redir END
"create a scratch buffer for dumping the text, ref: https://vi.stackexchange.com/a/11311/15292.
tabnew | setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile
let l:lines = split(@m, '\n')
call nvim_buf_set_lines(0, 0, 0, 0, l:lines)
let @m = l:tmp
endfunction
" Edit all files matching the given patterns.
function! utils#MultiEdit(patterns) abort
for p in a:patterns
for f in glob(p, 0, 1)
execute 'edit ' . f
endfor
endfor
endfunction