Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Highlight wrong function argument count

 * The plug-in now highlights wrong argument counts for function calls
   using the SpellLocal style (green underline). When you hover over the
   highlighted text a tooltip shows the associated warning message.

 * I've cleaned up the actions.tooltip() function a little in the
   process, using the new luainspect.signatures.value_signatures and
   splitting up the function into several distinct parts.

 * Signatures no longer include latin1 text so I removed the workaround.

 * Suffix () to known function type table fields in previews.
  • Loading branch information...
commit 72a058e773a97781eaa731567faf1f2268576563 1 parent 026fdd4
Peter Odding authored August 12, 2010
3  README.md
Source Rendered
@@ -10,6 +10,8 @@ The Vim plug-in `luainspect.vim` uses the [LuaInspect](http://lua-users.org/wiki
10 10
 
11 11
  * 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).
12 12
 
  13
+ * 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.
  14
+
13 15
  * 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.
14 16
 
15 17
 ![Screenshot of semantic highlighting](http://peterodding.com/code/vim/luainspect/screenshot.png)
@@ -38,6 +40,7 @@ You don't need to use this command unless you've disabled automatic highlighting
38 40
  * <span style="color: #600000">luaInspectFieldDefined</span>
39 41
  * <span style="color: #C00000">luaInspectFieldUndefined</span>
40 42
  * <span style="background: #D3D3D3">luaInspectSelectedVariable</span>
  43
+ * <span style="border-bottom: 1px dotted green">luaInspectWrongArgCount</span>
41 44
  * <span style="border-bottom: 1px dotted red">luaInspectSyntaxError</span>
42 45
 
43 46
 If you don't like one or more of the default styles the Vim documentation [describes how to change them](http://vimdoc.sourceforge.net/htmldoc/syntax.html#:hi-default). If you want to disable the semantic highlighting in a specific Vim buffer execute `:LuaInspect!` in that buffer. When you want to reenable the highlighting execute `:LuaInspect` again, but now without the [bang](http://vimdoc.sourceforge.net/htmldoc/map.html#:command-bang).
2  TODO.md
Source Rendered
@@ -3,5 +3,5 @@
3 3
  * Copy highlighting colors for dark backgrounds from luainspect/scite.lua.
4 4
  * OMNI completion for in scope variables (including display of library function signatures).
5 5
  * Fix improvised hack by using new `luainspect.signatures.value_signatures` table.
6  
- * Highlighting and tooltips for wrong parameter counts.
7 6
  * Document g:lua_inspect_path option.
  7
+ * Check whether "core/SciTE: jump to definition now supports functions in different files." is interesting.
13  luainspect.vim
@@ -2,7 +2,7 @@
2 2
 " Author: Peter Odding <peter@peterodding.com>
3 3
 " Last Change: August 12, 2010
4 4
 " URL: http://peterodding.com/code/vim/lua-inspect/
5  
-" Version: 0.3.5
  5
+" Version: 0.3.6
6 6
 " License: MIT
7 7
 
8 8
 " Support for automatic update using the GLVS plug-in.
@@ -52,6 +52,7 @@ let s:groups['FieldDefined'] = 'guifg=#600000'
52 52
 let s:groups['FieldUndefined'] = 'guifg=#c00000'
53 53
 let s:groups['SelectedVariable'] = 'CursorLine'
54 54
 let s:groups['SyntaxError'] = 'SpellBad'
  55
+let s:groups['WrongArgCount'] = 'SpellLocal'
55 56
 
56 57
 " (Automatic) command definitions. {{{1
57 58
 
@@ -235,12 +236,14 @@ function! s:highlight_variables() " {{{2
235 236
   call clearmatches()
236 237
   for line in b:luainspect_output[1:-1]
237 238
     if s:check_output(line, '^\w\+\(\s\+\d\+\)\{3}$')
238  
-      let [hlgroup, linenum, firstcol, lastcol] = split(line)
  239
+      let [group, linenum, firstcol, lastcol] = split(line)
239 240
       let pattern = s:highlight_position(linenum + 0, firstcol - 1, lastcol + 2)
240  
-      if hlgroup == 'luaInspectSelectedVariable'
241  
-        call matchadd(hlgroup, pattern)
  241
+      if group == 'luaInspectWarning'
  242
+        call matchadd(group, pattern)
  243
+      elseif group == 'luaInspectSelectedVariable' 
  244
+        call matchadd(group, pattern, 20)
242 245
       else
243  
-        execute 'syntax match' hlgroup '/' . pattern . '/'
  246
+        execute 'syntax match' group '/' . pattern . '/'
244 247
       endif
245 248
     endif
246 249
   endfor
99  luainspect4vim.lua
@@ -15,6 +15,7 @@ local LI = require 'luainspect.init'
15 15
 local LA = require 'luainspect.ast'
16 16
 local LS = require 'luainspect.signatures'
17 17
 local actions, myprint, getcurvar, knownvarorfield = {}
  18
+local printvartype, printsignature, printvalue
18 19
 
19 20
 if type(vim) == 'table' and vim.eval then
20 21
   -- The Lua interface for Vim redefines print() so it prints inside Vim.
@@ -26,7 +27,7 @@ else
26 27
   function myprint(text) io.write(text, '\n') end
27 28
 end
28 29
 
29  
-function getcurvar(tokenlist, line, column)
  30
+function getcurvar(tokenlist, line, column) -- {{{1
30 31
   for i, token in ipairs(tokenlist) do
31 32
     if token.ast.lineinfo then
32 33
       local l1, c1 = unpack(token.ast.lineinfo.first, 1, 2)
@@ -38,57 +39,78 @@ function getcurvar(tokenlist, line, column)
38 39
   end
39 40
 end
40 41
 
41  
-function knownvarorfield(token)
  42
+function knownvarorfield(token) -- {{{1
42 43
   local a = token.ast
43 44
   local v = a.seevalue or a
44 45
   return a.definedglobal or v.valueknown and v.value ~= nil
45 46
 end
46 47
 
47  
-function actions.highlight(tokenlist, line, column)
  48
+function actions.highlight(tokenlist, line, column) -- {{{1
  49
+  local function dump(token, hlgroup)
  50
+    local l1, c1 = unpack(token.ast.lineinfo.first, 1, 2)
  51
+    local l2, c2 = unpack(token.ast.lineinfo.last, 1, 2)
  52
+    myprint(hlgroup .. ' ' .. l1 .. ' ' .. c1 .. ' ' .. c2)
  53
+  end
48 54
   local curvar = getcurvar(tokenlist, line, column)
49 55
   for i, token in ipairs(tokenlist) do
50 56
     if curvar and curvar.ast.id == token.ast.id then
  57
+      dump(token, 'luaInspectSelectedVariable')
  58
+    end
  59
+    if token.ast.note and token.ast.note:find '[Tt]oo%s+%w+%s+arguments' then
51 60
       local l1, c1 = unpack(token.ast.lineinfo.first, 1, 2)
52 61
       local l2, c2 = unpack(token.ast.lineinfo.last, 1, 2)
53  
-      if l1 == l2 then myprint('luaInspectSelectedVariable ' .. l1 .. ' ' .. c1 .. ' ' .. c2) end
  62
+      dump(token, 'luaInspectWrongArgCount')
54 63
     end
55  
-    local kind
56 64
     if token.tag == 'Id' then
57 65
       if not token.ast.localdefinition then
58  
-        if token.ast.definedglobal then
59  
-          kind = 'luaInspectGlobalDefined'
60  
-        else
61  
-          kind = 'luaInspectGlobalUndefined'
62  
-        end
  66
+        dump(token, token.ast.definedglobal and 'luaInspectGlobalDefined' or 'luaInspectGlobalUndefined')
63 67
       elseif not token.ast.localdefinition.isused then
64  
-        kind = 'luaInspectLocalUnused'
  68
+        dump(token, 'luaInspectLocalUnused')
65 69
       elseif token.ast.localdefinition.functionlevel < token.ast.functionlevel then
66  
-        kind = 'luaInspectUpValue'
  70
+        dump(token, 'luaInspectUpValue')
67 71
       elseif token.ast.localdefinition.isset then
68  
-        kind = 'luaInspectLocalMutated'
  72
+        dump(token, 'luaInspectLocalMutated')
69 73
       elseif token.ast.localdefinition.isparam then
70  
-        kind = 'luaInspectParam'
  74
+        dump(token, 'luaInspectParam')
71 75
       else
72  
-        kind = 'luaInspectLocal'
  76
+        dump(token, 'luaInspectLocal')
73 77
       end
74 78
     elseif token.ast.isfield then
75  
-      kind = knownvarorfield(token) and 'luaInspectFieldDefined' or 'luaInspectFieldUndefined'
  79
+      dump(token, knownvarorfield(token) and 'luaInspectFieldDefined' or 'luaInspectFieldUndefined')
76 80
     end
77  
-    if kind then
  81
+  end
  82
+end
  83
+
  84
+function actions.tooltip(tokenlist, line, column) -- {{{1
  85
+  local did_details = false
  86
+  for i, token in ipairs(tokenlist) do
  87
+    if token.ast.lineinfo then
78 88
       local l1, c1 = unpack(token.ast.lineinfo.first, 1, 2)
79 89
       local l2, c2 = unpack(token.ast.lineinfo.last, 1, 2)
80  
-      if l1 == l2 then myprint(kind .. ' ' .. l1 .. ' ' .. c1 .. ' ' .. c2) end
  90
+      if l1 == line then
  91
+        local ast = token.ast
  92
+        if ast and ast.id and column >= c1 and column <= c2 and not did_details then
  93
+          printvartype(token)
  94
+          printsignature(ast)
  95
+          printvalue(ast)
  96
+          did_details = true
  97
+        end
  98
+        if ast.note then
  99
+          if ast.note:find '[Tt]oo%s+%w+%s+arguments' then
  100
+            myprint("Warning: " .. ast.note)
  101
+          else
  102
+            myprint("Note: " .. ast.note)
  103
+          end
  104
+          break
  105
+        end
  106
+      end
81 107
     end
82 108
   end
83 109
 end
84 110
 
85  
-function actions.tooltip(tokenlist, line, column)
86  
-  local text = {}
87  
-  local token = getcurvar(tokenlist, line, column)
88  
-  if not token then return end
  111
+function printvartype(token) -- {{{1
89 112
   local ast = token.ast
90  
-  if not ast then return end
91  
-  -- Describe the variable type and status.
  113
+  local text = {}
92 114
   if ast.localdefinition then
93 115
     if not ast.localdefinition.isused then text[#text+1] = "unused" end
94 116
     if ast.localdefinition.isset then text[#text+1] = "mutable" end
@@ -114,22 +136,17 @@ function actions.tooltip(tokenlist, line, column)
114 136
   -- unknown table field even though table.concat() returns a string?!
115 137
   text = table.concat(text, ' ')
116 138
   myprint("This is " .. (text:find '^[aeiou]' and 'an' or 'a') .. ' ' .. text .. '.')
  139
+end
  140
+
  141
+function printsignature(ast) -- {{{1
117 142
   -- Display signatures for standard library functions.
118 143
   local name = ast.resolvedname
119 144
   local signature = name and LS.global_signatures[name]
120 145
   if not signature then
121 146
     local value = (ast.seevalue or ast).value
122  
-    for name, sig in pairs(LS.global_signatures) do
123  
-      if value == loadstring('return ' .. name)() then
124  
-        signature = sig
125  
-      end
126  
-    end
  147
+    signature = value and LS.value_signatures[value]
127 148
   end
128 149
   if signature then
129  
-    -- luainspect/signatures.lua contains special bullet characters in the
130  
-    -- latin1 character encoding (according to Vim) which Vim doesn't like
131  
-    -- in tooltips (I guess because it expects UTF-8).
132  
-    signature = signature:gsub('\183', '.')
133 150
     if not signature:find '%w %b()$' then
134 151
       myprint 'Its description is:'
135 152
       myprint('    ' .. signature)
@@ -138,6 +155,9 @@ function actions.tooltip(tokenlist, line, column)
138 155
       myprint('    ' .. signature)
139 156
     end
140 157
   end
  158
+end
  159
+
  160
+function printvalue(ast) -- {{{1
141 161
   -- Try to represent the value as a string.
142 162
   local value = (ast.seevalue or ast).value
143 163
   if type(value) == 'table' then
@@ -145,7 +165,7 @@ function actions.tooltip(tokenlist, line, column)
145 165
     local keys = {}
146 166
     for k, v in pairs(value) do
147 167
       if type(k) == 'string' then
148  
-        keys[#keys+1] = k
  168
+        keys[#keys+1] = k .. (type(v) == 'function' and '()' or '')
149 169
       elseif type(k) == 'number' then
150 170
         keys[#keys+1] = '[' .. k .. ']'
151 171
       else
@@ -195,14 +215,9 @@ function actions.tooltip(tokenlist, line, column)
195 215
   elseif value ~= nil then
196 216
     myprint("Its value is the " .. type(value) .. ' ' .. tostring(value) .. '.')
197 217
   end
198  
-  --[[ TODO Print warning notes attached to function calls?
199  
-  local vast = ast.seevalue or ast
200  
-  local note = vast.parent and (vast.parent.tag == 'Call' or vast.parent.tag == 'Invoke') and vast.parent.note
201  
-  if note then myprint("WARNING: " .. note) end
202  
-  --]]
203 218
 end
204 219
 
205  
-function actions.goto(tokenlist, line, column)
  220
+function actions.goto(tokenlist, line, column) -- {{{1
206 221
   -- FIXME This only jumps to declaration of local / 1st occurrence of global.
207 222
   local curvar = getcurvar(tokenlist, line, column)
208 223
   for i, token in ipairs(tokenlist) do
@@ -215,7 +230,7 @@ function actions.goto(tokenlist, line, column)
215 230
   end
216 231
 end
217 232
 
218  
-function actions.rename(tokenlist, line, column)
  233
+function actions.rename(tokenlist, line, column) -- {{{1
219 234
   local curvar = getcurvar(tokenlist, line, column)
220 235
   for i, token in ipairs(tokenlist) do
221 236
     if curvar and curvar.ast.id == token.ast.id then
@@ -226,6 +241,8 @@ function actions.rename(tokenlist, line, column)
226 241
   end
227 242
 end
228 243
 
  244
+-- }}}
  245
+
229 246
 return function(src)
230 247
   local action, line, column, src = src:match '^(%S+)\n(%d+)\n(%d+)\n(.*)$'
231 248
   line = tonumber(line)

0 notes on commit 72a058e

Please sign in to comment.
Something went wrong with that request. Please try again.