Skip to content

Commit

Permalink
Bug fix: Show error highlighting only in Lua buffers
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
xolox committed Aug 12, 2010
1 parent c6a8ecf commit 2d671c4
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 81 deletions.
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -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.

Expand Down
1 change: 0 additions & 1 deletion TODO.md
Expand Up @@ -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('%'))
145 changes: 78 additions & 67 deletions luainspect.vim
Expand Up @@ -13,6 +13,8 @@ if &cp || exists('g:loaded_luainspect')
finish
endif

let s:script = expand('<sfile>:p:~')

" Configuration defaults. {{{1

if !exists('g:lua_inspect_events')
Expand Down Expand Up @@ -56,109 +58,118 @@ let s:groups['WrongArgCount'] = 'SpellLocal'

" (Automatic) command definitions. {{{1

command! -bar -bang LuaInspect call s:run_lua_inspect('highlight', 1, <q-bang> != '!')
command! -bar -bang LuaInspect call s:luainspect_command(<q-bang> == '!')

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 <buffer> <silent> <F2> <C-o>:call <Sid>run_lua_inspect('rename', 0, 1)<CR>
nnoremap <buffer> <silent> <F2> :call <Sid>run_lua_inspect('rename', 0, 1)<CR>
nnoremap <buffer> <silent> gd :call <Sid>run_lua_inspect('goto', 0, 1)<CR>
inoremap <buffer> <silent> <F2> <C-o>:call <Sid>run_lua_inspect('rename')<CR>
nnoremap <buffer> <silent> <F2> :call <Sid>run_lua_inspect('rename')<CR>
nnoremap <buffer> <silent> gd :call <Sid>run_lua_inspect('goto')<CR>
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
return type(text) == type('') ? text : ''
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'))
Expand Down
33 changes: 21 additions & 12 deletions luainspect4vim.lua
Expand Up @@ -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
Expand Down

0 comments on commit 2d671c4

Please sign in to comment.