Created
March 28, 2011 07:04
-
-
Save stevedonovan/890099 to your computer and use it in GitHub Desktop.
An interactive Lua prompt for the Textadept editor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- makes interactive prompt dodgy. | |
-- (In an ideal world, should be able to switch this off only for | |
-- the message buffer) | |
_m.textadept.editing.AUTOPAIR = false | |
-- useful function which can safely handle argument lists containing nil; | |
-- the resulting table has n set to the real length. | |
local function pack (...) | |
local args = {...} | |
args.n = select('#',...) | |
return args | |
end | |
local function eval_lua(code) | |
local status,res,val,f,err,rcnt | |
code,rcnt = code:gsub('^%s*=','return ') | |
f,err = loadstring(code,'TMP') | |
if f then | |
res = pack(pcall(f)) -- capture all the results | |
local n = res.n | |
if not res[1] then | |
err = res[2] | |
elseif n > 1 and not (n==2 and res[2]==nil) then | |
-- all results except the status; ignore functions returning nil | |
print(unpack(res,2,n)) | |
end | |
end | |
if err then -- either run-time or compile error | |
err = 'error: '..tostring(err):gsub('^%[string "TMP"%]:1:','') | |
print(err) -- 2DO: format as distinctive style | |
end | |
end | |
-- the message buffer does not have a filename field; we grab the last line | |
-- after \n and evaluate as Lua code. | |
local function handle_char (ch) | |
if ch == 10 and not buffer.filename then | |
local line_pos = buffer.current_pos | |
local lineno = buffer:line_from_position(line_pos)-1 | |
local line = buffer:get_line(lineno) | |
eval_lua(line:gsub('^> ','')) -- strip prompt | |
gui.write '> ' | |
end | |
end | |
function lua() | |
gui.write 'Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio\n> ' | |
print = gui.print | |
events.connect('char_added',handle_char) | |
end | |
-- finding the message buffer: factored out | |
local function find_buffer_of_type(buffer_type) | |
-- Try to find a message buffer to print to. Otherwise create one. | |
local message_buffer, message_buffer_index | |
local message_view, message_view_index | |
for i, buffer in ipairs(_BUFFERS) do | |
if buffer._type == buffer_type then | |
message_buffer, message_buffer_index = buffer, i | |
for j, view in ipairs(_VIEWS) do | |
if view.doc_pointer == message_buffer.doc_pointer then | |
message_view, message_view_index = view, j | |
break | |
end | |
end | |
break | |
end | |
end | |
if not message_view then | |
local _, message_view = view:split(false) -- horizontal split | |
if not message_buffer then | |
message_buffer = new_buffer() | |
message_buffer._type = buffer_type | |
events.emit('file_opened') | |
else | |
message_view:goto_buffer(message_buffer_index, true) | |
end | |
else | |
gui.goto_view(message_view_index, true) | |
end | |
end | |
-- append text to a buffer of given type, and position the caret at the end. | |
function gui._write(buffer_type,text) | |
local function safe_write(text) | |
if buffer._type ~= buffer_type then | |
find_buffer_of_type(buffer_type) | |
end | |
buffer:append_text(text) | |
buffer:goto_pos(buffer.length) | |
end | |
pcall(safe_write, text) -- prevent endless loops on error | |
end | |
-- gui._print is here redefined, to use _write. | |
-- It also uses pack() to ensure that it can handle arg lists with nils | |
-- and other values which are not numbers or strings (table.concat | |
-- will choke on these) | |
function gui._print(buffer_type, ...) | |
local args = pack(...) | |
for i = 1,args.n do | |
args[i] = tostring(args[i]) | |
end | |
gui._write(buffer_type,table.concat(args, '\t')) | |
gui._write(buffer_type,'\n') | |
buffer:set_save_point() | |
end | |
function gui.write(text) | |
gui._write("[Message Buffer]",text) | |
buffer:set_save_point() | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment