From 2d671c489bdf42dfe68b289588c09e0a18c7ce0b Mon Sep 17 00:00:00 2001 From: Peter Odding Date: Thu, 12 Aug 2010 21:19:41 +0200 Subject: [PATCH] Bug fix: Show error highlighting only in Lua buffers When luainspect.vim requests a tool tip text from luainspect4vim.lua but a syntax error is found then no tool tips are available, however the syntax error is reported so that it can be highlighted as such. This feature and its sequence of events introduced the following bug: 1. Open a Lua buffer. 2. Create a syntax error in the Lua buffer. 2. Create a split window showing a non-Lua buffer. 3. With the focus on the non-Lua buffer, hover over the split window showing the Lua buffer and wait for the tool tip to appear. 4. The tool tip will be correct but the syntax error highlighting is now applied in the non-Lua buffer: Clearly not the intention :-) This commit fixes the problem. I've also added calls to my xolox#timer functions so that, when you execute the following command: :verbose LuaInspect You get a message with the time spent inside luainspect4vim.lua and the overhead imposed by the communication between Vim and Lua. --- README.md | 2 +- TODO.md | 1 - luainspect.vim | 145 ++++++++++++++++++++++++--------------------- luainspect4vim.lua | 33 +++++++---- 4 files changed, 100 insertions(+), 81 deletions(-) diff --git a/README.md b/README.md index a630a36..31febb8 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ The Vim plug-in `luainspect.vim` uses the [LuaInspect](http://lua-users.org/wiki * If the text cursor is on a variable while the highlighting is refreshed then all occurrences of the variable will be marked in the style of [Vim's cursorline option](http://vimdoc.sourceforge.net/htmldoc/options.html#%27cursorline%27). - * When luainspect reports a wrong argument count for a function call the call will be highlighted with a green underline. When you hover over the highlighted text a tooltip shows the associated warning message. + * When luainspect reports a wrong argument count for a function call the text will be highlighted with a green underline. When you hover over the highlighted text a tooltip shows the associated warning message. * When a syntax error is found (during highlighting or using the rename functionality) the lines where the error is reported will be marked like a spelling error. diff --git a/TODO.md b/TODO.md index dc95a7b..2de4499 100644 --- a/TODO.md +++ b/TODO.md @@ -4,4 +4,3 @@ * Document g:lua_inspect_path option. * Check whether "core/SciTE: jump to definition now supports functions in different files." is interesting. * Use the new 'init.get_variable_details' function to replace most of actions.tooltip()? - * BUG: With a Lua script in one split window and a different file type in another split window, where the active window contains the non-Lua file, if you hover over the Lua window syntax error highlighting is applied to the non-Lua buffer! Hint: getbufline() / assert(v:beval_bufnr==bufnr('%')) diff --git a/luainspect.vim b/luainspect.vim index a18fb74..557a0fa 100644 --- a/luainspect.vim +++ b/luainspect.vim @@ -13,6 +13,8 @@ if &cp || exists('g:loaded_luainspect') finish endif +let s:script = expand(':p:~') + " Configuration defaults. {{{1 if !exists('g:lua_inspect_events') @@ -56,37 +58,54 @@ let s:groups['WrongArgCount'] = 'SpellLocal' " (Automatic) command definitions. {{{1 -command! -bar -bang LuaInspect call s:run_lua_inspect('highlight', 1, != '!') +command! -bar -bang LuaInspect call s:luainspect_command( == '!') augroup PluginLuaInspect " Clear existing automatic commands. autocmd! - " Disable easytags.vim because it doesn't play nice with luainspect.vim! - autocmd BufNewFile,BufReadPost,BufWritePost * call s:init_lua_buffer() - " Define the configured automatic commands. + " Automatically enable the plug-in on these events. + autocmd BufNewFile,BufReadPost,BufWritePost * call s:auto_enable_plugin() + " Define the configured automatic commands for highlighting. for s:event in split(g:lua_inspect_events, ',') - execute 'autocmd' s:event '* if s:check_plugin_enabled() | LuaInspect | endif' + execute 'autocmd' s:event '* if s:check_plugin_valid() | LuaInspect | endif' endfor + unlet s:event augroup END " Script local functions. {{{1 -function! s:check_plugin_enabled() +function! s:check_plugin_valid() " {{{2 return &ft == 'lua' && !&diff && !exists('b:luainspect_disabled') endfunction -function! s:init_lua_buffer() - if s:check_plugin_enabled() +function! s:luainspect_command(disable) " {{{2 + if a:disable + call s:clear_previous_matches() + unlet! b:luainspect_input b:luainspect_output + let b:luainspect_disabled = 1 + else + unlet! b:luainspect_disabled + let starttime = xolox#timer#start() + call s:run_lua_inspect('highlight') + let bufname = expand('%:p:~') + let msg = "%s: Highlighted %s in %s." + call xolox#timer#stop(msg, s:script, bufname, starttime) + endif +endfunction + +function! s:auto_enable_plugin() " {{{2 + if s:check_plugin_valid() + " Disable easytags.vim because it doesn't play nice with luainspect.vim! let b:easytags_nohl = 1 - inoremap :call run_lua_inspect('rename', 0, 1) - nnoremap :call run_lua_inspect('rename', 0, 1) - nnoremap gd :call run_lua_inspect('goto', 0, 1) + inoremap :call run_lua_inspect('rename') + nnoremap :call run_lua_inspect('rename') + nnoremap gd :call run_lua_inspect('goto') setlocal ballooneval balloonexpr=LuaInspectToolTip() endif endfunction function! LuaInspectToolTip() " {{{2 - let text = s:run_lua_inspect('tooltip', 0, 1) + let text = s:run_lua_inspect('tooltip') if exists('b:luainspect_syntax_error') return b:luainspect_syntax_error else @@ -94,71 +113,63 @@ function! LuaInspectToolTip() " {{{2 endif endfunction -function! s:run_lua_inspect(action, toggle, enabled) " {{{2 - if !a:toggle || s:set_plugin_enabled(a:enabled) +function! s:run_lua_inspect(action) " {{{2 + if a:action == 'tooltip' + let lines = getbufline(v:beval_bufnr, 1, "$") + call insert(lines, v:beval_col) + call insert(lines, v:beval_lnum) + else let lines = getline(1, "$") - if a:action == 'tooltip' - call insert(lines, v:beval_col) - call insert(lines, v:beval_lnum) - else - call insert(lines, col('.')) - call insert(lines, line('.')) + call insert(lines, col('.')) + call insert(lines, line('.')) + endif + call insert(lines, a:action) + call s:parse_text(join(lines, "\n"), s:prepare_search_path()) + if !empty(b:luainspect_output) + let response = b:luainspect_output[0] + if response == 'syntax_error' && len(b:luainspect_output) >= 4 + " Never perform syntax error highlighting in non-Lua buffers! + let linenum = b:luainspect_output[1] + 0 + let colnum = b:luainspect_output[2] + 0 + let linenum2 = b:luainspect_output[3] + 0 + let b:luainspect_syntax_error = b:luainspect_output[4] + if a:action != 'tooltip' || v:beval_bufnr == bufnr('%') + let error_cmd = 'syntax match luaInspectSyntaxError /\%%>%il\%%<%il.*/ containedin=ALLBUT,lua*Comment*' + execute printf(error_cmd, linenum - 1, (linenum2 ? linenum2 : line('$')) + 1) + endif + " But always let the user know that a syntax error exists. + let bufname = fnamemodify(bufname(a:action != 'tooltip' ? '%' : v:beval_bufnr), ':p:~') + call xolox#warning("Syntax error around line %i in %s: %s", linenum, bufname, b:luainspect_syntax_error) + return endif - call insert(lines, a:action) - call s:parse_text(join(lines, "\n"), s:prepare_search_path()) - if !empty(b:luainspect_output) - let response = b:luainspect_output[0] - if response == 'syntax_error' && len(b:luainspect_output) >= 4 + unlet! b:luainspect_syntax_error + if response == 'highlight' + call s:define_default_styles() + call s:clear_previous_matches() + call s:highlight_variables() + elseif response == 'goto' + if len(b:luainspect_output) < 3 + call xolox#warning("No variable under cursor!") + else let linenum = b:luainspect_output[1] + 0 let colnum = b:luainspect_output[2] + 0 - let linenum2 = b:luainspect_output[3] + 0 - let b:luainspect_syntax_error = b:luainspect_output[4] - let error_cmd = 'syntax match luaInspectSyntaxError /\%%>%il\%%<%il.*/ containedin=ALLBUT,lua*Comment*' - execute printf(error_cmd, linenum - 1, (linenum2 ? linenum2 : line('$')) + 1) - call xolox#warning("Syntax error around line %i: %s", linenum, b:luainspect_syntax_error) - return + call setpos('.', [0, linenum, colnum, 0]) + call xolox#message("") " Clear any previous message to avoid confusion. endif - unlet! b:luainspect_syntax_error - if response == 'highlight' - call s:define_default_styles() - call s:clear_previous_matches() - call s:highlight_variables() - elseif response == 'goto' - if len(b:luainspect_output) < 3 - call xolox#warning("No variable under cursor!") - else - let linenum = b:luainspect_output[1] + 0 - let colnum = b:luainspect_output[2] + 0 - call setpos('.', [0, linenum, colnum, 0]) - call xolox#message("") " Clear any previous message to avoid confusion. - endif - elseif response == 'tooltip' - if len(b:luainspect_output) > 1 - return join(b:luainspect_output[1:-1], "\n") - endif - elseif response == 'rename' - if len(b:luainspect_output) == 1 - call xolox#warning("No variable under cursor!") - else - call s:rename_variable() - endif + elseif response == 'tooltip' + if len(b:luainspect_output) > 1 + return join(b:luainspect_output[1:-1], "\n") + endif + elseif response == 'rename' + if len(b:luainspect_output) == 1 + call xolox#warning("No variable under cursor!") + else + call s:rename_variable() endif endif endif endfunction -function! s:set_plugin_enabled(enabled) " {{{2 - if a:enabled - unlet! b:luainspect_disabled - return 1 - else - call s:clear_previous_matches() - unlet! b:luainspect_input b:luainspect_output - let b:luainspect_disabled = 1 - return 0 - endif -endfunction - function! s:prepare_search_path() " {{{2 let code = '' if !(has('lua') && g:lua_inspect_internal && exists('s:changed_path')) diff --git a/luainspect4vim.lua b/luainspect4vim.lua index 3018d82..fca5df2 100644 --- a/luainspect4vim.lua +++ b/luainspect4vim.lua @@ -83,25 +83,34 @@ end function actions.tooltip(tokenlist, line, column) -- {{{1 local did_details = false + local note for i, token in ipairs(tokenlist) do if token.ast.lineinfo then local l1, c1 = unpack(token.ast.lineinfo.first, 1, 2) local l2, c2 = unpack(token.ast.lineinfo.last, 1, 2) if l1 == line then local ast = token.ast - if ast and ast.id and column >= c1 and column <= c2 and not did_details then - printvartype(token) - printsignature(ast) - printvalue(ast) - did_details = true - end - if ast.note then - if ast.note:find '[Tt]oo%s+%w+%s+arguments' then - myprint("Warning: " .. ast.note) - else - myprint("Note: " .. ast.note) + if ast and column >= c1 and column <= c2 then + if ast.id and not did_details then + printvartype(token) + printsignature(ast) + printvalue(ast) + if note then + myprint(note) + break + end + end + if ast.note then + -- This is complicated by the fact that I don't really understand + -- the metalua/lua-inspect abstract syntax tree and apparently notes + -- are not always available on the identifier token printed above. + local iswarning = ast.note:find '[Tt]oo%s+%w+%s+arguments' + note = (iswarning and "Warning: " or "Note: ") .. ast.note + if did_details then + myprint(note) + break + end end - break end end end