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