Language debugging support for Textadept.
All this module does is emit debugger events. Submodules that implement debuggers listen for these events and act on them.
Install this module by copying it into your ~/.textadept/modules/ directory or Textadept's modules/ directory, and then putting the following in your ~/.textadept/init.lua:
require('debugger')
There will be a top-level "Debug" menu.
Currently, only debugging Lua scripts should work out of the box, provided LuaSocket is installed for the external Lua interpreter invoked. (This module has its own copy of LuaSocket that is used by Textadept's internal Lua state only.) Running "Debug > Go" will run the current script up to the first breakpoint, while "Debug > Step Over" and "Debug > Step Into" will pause after the current script's first statement.
Project-specific debugging is configured using the debugger.project_commands
table. For
example, in order to use this module to debug a C program via GDB:
local debugger = require('debugger')
debugger.project_commands['/path/to/project'] = function()
return 'c', '/path/to/exe', 'command line args'
end
Textadept can debug another instance of itself.
Releases include binaries, so building this modules should not be necessary. If you want to build manually, use CMake. For example:
cmake -S . -B build_dir
cmake --build build_dir
cmake --install build_dir
Windows and Linux | macOS | Terminal | Command |
---|---|---|---|
Debug | |||
F5 | F5 | F5 | Start debugging |
F10 | F10 | F10 | Step over |
F11 | F11 | F11 | Step into |
Shift+F11 | ⇧F11 | S-F11 | Step out |
Shift+F5 | ⇧F5 | S-F5 | Stop debugging |
Alt+= | ⌘= | M-= | Inspect variable |
Alt++ | ⌘+ | M-+ | Evaluate expression... |
The color of breakpoint markers.
Emitted when a breakpoint is added. This is only emitted when the debugger is running and paused (e.g. at a breakpoint). Breakpoints added while the debugger is not running are queued up until the debugger starts. Arguments:
- lang: The lexer name of the language to add a breakpoint for.
- filename: The filename to add a breakpoint in.
- line: The 1-based line number to break on.
Emitted when a breakpoint is removed. This is only emitted when the debugger is running and paused (e.g. at a breakpoint). Arguments:
- lang: The lexer name of the language being debugged.
- filename: The filename to remove a breakpoint from.
- line: The 1-based line number to stop breaking on.
Emitted when a debugger command should be run. This is only emitted when the debugger is running and paused (e.g. at a breakpoint). Arguments:
- lang: The lexer name of the language being debugged.
- text: The text of the command to run.
Emitted when a execution should be continued. This is only emitted when the debugger is running and paused (e.g. at a breakpoint). Arguments:
- lang: The lexer name of the language being debugged.
- ...: Any arguments passed to
debugger.continue()
.
Emitted when a symbol should be inspected.
Debuggers typically show a symbol's value in a calltip via view:call_tip_show()
.
This is only emitted when the debugger is running and paused (e.g. at a breakpoint).
Arguments:
- lang: The lexer name of the language being debugged.
- position: The buffer position of the symbol to inspect. The debugger is responsible for identifying the symbol's name, as symbol characters vary from language to language.
Emitted when execution should be paused.
This is only emitted when the debugger is running and executing (e.g. not at a breakpoint).
If a listener pauses the debugger, it must return true
. Otherwise, it is assumed that
debugger could not be paused. Listeners must not return false
(they can return nil
).
Arguments:
- lang: The lexer name of the language being debugged.
- ...: Any arguments passed to
debugger.pause()
.
Emitted when execution should restart from the beginning. This is only emitted when the debugger is running. Arguments:
- lang: The lexer name of the language being debugged.
- ...: Any arguments passed to
debugger.restart()
.
Emitted when a stack frame should be switched to. This is only emitted when the debugger is running and paused (e.g. at a breakpoint). Arguments:
- lang: The lexer name of the language being debugged.
- level: The 1-based stack level number to switch to. This value depends on the stack
levels given to
debugger.update_state()
.
Emitted when a debugger should be started.
The debugger should not start executing yet, as there will likely be incoming breakpoint
and watch add events. Subsequent events will instruct the debugger to begin executing.
If a listener creates a debugger, it must return true
. Otherwise, it is assumed that no
debugger was created and subsequent debugger functions will not work. Listeners must not
return false
(they can return nil
).
Arguments:
- lang: The lexer name of the language to start debugging.
- ...: Any arguments passed to
debugger.start()
.
Emitted when execution should continue by one line, stepping into functions. This is only emitted when the debugger is running and paused (e.g. at a breakpoint). Arguments:
- lang: The lexer name of the language being debugged.
- ...: Any arguments passed to
debugger.step_into()
.
Emitted when execution should continue, stepping out of the current function. This is only emitted when the debugger is running and paused (e.g. at a breakpoint). Arguments:
- lang: The lexer name of the language being debugged.
- ...: Any arguments passed to
debugger.step_out()
.
Emitted when execution should continue by one line, stepping over functions. This is only emitted when the debugger is running and paused (e.g. at a breakpoint). Arguments:
- lang: The lexer name of the language being debugged.
- ...: Any arguments passed to
debugger.step_over()
.
Emitted when a debugger should be stopped. This is only emitted when the debugger is running. Arguments:
- lang: The lexer name of the language to stop debugging.
- ...: Any arguments passed to
debugger.stop()
.
Emitted when a watch is added. This is only emitted when the debugger is running and paused (e.g. at a breakpoint). Watches added while the debugger is not running are queued up until the debugger starts. Arguments:
- lang: The lexer name of the language to add a watch for.
- expr: The expression or variable to watch, depending on what the debugger supports.
- id: The expression's ID number.
- no_break: Whether the debugger should not break when the watch's value changes.
Emitted when a watch is removed. This is only emitted when the debugger is running and paused (e.g. at a breakpoint). Arguments:
- lang: The lexer name of the language being debugged.
- expr: The expression to stop watching.
- id: The expression's ID number.
Map of lexer languages to debugger modules. This is for debugger modules that support more than one language (e.g. the gdb module supports 'c' and 'cpp'). Otherwise, a debugger module should be named after the lexer language it debugs and an alias is not necessary.
Fields:
c
:cpp
:
Map of project root directories to functions that return the language of the debugger to
start followed by the arguments to pass to that debugger's events.DEBUGGER_START
handler.
The LuaSocket module.
Whether or not to use debug status buffers like variables, call stack, etc.
Updates the buffer containing the call stack.
Continue debugger execution unless the debugger is already executing (e.g. not at a
breakpoint).
If no debugger is running, starts one, then continues execution.
Emits events.DEBUGGER_CONTINUE
, passing along any arguments given.
Parameters:
- lang: Optional lexer name of the language to continue executing. The default value is the name of the current lexer.
Evaluates string text in the current debugger context if the debugger is paused. The result (if any) is not returned, but likely printed to the message buffer.
Parameters:
- text: String text to evaluate.
Inspects the symbol (if any) at buffer position position, unless the debugger is executing
(e.g. not at a breakpoint).
Emits events.DEBUGGER_INSPECT
.
Parameters:
- position: The buffer position to inspect.
Pause debugger execution unless the debugger is already paused (e.g. at a breakpoint).
Emits events.DEBUGGER_PAUSE
, passing along any additional arguments given.
Parameters:
- ...:
Removes a breakpoint from line number line in file file, or prompts the user for a
breakpoint(s) to remove.
Emits events.DEBUGGER_BREAKPOINT_REMOVED
if the debugger is running.
If the debugger is executing (e.g. not at a breakpoint), assumes a breakpoint cannot be
removed and shows an error message.
Parameters:
- file: Optional filename of the breakpoint to remove.
- line: Optional 1-based line number of the breakpoint to remove.
Stops watching the expression identified by id, or the expression selected by the user.
Emits events.DEBUGGER_WATCH_REMOVED
if the debugger is running.
If the debugger is executing (e.g. not at a breakpoint), assumes a watch cannot be set and
shows an error message.
Parameters:
- id: ID number of the expression, as given in the
events.DEBUGGER_WATCH_ADDED
event.
Restarts debugger execution from the beginning.
Emits events.DEBUGGER_PAUSE
, passing along any additional arguments given.
Parameters:
- ...:
Prompts the user to select a stack frame to switch to from the current debugger call stack,
unless the debugger is executing (e.g. not at a breakpoint).
Emits events.DEBUGGER_SET_FRAME
.
Parameters:
- level: Optional 1-based stack frame index to switch to.
Watches string expression expr for changes and breaks on each change unless no_break is
true
.
Emits events.DEBUGGER_WATCH_ADDED
if the debugger is running, or queues up the event to
run in debugger.start()
.
If the debugger is executing (e.g. not at a breakpoint), assumes a watch cannot be set and
shows an error message.
Parameters:
- expr: String expression to watch.
- no_break: Whether to just watch the expression and not break on changes. The default
value is
false
.
Starts a debugger and adds any queued breakpoints and watches.
Emits events.DEBUGGER_START
, passing along any arguments given. If a debugger cannot be
started, the event handler should throw an error.
This only starts a debugger. debugger.continue()
, debugger.step_into()
, or
debugger.step_over()
should be called next to begin debugging.
Parameters:
- lang: Optional lexer name of the language to start debugging. The default value is the name of the current lexer.
Return:
- whether or not a debugger was started
Continue debugger execution by one line, stepping into functions, unless the debugger is
already executing (e.g. not at a breakpoint).
If no debugger is running, starts one, then steps.
Emits events.DEBUGGER_STEP_INTO
, passing along any arguments given.
Parameters:
- ...:
Continue debugger execution, stepping out of the current function, unless the debugger is
already executing (e.g. not at a breakpoint).
Emits events.DEBUGGER_STEP_OUT
, passing along any additional arguments given.
Parameters:
- ...:
Continue debugger execution by one line, stepping over functions, unless the debugger is
already executing (e.g. not at a breakpoint).
If no debugger is running, starts one, then steps.
Emits events.DEBUGGER_STEP_OVER
, passing along any arguments given.
Parameters:
- ...:
Stops debugging.
Debuggers should call this function when finished.
Emits events.DEBUGGER_STOP
, passing along any arguments given.
Parameters:
- lang: Optional lexer name of the language to stop debugging. The default value is the name of the current lexer.
Toggles a breakpoint on line number line in file file, or the current line in the
current file.
May emit events.DEBUGGER_BREAKPOINT_ADDED
and events.DEBUGGER_BREAKPOINT_REMOVED
depending
on circumstance.
May show an error message if the debugger is executing (e.g. not at a breakpoint).
Parameters:
- file: Optional filename of the breakpoint to toggle.
- line: Optional 1-based line number of the breakpoint to toggle.
Updates the running debugger's state and marks the current debug line.
Debuggers need to call this function every time their state changes, typically during
DEBUGGER_*
events.
Parameters:
- state: A table with four fields:
file
,line
,call_stack
, andvariables
.file
andline
indicate the debugger's current position.call_stack
is a list of stack frames and apos
field whose value is the 1-based index of the current frame.variables
is an optional map of known variables and watches to their values. The debugger can choose what kind of variables make sense to put in the map.
Updates the buffer containing variables and watches in the current stack frame. Any variables/watches that have changed since the last updated are marked.