[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Lua Semantic Highlighting for Emacs
- From: Peter Odding <peter@...>
- Date: Tue, 27 Jul 2010 18:04:12 +0200
Romulo wrote:
As you mentioned it.. does anyone know if there any effort to bring
contextual highlighting to vim's Lua file type plugin? I've never done
any vim plugin, so I am clueless about how difficult it might be.
Inspired by this thread, I've just published the first prototype of a
Vim plug-in that uses LuaInspect to (automatically) perform semantic
highlighting of variables in Lua buffers. You can find installation
instructions for the plug-in at
http://peterodding.com/code/vim/lua-inspect/#installation
- Peter Odding
" Vim plug-in
" Author: Peter Odding <peter@peterodding.com>
" Last Change: July 27, 2010
" URL: http://peterodding.com/code/vim/lua-inspect/
" Version: 0.1.2
" Configuration defaults. {{{1
if !exists('g:lua_inspect_automatic')
" Set this to false (0) to disable the automatic command.
let g:lua_inspect_automatic = 1
endif
if !exists('g:lua_inspect_internal')
" Set this to false (0) to run LuaInspect inside the Lua interface for Vim.
" This makes it faster but less accurate because the Lua interface for Vim
" doesn't include io.* and half of os.* which means LuaInspect marks them as
" undefined globals...
let g:lua_inspect_internal = 0
endif
" (Automatic) command definitions. {{{1
command! LuaInspect call s:RunLuaInspect()
augroup PluginLuaInspect
autocmd! CursorHold,CursorHoldI * call s:AutoEnable()
augroup END
" Script local functions. {{{1
function! s:AutoEnable()
if &filetype == 'lua' && g:lua_inspect_automatic
LuaInspect
end
endfunction
function! s:RunLuaInspect()
let l:text = join(getline(1, "$"), "\n")
if has('lua') && g:lua_inspect_internal
" Run LuaInspect using the Lua interface for Vim.
redir => listing
silent lua << EOF
if io == nil then
-- The Lua interface for Vim doesn't include io.*!
io = { type = function() end }
end
require 'luainspect4vim' (vim.eval 'l:text')
EOF
redir END
else
" Run LuaInspect as an external program.
let listing = system("lua -e 'require\"luainspect4vim\" (io.read \"*a\")'", l:text)
endif
" Clear previously created highlighting.
call s:InitHighlighting()
" Highlight variables in buffer based on positions.
for fields in split(listing, "\n")
let [type, lnum, start, end] = split(fields)
let command = 'syntax match %s /\%%%il\%%>%ic.\+\%%<%ic/'
execute printf(command, type, lnum, start - 1, end + 2)
endfor
endfunction
function! s:InitHighlighting()
" Clear existing highlighting.
if hlexists('luaInspectGlobalDefined') | syntax clear luaInspectGlobalDefined | endif
if hlexists('luaInspectGlobalUndefined') | syntax clear luaInspectGlobalUndefined | endif
if hlexists('luaInspectLocalUnused') | syntax clear luaInspectLocalUnused | endif
if hlexists('luaInspectLocalMutated') | syntax clear luaInspectLocalMutated | endif
if hlexists('luaInspectUpValue') | syntax clear luaInspectUpValue | endif
if hlexists('luaInspectParam') | syntax clear luaInspectParam | endif
if hlexists('luaInspectLocal') | syntax clear luaInspectLocal | endif
if hlexists('luaInspectFieldDefined') | syntax clear luaInspectFieldDefined | endif
if hlexists('luaInspectFieldUndefined') | syntax clear luaInspectFieldUndefined | endif
" Define default styles (copied from /luainspect/scite.lua for consistency).
hi luaInspectGlobalDefined guifg=#600000
hi def link luaInspectGlobalUndefined WarningMsg
hi luaInspectLocalUnused guifg=#ffffff guibg=#0000ff
hi luaInspectLocalMutated gui=italic guifg=#000080
hi luaInspectUpValue guifg=#0000ff
hi luaInspectParam guifg=#000040
hi luaInspectLocal guifg=#000080
hi luaInspectFieldDefined guifg=#600000
hi luaInspectFieldUndefined guifg=#c00000
" TODO Consider the &background?
endfunction
" vim: ts=2 sw=2 et
--[[
This module is part of the luainspect.vim plug-in for the Vim text editor.
Author: Peter Odding <peter@peterodding.com>
Last Change: July 27, 2010
URL: http://peterodding.com/code/vim/lua-inspect/
--]]
local function offset2lineinfo(text, offset)
-- TODO Cache intermediate results because they won't change within a single
-- call to the function returned from this module below.
local curlnum = 1
local lastlineoffset = 0
for i in text:gmatch '()\n' do
if i < offset then
curlnum = curlnum + 1
lastlineoffset = i
else
break
end
end
return curlnum, offset - lastlineoffset
end
return function(text)
-- Load the LuaInspect core module.
local LI = require 'luainspect.init'
text = LI.remove_shebang(text)
local f, err, linenum, colnum, linenum2 = LI.loadstring(text)
local function dumpvar(kind, firstbyte, lastbyte)
local line1, offset1 = offset2lineinfo(text, firstbyte)
if type(vim) == 'table' and vim.eval then
-- The Lua interface for Vim redefines print() so it prints inside Vim.
print(kind, line1, offset1, offset1 + (lastbyte - firstbyte))
else
-- My $LUA_INIT script redefines print() to enable pretty printing in the
-- interactive prompt, which means strings are printed with surrounding
-- quotes. This would break the communication between Vim and this script.
io.write(kind, '\t', line1, '\t', offset1, '\t', offset1 + (lastbyte - firstbyte), '\n')
end
end
if f then
local ast; ast, err, linenum, colnum, linenum2 = LI.ast_from_string(text, "noname.lua")
if ast then
for i, note in ipairs(LI.inspect(ast)) do
if note.type == 'global' then
if note.definedglobal then
dumpvar('luaInspectGlobalDefined', note[1], note[2])
else
dumpvar('luaInspectGlobalUndefined', note[1], note[2])
end
elseif note.type == 'local' then
if not note.ast.localdefinition.isused then
dumpvar('luaInspectLocalUnused', note[1], note[2])
elseif note.ast.localdefinition.isset then
dumpvar('luaInspectLocalMutated', note[1], note[2])
elseif note.ast.localdefinition.functionlevel < note.ast.functionlevel then
dumpvar('luaInspectUpValue', note[1], note[2])
elseif note.ast.localdefinition.isparam then
dumpvar('luaInspectParam', note[1], note[2])
else
dumpvar('luaInspectLocal', note[1], note[2])
end
elseif note.type == 'field' then
if note.definedglobal or note.ast.seevalue.value ~= nil then
dumpvar('luaInspectFieldDefined', note[1], note[2])
else
dumpvar('luaInspectFieldUndefined', note[1], note[2])
end
end
end
end
end
end
-- vim: ts=2 sw=2 et