Skip to content

Commit

Permalink
HTML: highlight keywords in selected block
Browse files Browse the repository at this point in the history
  (LI.mark_related_keywords)
  • Loading branch information
davidm committed Aug 6, 2010
1 parent 191ebae commit cf1772a
Show file tree
Hide file tree
Showing 9 changed files with 67 additions and 25 deletions.
3 changes: 2 additions & 1 deletion README.txt
Expand Up @@ -12,7 +12,7 @@ For further details, see http://lua-users.org/wiki/LuaInspect .
== Features ==

* cross-references local variables with their definitions and uses (pink highlight)
* shows all keywords in a statement (pink highlight - SciTE only)
* shows all keywords in selected block (underline)
* identifies global (red) and local variables (blue)
* identifies function arguments (dark blue)
* identifies global variables that are probably undefined (white-on-red)
Expand Down Expand Up @@ -125,6 +125,7 @@ Peter Odding for VIM editor support [2]
20100805
core: Major internal refactoring to simplify incremental compilation
(lineinfo managed in tokenlist).
HTML: highlight keywords in selected block

20100803
core:Evaluate special comments (prefixed by '!') to inject semantic information into analysis
Expand Down
4 changes: 3 additions & 1 deletion htmllib/luainspect.css
@@ -1,4 +1,4 @@
// LuaInspect CSS styles
/* LuaInspect CSS styles */

.id { cursor: pointer }
.id.local { color: #000080; }
Expand All @@ -12,6 +12,8 @@
.id.mutatebind { font-style: italic }
.comment { color: #008000 }
.string { color: #00c000 }
.keyword { color: #505050; font-weight: bold }
.keyword.highlight { text-decoration: underline }

.id.highlight {background-color: #ffe0e0}

Expand Down
10 changes: 9 additions & 1 deletion htmllib/luainspect.js
Expand Up @@ -4,7 +4,7 @@ function highlightSameClass(obj, enable) {
var classes = obj.attr('class').split(' ');
for (var i in classes) {
var aclass = classes[i];
if (aclass.match(/^id\d+/)) {
if (aclass.match(/^id\w*\d+/)) {
if (enable) {
$("." + aclass).addClass("highlight");
}
Expand All @@ -29,6 +29,14 @@ $(document).ready(function() {
highlightSameClass($(this), false);
}
);
$(".keyword").hover(
function() {
highlightSameClass($(this), true);
},
function() {
highlightSameClass($(this), false);
}
);
});

//.mousemove(function(kmouse) {
Expand Down
1 change: 1 addition & 0 deletions luainspectlib/luainspect/command.lua
Expand Up @@ -31,6 +31,7 @@ local ast, err, linenum, colnum, linenum2 = LI.ast_from_string(src, path)
if ast then
local tokenlist = LI.ast_to_tokenlist(ast, src)
LI.inspect(ast, tokenlist)
LI.mark_related_keywords(ast, tokenlist, src)

local ast = LH.ast_to_html(ast, src, tokenlist)

Expand Down
3 changes: 3 additions & 0 deletions luainspectlib/luainspect/html.lua
Expand Up @@ -102,6 +102,9 @@ function M.ast_to_html(ast, src, tokenlist)
return "<span class='comment'>" .. snip_html .. "</span>"
elseif token.tag == 'String' then -- note: excludes ast.isfield
return "<span class='string'>" .. snip_html .. "</span>"
elseif token.tag == 'Keyword' then
local id = token.keywordid and 'idk' .. tostring(token.keywordid) or ''
return "<span class='keyword " .. id .. "'>" .. snip_html .. "</span>"
end
end
return snip_html
Expand Down
48 changes: 33 additions & 15 deletions luainspectlib/luainspect/init.lua
Expand Up @@ -245,8 +245,7 @@ end
-- function declaration syntactic sugar is handled specially too to ensure the 'function' keyword
-- is highlighted even though it may be outside of the `Function AST.
--
-- kposlist is list of begin/end positions of keywords. Returned `ast` is AST containing related
-- keywords.
-- Returns token list or nil if not applicable. Returned `ast` is AST containing related keywords.
local iskeystat = {Do=true, While=true, Repeat=true, If=true, Fornum=true, Forin=true,
Local=true, Localrec=true, Return=true, Break=true, Function=true,
Set=true -- note: Set for `function name`
Expand Down Expand Up @@ -303,12 +302,11 @@ function M.related_keywords(ast, top_ast, tokenlist, src)

-- keywords in statement/block.
if iskeystat[ast.tag] then
local kposlist = {}
local keywords = {}
for i=1,#tokenlist do
local token = tokenlist[i]
if token.ast == ast and token.tag == 'Keyword' then
kposlist[#kposlist+1] = token.fpos
kposlist[#kposlist+1] = token.lpos
keywords[#keywords+1] = token
end
end

Expand All @@ -320,8 +318,7 @@ function M.related_keywords(ast, top_ast, tokenlist, src)
if type(cast) == 'table' then
if cast.tag == 'Return' then
local token = tokenlist[M.ast_idx_range_in_tokenlist(tokenlist, cast)]
kposlist[#kposlist+1] = token.fpos
kposlist[#kposlist+1] = token.lpos
keywords[#keywords+1] = token
elseif cast.tag ~= 'Function' then f(cast) end
end
end
Expand All @@ -332,33 +329,30 @@ function M.related_keywords(ast, top_ast, tokenlist, src)
if grand_ast.tag == 'Set' then
local token = tokenlist[M.ast_idx_range_in_tokenlist(tokenlist, grand_ast)]
if token.tag == 'Keyword' and token[1] == 'function' then
kposlist[#kposlist+1] = token.fpos
kposlist[#kposlist+1] = token.lpos
keywords[#keywords+1] = token
end
elseif grand_ast.tag == 'Localrec' then
local tidx = M.ast_idx_range_in_tokenlist(tokenlist, grand_ast)
repeat tidx = tidx + 1 until tokenlist[tidx].tag == 'Keyword' and tokenlist[tidx][1] == 'function'
local token = tokenlist[tidx]
kposlist[#kposlist+1] = token.fpos
kposlist[#kposlist+1] = token.lpos
keywords[#keywords+1] = token
end
elseif isloop[ast.tag] then
-- if loop, also select 'break' keywords
local function f(ast)
for _,cast in ipairs(ast) do
if type(cast) == 'table' then
if cast.tag == 'Break' then
local kfpos, klpos = M.ast_pos_range(cast, tokenlist)
kposlist[#kposlist+1] = kfpos
kposlist[#kposlist+1] = klpos
local tidx = M.ast_idx_range_in_tokenlist(tokenlist, cast)
keywords[#keywords+1] = tokenlist[tidx]
elseif not isloop[cast.tag] then f(cast) end
end
end
end
f(ast)
end

return kposlist, ast
return keywords, ast
end
return nil, ast
end
Expand Down Expand Up @@ -961,6 +955,30 @@ end
--IMPROVE: in `do f() --[[!g()]] h()` only apply g to h.


-- Mark tokenlist (top_ast/tokenlist/src) with keywordid AST attributes.
-- All keywords related to each other have the same keyword ID integer.
-- NOTE: This is not done/undone by inspect/uninspect.
function M.mark_related_keywords(top_ast, tokenlist, src)
local id = 0
local idof = {}
for _, token in ipairs(tokenlist) do
if token.tag == 'Keyword' and not idof[token] then
id = id + 1
local match_ast =
M.smallest_ast_in_range(top_ast, tokenlist, src, token.fpos, token.lpos)
local ktokenlist = M.related_keywords(match_ast, top_ast, tokenlist, src)
if ktokenlist then
for _, ktoken in ipairs(ktokenlist) do
ktoken.keywordid = id
idof[ktoken] = true
end
end
-- note: related_keywords may return a keyword set not containing given keyword.
end
end
end


-- Partially undoes effects of inspect().
-- Note: does not undo mark_tag2 and mark_parents (see replace_statements).
function M.uninspect(top_ast)
Expand Down
9 changes: 4 additions & 5 deletions luainspectlib/luainspect/scite.lua
Expand Up @@ -436,11 +436,10 @@ scite_OnUpdateUI(function()
-- DEBUG('m', match1_ast and match1_ast.tag, match1_comment, iswhitespace)

-- Find and highlight.
local kposlist; kposlist, match1_ast = LI.related_keywords(match1_ast, buffer.ast, buffer.tokenlist, buffer.text)
if kposlist then
for i=1,#kposlist,2 do
local fpos, lpos = kposlist[i], kposlist[i+1]
--DEBUG(fpos,lpos,'m')
local keywords; keywords, match1_ast = LI.related_keywords(match1_ast, buffer.ast, buffer.tokenlist, buffer.text)
if keywords then
for i=1,#keywords do
local fpos, lpos = keywords[i].fpos, keywords[i].lpos
editor:IndicatorFillRange(fpos-1, lpos-fpos+1)
end
end
Expand Down
4 changes: 3 additions & 1 deletion test-output/luainspect.css
@@ -1,4 +1,4 @@
// LuaInspect CSS styles
/* LuaInspect CSS styles */

.id { cursor: pointer }
.id.local { color: #000080; }
Expand All @@ -12,6 +12,8 @@
.id.mutatebind { font-style: italic }
.comment { color: #008000 }
.string { color: #00c000 }
.keyword { color: #505050; font-weight: bold }
.keyword.highlight { text-decoration: underline }

.id.highlight {background-color: #ffe0e0}

Expand Down
10 changes: 9 additions & 1 deletion test-output/luainspect.js
Expand Up @@ -4,7 +4,7 @@ function highlightSameClass(obj, enable) {
var classes = obj.attr('class').split(' ');
for (var i in classes) {
var aclass = classes[i];
if (aclass.match(/^id\d+/)) {
if (aclass.match(/^id\w*\d+/)) {
if (enable) {
$("." + aclass).addClass("highlight");
}
Expand All @@ -29,6 +29,14 @@ $(document).ready(function() {
highlightSameClass($(this), false);
}
);
$(".keyword").hover(
function() {
highlightSameClass($(this), true);
},
function() {
highlightSameClass($(this), false);
}
);
});

//.mousemove(function(kmouse) {
Expand Down

0 comments on commit cf1772a

Please sign in to comment.