diff options
-rw-r--r-- | core/ui.lua | 9 | ||||
-rw-r--r-- | modules/textadept/run.lua | 41 | ||||
-rw-r--r-- | test/test.lua | 12 |
3 files changed, 41 insertions, 21 deletions
diff --git a/core/ui.lua b/core/ui.lua index 43101a96..aec0725f 100644 --- a/core/ui.lua +++ b/core/ui.lua @@ -495,7 +495,14 @@ if CURSES then end) end -events_connect(events.ERROR, ui.print) +local lua_error = (not WIN32 and '^/' or '^%a:[/\\]') .. '.-%.lua:%d+:' +-- Print internal Lua error messages as they are reported. +-- Attempt to mimic the Lua interpreter's error message format so tools that +-- look for it can recognize these errors too. +events_connect(events.ERROR, function(text) + if text and text:find(lua_error) then text = 'lua: ' .. text end -- mimic Lua + ui.print(text) +end) --[[ The tables below were defined in C. diff --git a/modules/textadept/run.lua b/modules/textadept/run.lua index 2faf38bf..3b19c222 100644 --- a/modules/textadept/run.lua +++ b/modules/textadept/run.lua @@ -351,18 +351,18 @@ M.error_patterns = {actionscript={'^(.-)%((%d+)%): col: (%d+) (.+)$'},ada={'^(.- local function is_msg_buf(buf) return buf._type == _L['[Message Buffer]'] end --- -- Jumps to the source of the recognized compile/run warning or error on line --- number *line* in the message buffer. --- If *line* is `nil`, jumps to the next or previous warning or error, depending --- on boolean *next*. Displays an annotation with the warning or error message --- if possible. --- @param line The line number in the message buffer that contains the +-- number *line_num* in the message buffer. +-- If *line_num* is `nil`, jumps to the next or previous warning or error, +-- depending on boolean *next*. Displays an annotation with the warning or error +-- message if possible. +-- @param line_num The line number in the message buffer that contains the -- compile/run warning or error to go to. -- @param next Optional flag indicating whether to go to the next recognized --- warning/error or the previous one. Only applicable when *line* is `nil`. +-- warning/error or the previous one. Only applicable when *line_num* is +-- `nil`. -- @see error_patterns -- @name goto_error -function M.goto_error(line, next) - if not cwd then return end -- no previously run command +function M.goto_error(line_num, next) local msg_view, msg_buf = nil, nil for i = 1, #_VIEWS do if is_msg_buf(_VIEWS[i].buffer) then msg_view = _VIEWS[i] break end @@ -373,38 +373,39 @@ function M.goto_error(line, next) if not msg_view and not msg_buf then return end if msg_view then ui.goto_view(msg_view) else view:goto_buffer(msg_buf) end - -- If no line was given, find the next warning or error marker. - if not assert_type(line, 'number/nil', 1) and next ~= nil then + -- If no line number was given, find the next warning or error marker. + if not assert_type(line_num, 'number/nil', 1) and next ~= nil then local f = next and buffer.marker_next or buffer.marker_previous - line = buffer:line_from_position(buffer.current_pos) + line_num = buffer:line_from_position(buffer.current_pos) local wrapped = false ::retry:: - local wline = f(buffer, line + (next and 1 or -1), 1 << M.MARK_WARNING) - local eline = f(buffer, line + (next and 1 or -1), 1 << M.MARK_ERROR) + local wline = f(buffer, line_num + (next and 1 or -1), 1 << M.MARK_WARNING) + local eline = f(buffer, line_num + (next and 1 or -1), 1 << M.MARK_ERROR) if wline == -1 and eline == -1 then wline = f(buffer, next and 0 or buffer.line_count, 1 << M.MARK_WARNING) eline = f(buffer, next and 0 or buffer.line_count, 1 << M.MARK_ERROR) elseif wline == -1 or eline == -1 then if wline == -1 then wline = eline else eline = wline end end - line = (next and math.min or math.max)(wline, eline) - if line == -1 and not wrapped then - line = next and 0 or buffer.line_count + line_num = (next and math.min or math.max)(wline, eline) + if line_num == -1 and not wrapped then + line_num = next and 0 or buffer.line_count wrapped = true goto retry end end - buffer:goto_line(line) -- Goto the warning or error and show an annotation. - local line = buffer:get_line(line):match('^[^\r\n]*') + local line = buffer:get_line(line_num):match('^[^\r\n]*') local detail = scan_for_error(line:iconv(_CHARSET, 'UTF-8')) if not detail then return end + buffer:goto_line(line_num) textadept.editing.select_line() - if not detail.filename:find(not WIN32 and '^/' or '^%a:[/\\]') then + if not detail.filename:find(not WIN32 and '^/' or '^%a:[/\\]') and cwd then detail.filename = cwd .. (not WIN32 and '/' or '\\') .. detail.filename end - ui.goto_file(detail.filename, true, preferred_view, true) + local sloppy = not detail.filename:find(not WIN32 and '^/' or '^%a:[/\\]') + ui.goto_file(detail.filename, true, preferred_view, sloppy) textadept.editing.goto_line(detail.line - 1) if detail.column then buffer:goto_pos(buffer:find_column(detail.line - 1, detail.column - 1)) diff --git a/test/test.lua b/test/test.lua index af0ec708..fc0d9e27 100644 --- a/test/test.lua +++ b/test/test.lua @@ -2282,6 +2282,16 @@ function test_run_build() end unstable(test_run_build) +function test_run_goto_internal_lua_error() + xpcall(error, function(message) events.emit(events.ERROR, debug.traceback(message)) end, 'internal error', 2) + if #_VIEWS > 1 then view:unsplit() end + textadept.run.goto_error(LINE(1)) + assert(buffer.filename:find('/test/test%.lua$'), 'did not detect internal Lua error') + view:unsplit() + io.close_buffer() + io.close_buffer() +end + -- TODO: test textadept.run.run_in_background function test_session_save() @@ -2736,6 +2746,8 @@ function test_lexer_api() assert_raises(function() lexer.line_from_position = nil end, 'read-only') end +-- TODO: test init.lua's buffer settings + -------------------------------------------------------------------------------- assert(not WIN32 and not OSX, 'Test suite currently only runs on Linux') |