mirror of
https://github.com/amix/vimrc
synced 2025-06-16 01:25:00 +08:00
Updated plugins, also experimenting with a new font
The font is IBM Plex Mono: https://ibm.github.io/type/
This commit is contained in:
@ -1,207 +1,113 @@
|
||||
let s:jobs = {}
|
||||
|
||||
" Nvim has always supported async commands.
|
||||
"
|
||||
" Vim introduced async in 7.4.1826.
|
||||
"
|
||||
" gVim didn't support aync until 7.4.1850 (though I haven't been able to
|
||||
" verify this myself).
|
||||
"
|
||||
" MacVim-GUI didn't support async until 7.4.1832 (actually commit
|
||||
" 88f4fe0 but 7.4.1832 was the first subsequent patch release).
|
||||
let s:available = has('nvim') || (
|
||||
\ has('job') && (
|
||||
\ (has('patch-7-4-1826') && !has('gui_running')) ||
|
||||
\ (has('patch-7-4-1850') && has('gui_running')) ||
|
||||
\ (has('patch-7-4-1832') && has('gui_macvim'))
|
||||
\ )
|
||||
\ has('job') && (
|
||||
\ (has('patch-7-4-1826') && !has('gui_running')) ||
|
||||
\ (has('patch-7-4-1850') && has('gui_running')) ||
|
||||
\ (has('patch-7-4-1832') && has('gui_macvim'))
|
||||
\ )
|
||||
\ )
|
||||
|
||||
function! gitgutter#async#available()
|
||||
return s:available
|
||||
endfunction
|
||||
|
||||
|
||||
function! gitgutter#async#execute(cmd) abort
|
||||
let bufnr = gitgutter#utility#bufnr()
|
||||
let options = {
|
||||
\ 'stdoutbuffer': [],
|
||||
\ 'buffer': gitgutter#utility#bufnr()
|
||||
\ }
|
||||
let command = s:build_command(a:cmd)
|
||||
|
||||
if has('nvim')
|
||||
if has('unix')
|
||||
let command = ["sh", "-c", a:cmd]
|
||||
elseif has('win32')
|
||||
let command = ["cmd.exe", "/c", a:cmd]
|
||||
else
|
||||
throw 'unknown os'
|
||||
endif
|
||||
" Make the job use a shell while avoiding (un)quoting problems.
|
||||
let job_id = jobstart(command, {
|
||||
\ 'buffer': bufnr,
|
||||
\ 'on_stdout': function('gitgutter#async#handle_diff_job_nvim'),
|
||||
\ 'on_stderr': function('gitgutter#async#handle_diff_job_nvim'),
|
||||
\ 'on_exit': function('gitgutter#async#handle_diff_job_nvim')
|
||||
\ })
|
||||
call gitgutter#debug#log('[nvim job: '.job_id.', buffer: '.bufnr.'] '.a:cmd)
|
||||
if job_id < 1
|
||||
throw 'diff failed'
|
||||
endif
|
||||
|
||||
" Note that when `cmd` doesn't produce any output, i.e. the diff is empty,
|
||||
" the `stdout` event is not fired on the job handler. Therefore we keep
|
||||
" track of the jobs ourselves so we can spot empty diffs.
|
||||
call s:job_started(job_id)
|
||||
|
||||
call jobstart(command, extend(options, {
|
||||
\ 'on_stdout': function('s:on_stdout_nvim'),
|
||||
\ 'on_stderr': function('s:on_stderr_nvim'),
|
||||
\ 'on_exit': function('s:on_exit_nvim')
|
||||
\ }))
|
||||
else
|
||||
" Make the job use a shell.
|
||||
"
|
||||
" Pass a handler for stdout but not for stderr so that errors are
|
||||
" ignored (and thus signs are not updated; this assumes that an error
|
||||
" only occurs when a file is not tracked by git).
|
||||
|
||||
if has('unix')
|
||||
let command = ["sh", "-c", a:cmd]
|
||||
elseif has('win32')
|
||||
let command = "cmd.exe /c ".a:cmd
|
||||
else
|
||||
throw 'unknown os'
|
||||
endif
|
||||
|
||||
let job = job_start(command, {
|
||||
\ 'out_cb': 'gitgutter#async#handle_diff_job_vim',
|
||||
\ 'close_cb': 'gitgutter#async#handle_diff_job_vim_close'
|
||||
call job_start(command, {
|
||||
\ 'out_cb': function('s:on_stdout_vim', options),
|
||||
\ 'err_cb': function('s:on_stderr_vim', options),
|
||||
\ 'close_cb': function('s:on_exit_vim', options)
|
||||
\ })
|
||||
call gitgutter#debug#log('[vim job: '.string(job_info(job)).', buffer: '.bufnr.'] '.a:cmd)
|
||||
|
||||
call s:job_started(s:channel_id(job_getchannel(job)), bufnr)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! gitgutter#async#handle_diff_job_nvim(job_id, data, event) dict abort
|
||||
call gitgutter#debug#log('job_id: '.a:job_id.', event: '.a:event.', buffer: '.self.buffer)
|
||||
function! s:build_command(cmd)
|
||||
if has('unix')
|
||||
return ['sh', '-c', a:cmd]
|
||||
endif
|
||||
|
||||
let job_bufnr = self.buffer
|
||||
if bufexists(job_bufnr)
|
||||
let current_buffer = gitgutter#utility#bufnr()
|
||||
call gitgutter#utility#set_buffer(job_bufnr)
|
||||
if has('win32')
|
||||
return has('nvim') ? ['cmd.exe', '/c', a:cmd] : 'cmd.exe /c '.a:cmd
|
||||
endif
|
||||
|
||||
if a:event == 'stdout'
|
||||
" a:data is a list
|
||||
call s:job_finished(a:job_id)
|
||||
if gitgutter#utility#is_active()
|
||||
call gitgutter#handle_diff(gitgutter#utility#stringify(a:data))
|
||||
endif
|
||||
throw 'unknown os'
|
||||
endfunction
|
||||
|
||||
elseif a:event == 'exit'
|
||||
" If the exit event is triggered without a preceding stdout event,
|
||||
" the diff was empty.
|
||||
if s:is_job_started(a:job_id)
|
||||
if gitgutter#utility#is_active()
|
||||
call gitgutter#handle_diff("")
|
||||
endif
|
||||
call s:job_finished(a:job_id)
|
||||
endif
|
||||
|
||||
else " a:event is stderr
|
||||
call gitgutter#hunk#reset()
|
||||
call s:job_finished(a:job_id)
|
||||
|
||||
endif
|
||||
|
||||
call gitgutter#utility#set_buffer(current_buffer)
|
||||
function! s:on_stdout_nvim(_job_id, data, _event) dict abort
|
||||
if empty(self.stdoutbuffer)
|
||||
let self.stdoutbuffer = a:data
|
||||
else
|
||||
call s:job_finished(a:job_id)
|
||||
let self.stdoutbuffer = self.stdoutbuffer[:-2] +
|
||||
\ [self.stdoutbuffer[-1] . a:data[0]] +
|
||||
\ a:data[1:]
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
" Channel is in NL mode.
|
||||
function! gitgutter#async#handle_diff_job_vim(channel, line) abort
|
||||
call gitgutter#debug#log('channel: '.a:channel.', line: '.a:line)
|
||||
|
||||
call s:accumulate_job_output(s:channel_id(a:channel), a:line)
|
||||
endfunction
|
||||
|
||||
function! gitgutter#async#handle_diff_job_vim_close(channel) abort
|
||||
call gitgutter#debug#log('channel: '.a:channel)
|
||||
|
||||
let channel_id = s:channel_id(a:channel)
|
||||
let job_bufnr = s:job_buffer(channel_id)
|
||||
|
||||
if bufexists(job_bufnr)
|
||||
function! s:on_stderr_nvim(_job_id, _data, _event) dict abort
|
||||
" Backward compatibility for nvim < 0.2.0
|
||||
if !has('nvim-0.2.0')
|
||||
let current_buffer = gitgutter#utility#bufnr()
|
||||
call gitgutter#utility#set_buffer(job_bufnr)
|
||||
|
||||
call gitgutter#utility#set_buffer(self.buffer)
|
||||
if gitgutter#utility#is_active()
|
||||
call gitgutter#handle_diff(s:job_output(channel_id))
|
||||
call gitgutter#hunk#reset()
|
||||
endif
|
||||
|
||||
call gitgutter#utility#set_buffer(current_buffer)
|
||||
return
|
||||
endif
|
||||
call s:job_finished(channel_id)
|
||||
|
||||
call s:buffer_exec(self.buffer, function('gitgutter#hunk#reset'))
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:channel_id(channel) abort
|
||||
return ch_info(a:channel)['id']
|
||||
endfunction
|
||||
|
||||
|
||||
"
|
||||
" Keep track of jobs.
|
||||
"
|
||||
" nvim: receives all the job's output at once so we don't need to accumulate
|
||||
" it ourselves. We can pass the buffer number into the job so we don't need
|
||||
" to track that either.
|
||||
"
|
||||
" s:jobs {} -> key: job's id, value: anything truthy
|
||||
"
|
||||
" vim: receives the job's output line by line so we need to accumulate it.
|
||||
" We also need to keep track of the buffer the job is running for.
|
||||
" Vim job's don't have an id. Instead we could use the external process's id
|
||||
" or the channel's id (there seems to be 1 channel per job). Arbitrarily
|
||||
" choose the channel's id.
|
||||
"
|
||||
" s:jobs {} -> key: channel's id, value: {} key: output, value: [] job's output
|
||||
" key: buffer: value: buffer number
|
||||
|
||||
|
||||
" nvim:
|
||||
" id: job's id
|
||||
"
|
||||
" vim:
|
||||
" id: channel's id
|
||||
" arg: buffer number
|
||||
function! s:job_started(id, ...) abort
|
||||
if a:0 " vim
|
||||
let s:jobs[a:id] = {'output': [], 'buffer': a:1}
|
||||
else " nvim
|
||||
let s:jobs[a:id] = 1
|
||||
function! s:on_exit_nvim(_job_id, _data, _event) dict abort
|
||||
" Backward compatibility for nvim < 0.2.0
|
||||
if !has('nvim-0.2.0')
|
||||
let current_buffer = gitgutter#utility#bufnr()
|
||||
call gitgutter#utility#set_buffer(self.buffer)
|
||||
if gitgutter#utility#is_active()
|
||||
call gitgutter#handle_diff(gitgutter#utility#stringify(self.stdoutbuffer))
|
||||
endif
|
||||
call gitgutter#utility#set_buffer(current_buffer)
|
||||
return
|
||||
endif
|
||||
|
||||
call s:buffer_exec(self.buffer, function('gitgutter#handle_diff', [gitgutter#utility#stringify(self.stdoutbuffer)]))
|
||||
endfunction
|
||||
|
||||
function! s:is_job_started(id) abort
|
||||
return has_key(s:jobs, a:id)
|
||||
|
||||
function! s:on_stdout_vim(_channel, data) dict abort
|
||||
call add(self.stdoutbuffer, a:data)
|
||||
endfunction
|
||||
|
||||
function! s:accumulate_job_output(id, line) abort
|
||||
call add(s:jobs[a:id].output, a:line)
|
||||
function! s:on_stderr_vim(_channel, _data) dict abort
|
||||
call s:buffer_exec(self.buffer, function('gitgutter#hunk#reset'))
|
||||
endfunction
|
||||
|
||||
" Returns a string
|
||||
function! s:job_output(id) abort
|
||||
if has_key(s:jobs, a:id)
|
||||
return gitgutter#utility#stringify(s:jobs[a:id].output)
|
||||
else
|
||||
return ""
|
||||
function! s:on_exit_vim(_channel) dict abort
|
||||
call s:buffer_exec(self.buffer, function('gitgutter#handle_diff', [gitgutter#utility#stringify(self.stdoutbuffer)]))
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:buffer_exec(buffer, fn)
|
||||
let current_buffer = gitgutter#utility#bufnr()
|
||||
call gitgutter#utility#set_buffer(a:buffer)
|
||||
|
||||
if gitgutter#utility#is_active()
|
||||
call a:fn()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:job_buffer(id) abort
|
||||
return s:jobs[a:id].buffer
|
||||
call gitgutter#utility#set_buffer(current_buffer)
|
||||
endfunction
|
||||
|
||||
function! s:job_finished(id) abort
|
||||
if has_key(s:jobs, a:id)
|
||||
unlet s:jobs[a:id]
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
@ -19,7 +19,7 @@ function! gitgutter#highlight#define_highlights() abort
|
||||
execute "highlight GitGutterAddInvisible guifg=bg guibg=" . guibg . " ctermfg=" . ctermbg . " ctermbg=" . ctermbg
|
||||
execute "highlight GitGutterChangeInvisible guifg=bg guibg=" . guibg . " ctermfg=" . ctermbg . " ctermbg=" . ctermbg
|
||||
execute "highlight GitGutterDeleteInvisible guifg=bg guibg=" . guibg . " ctermfg=" . ctermbg . " ctermbg=" . ctermbg
|
||||
highlight default link GitGutterChangeDeleteInvisible GitGutterChangeInvisble
|
||||
highlight default link GitGutterChangeDeleteInvisible GitGutterChangeInvisible
|
||||
|
||||
highlight default link GitGutterAdd GitGutterAddDefault
|
||||
highlight default link GitGutterChange GitGutterChangeDefault
|
||||
|
@ -51,7 +51,7 @@ function! gitgutter#hunk#next_hunk(count) abort
|
||||
if hunk[2] > current_line
|
||||
let hunk_count += 1
|
||||
if hunk_count == a:count
|
||||
execute 'normal!' hunk[2] . 'G'
|
||||
execute 'normal!' hunk[2] . 'Gzv'
|
||||
return
|
||||
endif
|
||||
endif
|
||||
@ -69,7 +69,7 @@ function! gitgutter#hunk#prev_hunk(count) abort
|
||||
let hunk_count += 1
|
||||
if hunk_count == a:count
|
||||
let target = hunk[2] == 0 ? 1 : hunk[2]
|
||||
execute 'normal!' target . 'G'
|
||||
execute 'normal!' target . 'Gzv'
|
||||
return
|
||||
endif
|
||||
endif
|
||||
|
Reference in New Issue
Block a user