Rainbow
[my-vim-dotfolder.git] / plugin / errormarker.vim
bloba463483a2052518a6d587deee4822e266bd69734
1 " ============================================================================
2 "    Copyright: Copyright (C) 2007,2010 Michael Hofmann
3 "               Permission is hereby granted to use and distribute this code,
4 "               with or without modifications, provided that this copyright
5 "               notice is copied with it. Like anything else that's free,
6 "               errormarker.vim is provided *as is* and comes with no
7 "               warranty of any kind, either expressed or implied. In no
8 "               event will the copyright holder be liable for any damages
9 "               resulting from the use of this software.
10 " Name Of File: errormarker.vim
11 "  Description: Sets markers for compile errors
12 "   Maintainer: Michael Hofmann (mh21 at piware dot de)
13 "      Version: See g:loaded_errormarker for version number.
14 "        Usage: Normally, this file should reside in the plugins
15 "               directory and be automatically sourced. If not, you must
16 "               manually source this file using ':source errormarker.vim'.
18 " === Support for automatic retrieval (Vim script 642) ==================={{{1
20 " GetLatestVimScripts: 1861 1 :AutoInstall: errormarker.vim
22 " === Initialization ====================================================={{{1
24 " Exit when the Vim version is too old or missing some features
25 if v:version < 700 || !has("signs") || !has("autocmd")
26     finish
27 endif
29 " Exit quickly when the script has already been loaded or when 'compatible'
30 " is set.
31 if exists("g:loaded_errormarker") || &compatible
32     finish
33 endif
35 " Version number.
36 let g:loaded_errormarker = "0.1.13"
38 let s:save_cpo = &cpo
39 set cpo&vim
41 command! ErrorAtCursor call ShowErrorAtCursor()
42 if !hasmapto(":ErrorAtCursor<cr>", "n") &&
43             \ (!exists('g:errormarker_disablemappings') || !g:errormarker_disablemappings)
44     nmap <silent> <unique> <Leader>cc :ErrorAtCursor<CR>
45 endif
47 function! s:DefineVariable(name, default)
48     if !exists(a:name)
49         execute 'let ' . a:name . ' = "' . escape(a:default, '\"') . '"'
50     endif
51 endfunction
53 " === Variables =========================================================={{{1
55 " Defines the icon to show for errors in the gui
56 call s:DefineVariable("g:errormarker_erroricon",
57             \ has('win32') ? expand("~/vimfiles/icons/error.bmp") :
58                 \ "/usr/share/icons/gnome/16x16/status/dialog-error.png")
60 " Defines the icon to show for warnings in the gui
61 call s:DefineVariable("g:errormarker_warningicon",
62             \ has('win32') ? expand("~/vimfiles/icons/warning.bmp") :
63                 \ "/usr/share/icons/gnome/16x16/status/dialog-warning.png")
65 " Defines the text (two characters) to show for errors in the gui
66 call s:DefineVariable("g:errormarker_errortext", "EE")
68 " Defines the text (two characters) to show for warnings in the gui
69 call s:DefineVariable("g:errormarker_warningtext", "WW")
71 " Defines the highlighting group to use for errors in the gui
72 call s:DefineVariable("g:errormarker_errorgroup", "Todo")
74 " Defines the highlighting group to use for warnings in the gui
75 call s:DefineVariable("g:errormarker_warninggroup", "Todo")
77 " Defines the error types that should be treated as warning
78 call s:DefineVariable("g:errormarker_warningtypes", "wW")
80 " === Global ============================================================={{{1
82 " Define the signs
83 let s:erroricon = ""
84 if filereadable(g:errormarker_erroricon)
85     let s:erroricon = " icon=" . escape(g:errormarker_erroricon, '| \')
86 endif
87 let s:warningicon = ""
88 if filereadable(g:errormarker_warningicon)
89     let s:warningicon = " icon=" . escape(g:errormarker_warningicon, '| \')
90 endif
91 execute "sign define errormarker_error texthl=ErrorMsg text=" . g:errormarker_errortext .
92             \ " linehl=" . g:errormarker_errorgroup . s:erroricon
94 execute "sign define errormarker_warning texthl=WarningMsg text=" . g:errormarker_warningtext .
95             \ " linehl=" . g:errormarker_warninggroup . s:warningicon
97 " Setup the autocommands that handle the MRUList and other stuff.
98 augroup errormarker
99     autocmd QuickFixCmdPost make call <SID>SetErrorMarkers()
100 augroup END
102 " === Functions =========================================================={{{1
104 function! ShowErrorAtCursor()
105     let [l:bufnr, l:lnum] = getpos(".")[0:1]
106     let l:bufnr = bufnr("%")
107     for l:d in getqflist()
108         if (l:d.bufnr != l:bufnr || l:d.lnum != l:lnum)
109             continue
110         endif
111         redraw | echomsg "Line " . l:lnum . ": " . l:d.text
112     endfor
113 endfunction
115 function! s:SetErrorMarkers()
116     if has ('balloon_eval')
117         let &balloonexpr = "<SNR>" . s:SID() . "_ErrorMessageBalloons()"
118         set ballooneval
119     endif
121     sign unplace *
123     let l:positions = {}
124     for l:d in getqflist()
125         if (l:d.bufnr == 0 || l:d.lnum == 0)
126             continue
127         endif
129         let l:key = l:d.bufnr . l:d.lnum
130         if has_key(l:positions, l:key)
131             continue
132         endif
133         let l:positions[l:key] = 1
135         if strlen(l:d.type) &&
136                     \ stridx(g:errormarker_warningtypes, l:d.type) >= 0
137             let l:name = "errormarker_warning"
138         else
139             let l:name = "errormarker_error"
140         endif
141         execute ":sign place " . l:key . " line=" . l:d.lnum . " name=" .
142                     \ l:name . " buffer=" . l:d.bufnr
143     endfor
144 endfunction
146 function! s:ErrorMessageBalloons()
147     let l:result = []
148     for l:d in getqflist()
149         if (d.bufnr == v:beval_bufnr && d.lnum == v:beval_lnum)
150             let l:result += [l:d.text]
151         endif
152     endfor
153     return l:result
154 endfunction
156 function! s:SID()
157     return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze_SID$')
158 endfunction
160 " === Help file installation ============================================={{{1
162 " Original version: Copyright (C) Mathieu Clabaut, author of vimspell
163 " http://www.vim.org/scripts/script.php?script_id=465
164 function! s:InstallDocumentation(full_name, revision)
165     " Name of the document path based on the system we use:
166     if has("vms")
167         " No chance that this script will work with
168         " VMS -  to much pathname juggling here.
169         return 1
170     elseif (has("unix"))
171         " On UNIX like system, using forward slash:
172         let l:slash_char = '/'
173         let l:mkdir_cmd  = ':silent !mkdir -p '
174     else
175         " On M$ system, use backslash. Also mkdir syntax is different.
176         " This should only work on W2K and up.
177         let l:slash_char = '\'
178         let l:mkdir_cmd  = ':silent !mkdir '
179     endif
181     let l:doc_path = l:slash_char . 'doc'
182     let l:doc_home = l:slash_char . '.vim' . l:slash_char . 'doc'
184     " Figure out document path based on full name of this script:
185     let l:vim_plugin_path = fnamemodify(a:full_name, ':h')
186     let l:vim_doc_path    = fnamemodify(a:full_name, ':h:h') . l:doc_path
187     if (!(filewritable(l:vim_doc_path) == 2))
188         echo "Creating doc path: " . l:vim_doc_path
189         execute l:mkdir_cmd . '"' . l:vim_doc_path . '"'
190         if (!(filewritable(l:vim_doc_path) == 2))
191             " Try a default configuration in user home:
192             let l:vim_doc_path = expand("~") . l:doc_home
193             if (!(filewritable(l:vim_doc_path) == 2))
194                 execute l:mkdir_cmd . '"' . l:vim_doc_path . '"'
195                 if (!(filewritable(l:vim_doc_path) == 2))
196                     echohl WarningMsg
197                     echo "Unable to create documentation directory.\ntype :help add-local-help for more information."
198                     echohl None
199                     return 0
200                 endif
201             endif
202         endif
203     endif
205     " Exit if we have problem to access the document directory:
206     if (!isdirectory(l:vim_plugin_path) || !isdirectory(l:vim_doc_path) || filewritable(l:vim_doc_path) != 2)
207         return 0
208     endif
210     " Full name of script and documentation file:
211     let l:script_name = fnamemodify(a:full_name, ':t')
212     let l:doc_name    = fnamemodify(a:full_name, ':t:r') . '.txt'
213     let l:plugin_file = l:vim_plugin_path . l:slash_char . l:script_name
214     let l:doc_file    = l:vim_doc_path    . l:slash_char . l:doc_name
216     " Bail out if document file is still up to date:
217     if (filereadable(l:doc_file) && getftime(l:plugin_file) < getftime(l:doc_file))
218         return 0
219     endif
221     " Prepare window position restoring command:
222     if (strlen(@%))
223         let l:go_back = 'b ' . bufnr("%")
224     else
225         let l:go_back = 'enew!'
226     endif
228     " Create a new buffer & read in the plugin file (me):
229     setl nomodeline
230     exe 'enew!'
231     silent exe 'r ' . l:plugin_file
233     setl modeline
234     let l:buf = bufnr("%")
235     setl noswapfile modifiable
237     norm zR
238     norm gg
240     " Delete from first line to a line starts with
241     " === START_DOC
242     silent 1,/^=\{3,}\s\+START_DOC\C/ d
244     " Delete from a line starts with
245     " === END_DOC
246     " to the end of the documents:
247     silent /^=\{3,}\s\+END_DOC\C/,$ d
249     " Add modeline for help doc: the modeline string is mangled intentionally
250     " to avoid it be recognized by Vim:
251     call append(line('$'), '')
252     call append(line('$'), ' v' . 'im:tw=78:ts=8:ft=help:norl:')
254     " Replace revision:
255     silent exe "normal :1s/#version#/ v" . a:revision . "/\<CR>"
257     " Save the help document:
258     silent exe 'w! ' . l:doc_file
259     exe l:go_back
260     exe 'bw ' . l:buf
262     " Build help tags:
263     exe 'helptags ' . l:vim_doc_path
265     return 1
266 endfunction
268 call s:InstallDocumentation(expand('<sfile>:p'), g:loaded_errormarker)
270 " === Cleanup ============================================================{{{1
272 let &cpo = s:save_cpo
274 finish
276 " === Help file =========================================================={{{1
277 === START_DOC
278 *errormarker*   Plugin to highlight error positions #version#
280                         ERROR MARKER REFERENCE MANUAL ~
282 1. Usage                                                   |errormarker-usage|
283 2. Customization                                   |errormarker-customization|
284 3. Credits                                               |errormarker-credits|
285 4. Changelog                                           |errormarker-changelog|
287 This plugin is only available if Vim was compiled with the |+signs| feature
288 and 'compatible' is not set.
290 ==============================================================================
291 1. USAGE                                                   *errormarker-usage*
293 This plugin hooks the quickfix command |QuickFixCmdPost| and generates error
294 markers for every line that contains an error. Vim has to be compiled with
295 |+signs| for this to work.
297 Additionally, a tooltip with the error message is shown when you hover with
298 the mouse over a line with an error (only available when compiled with the
299 |+balloon_eval| feature), or when you press <Leader>cc in normal mode. This
300 functionality is also available with the |:ErrorAtCursor| command.
302 The functionality mentioned here is a plugin, see |add-plugin|. This plugin is
303 only available if 'compatible' is not set and Vim was compiled with |+signs|
304 and |+autocmd| support. You can avoid loading this plugin by setting the
305 "loaded_errormarker" variable in your |vimrc| file: >
306         :let loaded_errormarker = 1
308 ==============================================================================
309 2. CUSTOMIZATION                                   *errormarker-customization*
311 You can customize the signs that are used by Vim to mark warnings and errors
312 (see |:sign-define| for details).
314                              *errormarker_erroricon* *errormarker_warningicon*
315 The icons that are used for the warnings and error signs in the GUI version of
316 Vim can be set by >
317         :let errormarker_erroricon = "/path/to/error/icon/name.png"
318         :let errormarker_warningicon = "/path/to/warning/icon/name.png"
319 If an icon is not found, text-only markers are displayed instead. The bitmap
320 should fit into the place of two characters.
322 You must use full paths for these variables, for icons in your home directory
323 expand the paths in your .vimrc with something like >
324         :let errormarker_erroricon = expand ("~/.vim/icons/error.png")
325 To get working icons on Microsoft Windows, place icons for errors and warnings
326 (you can use Google at http://images.google.com/images?q=error&imgsz=icon to
327 find some nice ones) as error.bmp and warning.bmp in your home directory at
328 C:\Documents and Settings\<user>\vimfiles\icons.
330                              *errormarker_errortext* *errormarker_warningtext*
331 The text that is displayed without a GUI or if the icon files can not be found
332 can be set by >
333         :let errormarker_errortext = "Er"
334         :let errormarker_warningtext = "Wa"
335 The maximum length is two characters.
337                            *errormarker_errorgroup* *errormarker_warninggroup*
338 The hightlighting groups that are used to mark the lines that contain warnings
339 and errors can be set by >
340         :let errormarker_errorgroup = "ErrorMsg"
341         :let errormarker_warninggroup = "Todo"
343                                                     *errormarker_warningtypes*
344 If the compiler reports a severity for the error messages this can be used to
345 distinguish between warnings and errors. Vim uses a single character error
346 type that can be parsed with |errorformat| (%t). The error types that should
347 be treated as warnings can be set by >
348         let errormarker_warningtypes = "wWiI"
350 For example, the severity of error messages from gcc
351         averagergui.cpp|18 warning| unused parameter ‘file’ ~
352         averagergui.cpp|33 error| expected class-name before ‘I’ ~
353 can be parsed by adding the following lines to your .vimrc >
354         let &errorformat="%f:%l: %t%*[^:]:%m," . &errorformat
355         let &errorformat="%f:%l:%c: %t%*[^:]:%m," . &errorformat
356         let errormarker_warningtypes = "wW"
358 If you use a different locale than English, this may also be needed: >
359         set makeprg=LANGUAGE=C\ make
361                               *errormarker_disablemappings* *:ErrorAtCursor*
362 To show the error message at the cursor position (e.g. if you are working from
363 within a terminal, where tooltips are not available), the following command
364 and shortcut are defined: >
365         :ErrorAtCursor
366         :nmap <silent> <unique> <Leader>cc :ErrorAtCursor<CR>
368 The shortcut is only defined if no other mapping to ErrorAtCursor<CR> can be
369 found, and can be completely disabled by >
370         let errormarker_disablemappings = 1
373 ==============================================================================
374 3. CREDITS                                               *errormarker-credits*
376 Author: Michael Hofmann <mh21 at piware dot de>
378 ==============================================================================
379 4. CHANGELOG                                           *errormarker-changelog*
381 0.1.13  - shortcut can be disabled (thanks Michael Jansen)
382 0.1.12  - shortcut (<Leader>cc) to show error at cursor (thanks Eric Rannaud)
383 0.1.11  - changelog fix
384 0.1.10  - removes accidental dependency on NerdEcho
385 0.1.9   - fixes Win32 icon display
386 0.1.8   - check for Vim version
387 0.1.7   - fixes gcc error message parsing example
388 0.1.6   - support for GetLatestVimScripts (vimscript#642)
389 0.1.5   - clarified documentation about paths
390 0.1.4   - fixes icon name and variable escaping
391 0.1.3   - customizable signs
392         - distinguishes between warnings and errors
393 0.1.2   - documentation
394 0.1.1   - handles nonexistent icons gracefully
395         - tooltips only used if Vim has balloon-eval support
396 0.1     - initial release
398 ==============================================================================
399 === END_DOC
401 " vim:ft=vim foldmethod=marker tw=78