]> git.madduck.net Git - etc/vim.git/blob - autoload/ale/cursor.vim

madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

All patches and comments are welcome. Please squash your changes to logical commits before using git-format-patch and git-send-email to patches@git.madduck.net. If you'd read over the Git project's submission guidelines and adhered to them, I'd be especially grateful.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

Squashed '.vim/bundle/ale/' content from commit 22185c4c
[etc/vim.git] / autoload / ale / cursor.vim
1 scriptencoding utf-8
2 " Author: w0rp <devw0rp@gmail.com>
3 " Author: João Paulo S. de Souza <joao.paulo.silvasouza@hotmail.com>
4 " Description: Echoes lint message for the current line, if any
5
6 " Controls the milliseconds delay before echoing a message.
7 let g:ale_echo_delay = get(g:, 'ale_echo_delay', 10)
8 " A string format for the echoed message.
9 let g:ale_echo_msg_format = get(g:, 'ale_echo_msg_format', '%code: %%s')
10
11 let s:cursor_timer = -1
12
13 " A wrapper for echon so we can test messages we echo in Vader tests.
14 function! ale#cursor#Echom(message) abort
15     if mode() is# 'n'
16         " no-custom-checks
17         exec "norm! :echom a:message\n"
18     endif
19 endfunction
20
21 function! ale#cursor#TruncatedEcho(original_message) abort
22     let l:message = a:original_message
23     " Change tabs to spaces.
24     let l:message = substitute(l:message, "\t", ' ', 'g')
25     " Remove any newlines in the message.
26     let l:message = substitute(l:message, "\n", '', 'g')
27     " Convert indentation groups into single spaces for better legibility when
28     " put on a single line
29     let l:message = substitute(l:message, ' \+', ' ', 'g')
30
31     " We need to remember the setting for shortmess and reset it again.
32     let l:shortmess_options = &l:shortmess
33
34     try
35         let l:cursor_position = getpos('.')
36
37         " The message is truncated and saved to the history.
38         silent! setlocal shortmess+=T
39
40         try
41             call ale#cursor#Echom(l:message)
42         catch /^Vim\%((\a\+)\)\=:E523/
43             " Fallback into manual truncate (#1987)
44             let l:winwidth = winwidth(0)
45
46             if l:winwidth < strdisplaywidth(l:message)
47                 " Truncate message longer than window width with trailing '...'
48                 let l:message = l:message[:l:winwidth - 4] . '...'
49             endif
50
51             exec 'echomsg l:message'
52         catch /E481/
53             " Do nothing if running from a visual selection.
54         endtry
55
56         " Reset the cursor position if we moved off the end of the line.
57         " Using :norm and :echomsg can move the cursor off the end of the
58         " line.
59         if l:cursor_position != getpos('.')
60             call setpos('.', l:cursor_position)
61         endif
62     finally
63         let &l:shortmess = l:shortmess_options
64     endtry
65 endfunction
66
67 function! s:StopCursorTimer() abort
68     if s:cursor_timer != -1
69         call timer_stop(s:cursor_timer)
70         let s:cursor_timer = -1
71     endif
72 endfunction
73
74 function! ale#cursor#EchoCursorWarning(...) abort
75     let l:buffer = bufnr('')
76
77     if !g:ale_echo_cursor && !g:ale_cursor_detail
78         return
79     endif
80
81     " Only echo the warnings in normal mode, otherwise we will get problems.
82     if mode(1) isnot# 'n'
83         return
84     endif
85
86     if ale#ShouldDoNothing(l:buffer)
87         return
88     endif
89
90     let [l:info, l:loc] = ale#util#FindItemAtCursor(l:buffer)
91
92     if g:ale_echo_cursor
93         if !empty(l:loc)
94             let l:format = ale#Var(l:buffer, 'echo_msg_format')
95             let l:msg = ale#GetLocItemMessage(l:loc, l:format)
96             call ale#cursor#TruncatedEcho(l:msg)
97             let l:info.echoed = 1
98         elseif get(l:info, 'echoed')
99             " We'll only clear the echoed message when moving off errors once,
100             " so we don't continually clear the echo line.
101             "
102             " no-custom-checks
103             echo
104             let l:info.echoed = 0
105         endif
106     endif
107
108     if g:ale_cursor_detail
109         if !empty(l:loc)
110             call s:ShowCursorDetailForItem(l:loc, {'stay_here': 1})
111         else
112             call ale#preview#CloseIfTypeMatches('ale-preview')
113         endif
114     endif
115 endfunction
116
117 function! ale#cursor#EchoCursorWarningWithDelay() abort
118     let l:buffer = bufnr('')
119
120     if !g:ale_echo_cursor && !g:ale_cursor_detail
121         return
122     endif
123
124     " Only echo the warnings in normal mode, otherwise we will get problems.
125     if mode(1) isnot# 'n'
126         return
127     endif
128
129     call s:StopCursorTimer()
130
131     let l:pos = getpos('.')[0:2]
132
133     if !exists('w:last_pos')
134         let w:last_pos = [0, 0, 0]
135     endif
136
137     " Check the current buffer, line, and column number against the last
138     " recorded position. If the position has actually changed, *then*
139     " we should echo something. Otherwise we can end up doing processing
140     " the echo message far too frequently.
141     if l:pos != w:last_pos
142         let l:delay = ale#Var(l:buffer, 'echo_delay')
143
144         let w:last_pos = l:pos
145         let s:cursor_timer = timer_start(
146         \   l:delay,
147         \   function('ale#cursor#EchoCursorWarning')
148         \)
149     endif
150 endfunction
151
152 function! s:ShowCursorDetailForItem(loc, options) abort
153     let l:stay_here = get(a:options, 'stay_here', 0)
154
155     let s:last_detailed_line = line('.')
156     let l:message = get(a:loc, 'detail', a:loc.text)
157     let l:lines = split(l:message, "\n")
158
159     if g:ale_floating_preview || g:ale_detail_to_floating_preview
160         call ale#floating_preview#Show(l:lines)
161     else
162         call ale#preview#Show(l:lines, {'stay_here': l:stay_here})
163
164         " Clear the echo message if we manually displayed details.
165         if !l:stay_here
166             " no-custom-checks
167             echo
168         endif
169     endif
170 endfunction
171
172 function! ale#cursor#ShowCursorDetail() abort
173     let l:buffer = bufnr('')
174
175     " Only echo the warnings in normal mode, otherwise we will get problems.
176     if mode() isnot# 'n'
177         return
178     endif
179
180     if ale#ShouldDoNothing(l:buffer)
181         return
182     endif
183
184     call s:StopCursorTimer()
185
186     let [l:info, l:loc] = ale#util#FindItemAtCursor(l:buffer)
187
188     if !empty(l:loc)
189         call s:ShowCursorDetailForItem(l:loc, {'stay_here': 0})
190     endif
191 endfunction