From 212dcd0bf753f08c0127a26a71b673c734b45c02 Mon Sep 17 00:00:00 2001 From: Yaroslav Date: Thu, 5 Sep 2019 19:35:38 +0300 Subject: init commit, extracted vim config from i3rice --- .vim/autoload/neomake/signs.vim | 289 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 289 insertions(+) create mode 100644 .vim/autoload/neomake/signs.vim (limited to '.vim/autoload/neomake/signs.vim') diff --git a/.vim/autoload/neomake/signs.vim b/.vim/autoload/neomake/signs.vim new file mode 100644 index 0000000..fb96934 --- /dev/null +++ b/.vim/autoload/neomake/signs.vim @@ -0,0 +1,289 @@ +" vim: ts=4 sw=4 et +scriptencoding utf-8 + +if !has('signs') + call neomake#log#error('Trying to load signs.vim, without +signs.') + finish +endif + +let s:base_sign_id = 5000 +let s:placed_signs = {'project': {}, 'file': {}} +let s:last_placed_signs = {'project': {}, 'file': {}} + +exe 'sign define neomake_invisible' + +" Reset signs placed by a :Neomake! call +function! neomake#signs#ResetProject() abort + for buf in keys(s:placed_signs.project) + call neomake#signs#Reset(buf, 'project') + call neomake#signs#CleanOldSigns(buf, 'project') + endfor +endfunction + +" Reset signs placed by a :Neomake call in a buffer +function! neomake#signs#ResetFile(bufnr) abort + call neomake#signs#Reset(a:bufnr, 'file') + call neomake#signs#CleanOldSigns(a:bufnr, 'file') +endfunction + +function! neomake#signs#Reset(bufnr, type) abort + if has_key(s:placed_signs[a:type], a:bufnr) + " Clean any lingering, already retired signs. + call neomake#signs#CleanOldSigns(a:bufnr, a:type) + let s:last_placed_signs[a:type][a:bufnr] = s:placed_signs[a:type][a:bufnr] + unlet s:placed_signs[a:type][a:bufnr] + endif +endfunction + +let s:sign_order = {'neomake_file_err': 0, 'neomake_file_warn': 1, + \ 'neomake_file_info': 2, 'neomake_file_msg': 3, + \ 'neomake_project_err': 4, 'neomake_project_warn': 5, + \ 'neomake_project_info': 6, 'neomake_project_msg': 7} + +" Get the defined signs for a:bufnr. +" It returns a dictionary with line numbers as keys. +" If there are multiple entries for a line only the first (visible) entry is +" returned. +function! neomake#signs#by_lnum(bufnr) abort + let bufnr = a:bufnr + 0 + if !bufexists(bufnr) + return {} + endif + + let r = {} + if exists('*sign_getplaced') " patch-8.1.0614 + for sign in sign_getplaced(bufnr)[0].signs + if has_key(r, sign.lnum) + continue + endif + let r[sign.lnum] = [sign.id, sign.name] + endfor + return r + endif + + let signs_output = split(neomake#utils#redir('sign place buffer='.a:bufnr), '\n') + + " Originally via ALE. + " Matches output like : + " line=4 id=1 name=neomake_err + " строка=1 id=1000001 имя=neomake_err + " 行=1 識別子=1000001 名前=neomake_err + " línea=12 id=1000001 nombre=neomake_err + " riga=1 id=1000001, nome=neomake_err + for line in reverse(signs_output[2:]) + " XXX: does not really match "name=" + " (broken by patch-8.1.0614, but handled above) + let sign_type = line[strridx(line, '=')+1:] + if sign_type[0:7] ==# 'neomake_' + let lnum_idx = stridx(line, '=') + let lnum = line[lnum_idx+1:] + 0 + if lnum + let sign_id = line[stridx(line, '=', lnum_idx+1)+1:] + 0 + let r[lnum] = [sign_id, sign_type] + endif + endif + endfor + return r +endfunction + +let s:entry_to_sign_type = {'W': 'warn', 'I': 'info', 'M': 'msg'} + +" Place signs for list a:entries in a:bufnr for a:type ('file' or 'project'). +" List items in a:entries need to have a "type" and "lnum" (non-zero) property. +function! neomake#signs#PlaceSigns(bufnr, entries, type) abort + " Query the list of currently placed signs. + " This allows to cope with movements, e.g. when lines were added. + let placed_signs = neomake#signs#by_lnum(a:bufnr) + + let entries_by_linenr = {} + for entry in a:entries + let lnum = entry.lnum + let sign_type = printf('neomake_%s_%s', + \ a:type, + \ get(s:entry_to_sign_type, toupper(entry.type), 'err')) + if !exists('entries_by_linenr[lnum]') + \ || s:sign_order[entries_by_linenr[lnum]] + \ > s:sign_order[sign_type] + let entries_by_linenr[lnum] = sign_type + endif + endfor + + let place_new = [] + let log_context = {'bufnr': a:bufnr} + let count_reused = 0 + for [lnum, sign_type] in items(entries_by_linenr) + let existing_sign = get(placed_signs, lnum, []) + if empty(existing_sign) || existing_sign[1] !~# '^neomake_'.a:type.'_' + call add(place_new, [lnum, sign_type]) + continue + endif + + let sign_id = existing_sign[0] + if existing_sign[1] == sign_type + let count_reused += 1 + " call neomake#log#debug(printf( + " \ 'Reusing sign: id=%d, type=%s, lnum=%d.', + " \ sign_id, existing_sign[1], lnum), log_context) + else + let cmd = printf('sign place %s name=%s buffer=%d', + \ sign_id, sign_type, a:bufnr) + call neomake#log#debug('Upgrading sign for lnum='.lnum.': '.cmd.'.', log_context) + exe cmd + endif + + " Keep this sign from being cleaned. + if exists('s:last_placed_signs[a:type][a:bufnr][sign_id]') + unlet s:last_placed_signs[a:type][a:bufnr][sign_id] + endif + endfor + if count_reused + call neomake#log#debug(printf('Reused %d signs.', count_reused), log_context) + endif + + for [lnum, sign_type] in place_new + if !exists('next_sign_id') + if !empty(placed_signs) + let next_sign_id = max(map(values(copy(placed_signs)), 'v:val[0]')) + 1 + else + let next_sign_id = s:base_sign_id + endif + else + let next_sign_id += 1 + endif + let cmd = 'sign place '.next_sign_id.' line='.lnum. + \ ' name='.sign_type. + \ ' buffer='.a:bufnr + call neomake#log#debug('Placing sign: '.cmd.'.', log_context) + let placed_signs[lnum] = [next_sign_id, sign_type] + exe cmd + endfor + + let s:placed_signs[a:type][a:bufnr] = {} + for [lnum, sign_info] in items(placed_signs) + let s:placed_signs[a:type][a:bufnr][sign_info[0]] = sign_info[1] + endfor +endfunction + +function! neomake#signs#CleanAllOldSigns(type) abort + call neomake#log#debug_obj('Removing signs', s:last_placed_signs) + for buf in keys(s:last_placed_signs[a:type]) + call neomake#signs#CleanOldSigns(buf, a:type) + endfor +endfunction + +" type may be either 'file' or 'project' +function! neomake#signs#CleanOldSigns(bufnr, type) abort + if !has_key(s:last_placed_signs[a:type], a:bufnr) + return + endif + let placed_signs = s:last_placed_signs[a:type][a:bufnr] + unlet s:last_placed_signs[a:type][a:bufnr] + if bufexists(+a:bufnr) + call neomake#log#debug(printf('Cleaning %d old signs.', len(placed_signs)), {'bufnr': a:bufnr}) + for sign_id in keys(placed_signs) + exe 'sign unplace '.sign_id.' buffer='.a:bufnr + if has_key(s:placed_signs[a:type], a:bufnr) + if has_key(s:placed_signs[a:type][a:bufnr], sign_id) + unlet s:placed_signs[a:type][a:bufnr][sign_id] + endif + endif + endfor + else + call neomake#log#debug_obj('Skipped cleaning of old signs in non-existing buffer '.a:bufnr, placed_signs) + endif +endfunction + +function! neomake#signs#RedefineSign(name, opts) abort + let sign_define = 'sign define '.a:name + for attr in keys(a:opts) + let sign_define .= ' '.attr.'='.a:opts[attr] + endfor + call neomake#log#debug(printf('Defining sign: %s.', sign_define)) + exe sign_define +endfunction + +function! neomake#signs#RedefineErrorSign(...) abort + let default_opts = {'text': '✖', 'texthl': 'NeomakeErrorSign'} + let opts = {} + if a:0 + call extend(opts, a:1) + elseif exists('g:neomake_error_sign') + call extend(opts, g:neomake_error_sign) + endif + call extend(opts, default_opts, 'keep') + call neomake#signs#RedefineSign('neomake_file_err', opts) + call neomake#signs#RedefineSign('neomake_project_err', opts) +endfunction + +function! neomake#signs#RedefineWarningSign(...) abort + let default_opts = {'text': '‼', 'texthl': 'NeomakeWarningSign'} + let opts = {} + if a:0 + call extend(opts, a:1) + elseif exists('g:neomake_warning_sign') + call extend(opts, g:neomake_warning_sign) + endif + call extend(opts, default_opts, 'keep') + call neomake#signs#RedefineSign('neomake_file_warn', opts) + call neomake#signs#RedefineSign('neomake_project_warn', opts) +endfunction + +function! neomake#signs#RedefineMessageSign(...) abort + let default_opts = {'text': '➤', 'texthl': 'NeomakeMessageSign'} + let opts = {} + if a:0 + call extend(opts, a:1) + elseif exists('g:neomake_message_sign') + call extend(opts, g:neomake_message_sign) + endif + call extend(opts, default_opts, 'keep') + call neomake#signs#RedefineSign('neomake_file_msg', opts) + call neomake#signs#RedefineSign('neomake_project_msg', opts) +endfunction + +function! neomake#signs#RedefineInfoSign(...) abort + let default_opts = {'text': 'ℹ', 'texthl': 'NeomakeInfoSign'} + let opts = {} + if a:0 + call extend(opts, a:1) + elseif exists('g:neomake_info_sign') + call extend(opts, g:neomake_info_sign) + endif + call extend(opts, default_opts, 'keep') + call neomake#signs#RedefineSign('neomake_file_info', opts) + call neomake#signs#RedefineSign('neomake_project_info', opts) +endfunction + +function! neomake#signs#DefineHighlights() abort + " Use background from SignColumn. + let ctermbg = neomake#utils#GetHighlight('SignColumn', 'bg', 'Normal') + let guibg = neomake#utils#GetHighlight('SignColumn', 'bg#', 'Normal') + + " Define NeomakeErrorSign, NeomakeWarningSign etc. + call neomake#utils#define_derived_highlights('Neomake%sSign', [ctermbg, guibg]) +endfunction + +function! neomake#signs#DefineSigns() abort + call neomake#signs#RedefineErrorSign() + call neomake#signs#RedefineWarningSign() + call neomake#signs#RedefineInfoSign() + call neomake#signs#RedefineMessageSign() +endfunction + +function! s:wipe_signs(bufnr) abort + for type in ['file', 'project'] + if has_key(s:placed_signs[type], a:bufnr) + unlet s:placed_signs[type][a:bufnr] + endif + if has_key(s:last_placed_signs[type], a:bufnr) + unlet s:last_placed_signs[type][a:bufnr] + endif + endfor +endfunction +augroup neomake_signs + au! + autocmd BufWipeout * call s:wipe_signs(expand('')) +augroup END + +call neomake#signs#DefineSigns() +call neomake#signs#DefineHighlights() -- cgit v1.2.3