Added documentation
This commit is contained in:
parent
663c38e1a6
commit
b35eb96727
@ -1,3 +1,4 @@
|
||||
"Read and return all new lines from a Vebugger pipe object.
|
||||
function! s:readNewLinesFromPipe(pipeObject)
|
||||
"read
|
||||
let l:text=a:pipeObject.pipe.read(1000,0)
|
||||
@ -19,6 +20,7 @@ endfunction
|
||||
|
||||
let s:f_debugger={}
|
||||
|
||||
"Terminate the debugger
|
||||
function! s:f_debugger.kill() dict
|
||||
if self.shell.is_valid
|
||||
call self.addLineToTerminal('','== DEBUGGER TERMINATED ==')
|
||||
@ -32,10 +34,12 @@ function! s:f_debugger.kill() dict
|
||||
endif
|
||||
endfunction
|
||||
|
||||
"Write a line to the debugger's interactive shell
|
||||
function! s:f_debugger.writeLine(line) dict
|
||||
call self.shell.stdin.write(a:line."\n")
|
||||
endfunction
|
||||
|
||||
"Check for new lines from the debugger's interactive shell and handle them
|
||||
function! s:f_debugger.invokeReading() dict
|
||||
let l:newLines={}
|
||||
for l:k in keys(self.pipes)
|
||||
@ -58,6 +62,7 @@ function! s:f_debugger.invokeReading() dict
|
||||
call feedkeys("f\e") " Make sure the CursorHold event is refired even if the user does nothing
|
||||
endfunction
|
||||
|
||||
"Handle a single line from the debugger's interactive shell
|
||||
function! s:f_debugger.handleLine(pipeName,line) dict
|
||||
call self.addLineToTerminal(a:pipeName,a:line)
|
||||
|
||||
@ -74,6 +79,7 @@ function! s:f_debugger.handleLine(pipeName,line) dict
|
||||
call self.performWriteActions()
|
||||
endfunction
|
||||
|
||||
"Perform all write actions
|
||||
function! s:f_debugger.performWriteActions() dict
|
||||
for l:namespace in keys(self.writeActions)
|
||||
let l:handlers=get(self.writeHandlers,l:namespace)
|
||||
@ -90,6 +96,8 @@ function! s:f_debugger.performWriteActions() dict
|
||||
call self.generateWriteActionsFromTemplate()
|
||||
endfunction
|
||||
|
||||
"Show the terminal buffer that gets it's content from the debugger's
|
||||
"interactive shell
|
||||
function! s:f_debugger.showTerminalBuffer() dict
|
||||
if has_key(self,'terminalBuffer')
|
||||
if -1<bufwinnr(self.terminalBuffer)
|
||||
@ -104,6 +112,7 @@ function! s:f_debugger.showTerminalBuffer() dict
|
||||
wincmd p
|
||||
endfunction
|
||||
|
||||
"Close the terminal buffer
|
||||
function! s:f_debugger.closeTerminalBuffer() dict
|
||||
if has_key(self,'terminalBuffer')
|
||||
if -1<bufwinnr(self.terminalBuffer)
|
||||
@ -115,6 +124,7 @@ function! s:f_debugger.closeTerminalBuffer() dict
|
||||
endif
|
||||
endfunction
|
||||
|
||||
"Check if the terminal buffer associated with this debugger is currently open
|
||||
function! s:f_debugger.isTerminalBufferOpen() dict
|
||||
if has_key(self,'terminalBuffer')
|
||||
if -1<bufwinnr(self.terminalBuffer)
|
||||
@ -124,6 +134,7 @@ function! s:f_debugger.isTerminalBufferOpen() dict
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
"Turn on and off the terminal buffer associated with this debugger
|
||||
function! s:f_debugger.toggleTerminalBuffer() dict
|
||||
if self.isTerminalBufferOpen()
|
||||
call self.closeTerminalBuffer()
|
||||
@ -132,6 +143,7 @@ function! s:f_debugger.toggleTerminalBuffer() dict
|
||||
endif
|
||||
endfunction
|
||||
|
||||
"Write a line to the terminal buffer. This function does not process the line
|
||||
function! s:f_debugger.addLineToTerminal(pipeName,line) dict
|
||||
if has_key(self,'terminalBuffer')
|
||||
let l:bufwin=bufwinnr(self.terminalBuffer)
|
||||
@ -150,6 +162,7 @@ function! s:f_debugger.addLineToTerminal(pipeName,line) dict
|
||||
endif
|
||||
endfunction
|
||||
|
||||
"Add an handler to a handler list
|
||||
function! s:addHandler(list,handler)
|
||||
if type(a:handler) == type({})
|
||||
call add(a:list,a:handler)
|
||||
@ -158,6 +171,7 @@ function! s:addHandler(list,handler)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
"Set a named handler in a handler dictionary
|
||||
function! s:setHandler(dict,namespace,name,handler)
|
||||
if !has_key(a:dict,a:namespace)
|
||||
let a:dict[a:namespace]={}
|
||||
@ -169,34 +183,51 @@ function! s:setHandler(dict,namespace,name,handler)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
"Add a read handler. Read handlers process output from the debugger's
|
||||
"interactive shell and modify read result objects with structured information
|
||||
"parsed from those lines
|
||||
function! s:f_debugger.addReadHandler(handler) dict
|
||||
call s:addHandler(self.readHandlers,a:handler)
|
||||
endfunction
|
||||
|
||||
"Add a think handler. Think handlers are debugger agnostic - they look at
|
||||
"read result objects and decide what to do with them.
|
||||
function! s:f_debugger.addThinkHandler(handler) dict
|
||||
call s:addHandler(self.thinkHandlers,a:handler)
|
||||
endfunction
|
||||
|
||||
"Set a write handler. Write handlers get write action objects and convert them
|
||||
"to debugger specific commands. A write action can only handle a write action
|
||||
"of the namespace and name it is registered for, to prevent the same write
|
||||
"action handled by multiple write handlers.
|
||||
function! s:f_debugger.setWriteHandler(namespace,name,handler) dict
|
||||
call s:setHandler(self.writeHandlers,a:namespace,a:name,a:handler)
|
||||
endfunction
|
||||
|
||||
"Add a close handler. Close handlers are called when the debugger is closed to
|
||||
"tidy things up.
|
||||
function! s:f_debugger.addCloseHandler(handler) dict
|
||||
call s:addHandler(self.closeHandlers,a:handler)
|
||||
endfunction
|
||||
|
||||
"Create an empty write action that follows the write actions template. That
|
||||
"action will later be filled by think handlers or from outside.
|
||||
function! s:f_debugger.generateWriteActionsFromTemplate() dict
|
||||
let self.writeActions=deepcopy(self.writeActionsTemplate)
|
||||
endfunction
|
||||
|
||||
"Set a write action of a specific namespace and name, for write actions that
|
||||
"do not support a list
|
||||
function! s:f_debugger.setWriteAction(namespace,name,value) dict
|
||||
let self.writeActions[a:namespace][a:name]=a:value
|
||||
endfunction
|
||||
|
||||
"Add a write action of a specific namespace and name, for write actions that supports a list
|
||||
function! s:f_debugger.addWriteAction(namespace,name,value) dict
|
||||
call add(self.writeActions[a:namespace][a:name],a:value)
|
||||
endfunction
|
||||
|
||||
"Create a bare debugger object from a raw shell line
|
||||
function! vebugger#createDebugger(command)
|
||||
|
||||
let l:debugger=deepcopy(s:f_debugger)
|
||||
@ -225,8 +256,8 @@ function! vebugger#createDebugger(command)
|
||||
return l:debugger
|
||||
endfunction
|
||||
|
||||
" all the functions here are currently just for testing:
|
||||
|
||||
"Create a debugger and set it as the currently active debugger
|
||||
function! vebugger#startDebugger(command)
|
||||
call vebugger#killDebugger()
|
||||
|
||||
@ -240,6 +271,7 @@ function! vebugger#startDebugger(command)
|
||||
return s:debugger
|
||||
endfunction
|
||||
|
||||
"Terminate the currently active debugger
|
||||
function! vebugger#killDebugger()
|
||||
augroup vebugger_shell
|
||||
autocmd!
|
||||
@ -251,24 +283,28 @@ function! vebugger#killDebugger()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
"Write a line to the currently active debugger
|
||||
function! vebugger#writeLine(line)
|
||||
if exists('s:debugger')
|
||||
call s:debugger.writeLine(a:line)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
"Invoke reading for the currently active debugger
|
||||
function! vebugger#invokeReading()
|
||||
if exists('s:debugger')
|
||||
call s:debugger.invokeReading()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
"Toggle the terminal buffer for the currently active debugger
|
||||
function! vebugger#toggleTerminalBuffer()
|
||||
if exists('s:debugger')
|
||||
call s:debugger.toggleTerminalBuffer()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
"Fetch the currently active debugger object
|
||||
function! vebugger#getActiveDebugger()
|
||||
if exists('s:debugger')
|
||||
return s:debugger
|
||||
@ -277,29 +313,34 @@ function! vebugger#getActiveDebugger()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
"Set a write action for the currently active debugger
|
||||
function! vebugger#setWriteAction(namespace,name,value)
|
||||
if exists('s:debugger')
|
||||
call s:debugger.setWriteAction(a:namespace,a:name,a:value)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
"Add a write action to the currently active debugger
|
||||
function! vebugger#addWriteAction(namespace,name,value)
|
||||
if exists('s:debugger')
|
||||
call s:debugger.addWriteAction(a:namespace,a:name,a:value)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
"Force performing all the write of the currently active debugger
|
||||
function! vebugger#performWriteActions()
|
||||
if exists('s:debugger')
|
||||
call s:debugger.performWriteActions()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
"Set a write action for the currently active debugger and perform it
|
||||
function! vebugger#setWriteActionAndPerform(namespace,name,value)
|
||||
call vebugger#setWriteAction(a:namespace,a:name,a:value)
|
||||
call vebugger#performWriteActions()
|
||||
endfunction
|
||||
|
||||
"Add a write action to the currently active debugger and perform it
|
||||
function! vebugger#addWriteActionAndPerform(namespace,name,value)
|
||||
call vebugger#addWriteAction(a:namespace,a:name,a:value)
|
||||
call vebugger#performWriteActions()
|
||||
|
@ -1,5 +1,6 @@
|
||||
let g:vebugger_breakpoints=[]
|
||||
|
||||
"Initialize the std part of the debugger's state
|
||||
function! vebugger#std#setStandardState(debugger)
|
||||
let a:debugger.state.std={
|
||||
\'config':{
|
||||
@ -9,6 +10,7 @@ function! vebugger#std#setStandardState(debugger)
|
||||
\'evaluateExpressions':[]}
|
||||
endfunction
|
||||
|
||||
"Initialize the std part of the debugger's read result template
|
||||
function! vebugger#std#setStandardReadResultTemplate(debugger)
|
||||
let a:debugger.readResultTemplate.std={
|
||||
\'programOutput':{},
|
||||
@ -19,6 +21,7 @@ function! vebugger#std#setStandardReadResultTemplate(debugger)
|
||||
\'exception':{}}
|
||||
endfunction
|
||||
|
||||
"Initialize the std part of the debugger's write actions template
|
||||
function! vebugger#std#setStandardWriteactionsTemplate(debugger)
|
||||
let a:debugger.writeActionsTemplate.std={
|
||||
\'flow':'',
|
||||
@ -29,24 +32,28 @@ function! vebugger#std#setStandardWriteactionsTemplate(debugger)
|
||||
\'closeDebugger':''}
|
||||
endfunction
|
||||
|
||||
"Adds the std_ functions to the debugger object
|
||||
function! vebugger#std#addStandardFunctions(debugger)
|
||||
for l:k in keys(s:standardFunctions)
|
||||
let a:debugger['std_'.l:k]=s:standardFunctions[l:k]
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
"Add the standard think handlers to the debugger
|
||||
function! vebugger#std#addStandardThinkHandlers(debugger)
|
||||
for l:ThinkHandler in values(s:standardThinkHandlers)
|
||||
call a:debugger.addThinkHandler(l:ThinkHandler)
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
"Add the standard close handlers to the debugger
|
||||
function! vebugger#std#addStandardCloseHandlers(debugger)
|
||||
for l:CloseHandler in values(s:standardCloseHandlers)
|
||||
call a:debugger.addCloseHandler(l:CloseHandler)
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
"Performs the standard initialization of the debugger object
|
||||
function! vebugger#std#standardInit(debugger)
|
||||
call vebugger#std#setStandardState(a:debugger)
|
||||
call vebugger#std#setStandardReadResultTemplate(a:debugger)
|
||||
@ -56,6 +63,7 @@ function! vebugger#std#standardInit(debugger)
|
||||
call vebugger#std#addStandardCloseHandlers(a:debugger)
|
||||
endfunction
|
||||
|
||||
"Start a debugger with the std settings
|
||||
function! vebugger#std#startDebugger(command)
|
||||
let l:debugger=vebugger#startDebugger(a:command)
|
||||
|
||||
@ -65,6 +73,10 @@ function! vebugger#std#startDebugger(command)
|
||||
endfunction
|
||||
|
||||
|
||||
"Opens the shell buffer for a debugger. The shell buffer displays the output
|
||||
"of the debugged program, and when it's closed the debugger gets terminated.
|
||||
"Shell buffers should not be used when attaching a debugger to a running
|
||||
"process.
|
||||
function! vebugger#std#openShellBuffer(debugger)
|
||||
if has_key(a:debugger,'shellBuffer')
|
||||
if -1<bufwinnr(a:debugger.shellBuffer)
|
||||
@ -90,6 +102,8 @@ function! vebugger#std#openShellBuffer(debugger)
|
||||
endfunction
|
||||
|
||||
let s:standardFunctions={}
|
||||
|
||||
"Write a line to the shell buffer
|
||||
function! s:standardFunctions.addLineToShellBuffer(line) dict
|
||||
if has_key(self,'shellBuffer')
|
||||
let l:bufwin=bufwinnr(self.shellBuffer)
|
||||
@ -102,6 +116,7 @@ function! s:standardFunctions.addLineToShellBuffer(line) dict
|
||||
endif
|
||||
endfunction
|
||||
|
||||
"Set the write actions to add all breakpoints registered in Vebugger
|
||||
function! s:standardFunctions.addAllBreakpointActions(breakpoints) dict
|
||||
for l:breakpoint in a:breakpoints
|
||||
call self.addWriteAction('std','breakpoints',{
|
||||
@ -111,6 +126,7 @@ function! s:standardFunctions.addAllBreakpointActions(breakpoints) dict
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
"Make the debugger evaluate an expression
|
||||
function! s:standardFunctions.eval(expression) dict
|
||||
if -1==index(self.state.std.evaluateExpressions,a:expression)
|
||||
call add(self.state.std.evaluateExpressions,a:expression)
|
||||
@ -120,14 +136,17 @@ function! s:standardFunctions.eval(expression) dict
|
||||
call self.performWriteActions()
|
||||
endfunction
|
||||
|
||||
"Executes a statement in the debugged program
|
||||
"Execute a statement in the debugged program
|
||||
function! s:standardFunctions.execute(statement) dict
|
||||
call self.addWriteAction('std','executeStatements',{
|
||||
\'statement':(a:statement)})
|
||||
call self.performWriteActions()
|
||||
endfunction
|
||||
|
||||
|
||||
let s:standardThinkHandlers={}
|
||||
|
||||
"Update the shell buffer with program output
|
||||
function! s:standardThinkHandlers.addProgramOutputToShell(readResult,debugger) dict
|
||||
let l:programOutput=a:readResult.std.programOutput
|
||||
if !empty(l:programOutput)
|
||||
@ -135,6 +154,7 @@ function! s:standardThinkHandlers.addProgramOutputToShell(readResult,debugger) d
|
||||
endif
|
||||
endfunction
|
||||
|
||||
"Make Vim jump to the currently executed line
|
||||
function! s:standardThinkHandlers.moveToCurrentLine(readResult,debugger) dict
|
||||
if !empty(a:readResult.std.location)
|
||||
if !empty(a:debugger.state.std.config.externalFileStop_flowCommand) " Do we need to worry about stopping at external files?
|
||||
@ -157,6 +177,7 @@ function! s:standardThinkHandlers.moveToCurrentLine(readResult,debugger) dict
|
||||
endif
|
||||
endfunction
|
||||
|
||||
"Update the call stack
|
||||
function! s:standardThinkHandlers.updateCallStack(readResult,debugger) dict
|
||||
let l:callstack=a:readResult.std.callstack
|
||||
if !empty(l:callstack)
|
||||
@ -172,6 +193,7 @@ function! s:standardThinkHandlers.updateCallStack(readResult,debugger) dict
|
||||
endif
|
||||
endfunction
|
||||
|
||||
"Print an expression that it's evaluation was previously requested
|
||||
function! s:standardThinkHandlers.printEvaluatedExpression(readResult,debugger) dict
|
||||
let l:evaluatedExpression=a:readResult.std.evaluatedExpression
|
||||
if !empty(l:evaluatedExpression)
|
||||
@ -189,12 +211,15 @@ function! s:standardThinkHandlers.printEvaluatedExpression(readResult,debugger)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
"Close the debugger when the program is finished but the debugger wasn't
|
||||
"closed automatically
|
||||
function! s:standardThinkHandlers.closeDebuggerWhenProgramFinishes(readResult,debugger) dict
|
||||
if !empty(a:readResult.std.programFinish)
|
||||
call a:debugger.setWriteAction('std','closeDebugger','close')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
"Print an exception message
|
||||
function! s:standardThinkHandlers.printException(readResult,debugger) dict
|
||||
if !empty(a:readResult.std.exception)
|
||||
echohl WarningMsg
|
||||
@ -204,6 +229,7 @@ function! s:standardThinkHandlers.printException(readResult,debugger) dict
|
||||
endfunction
|
||||
|
||||
let s:standardCloseHandlers={}
|
||||
"Remove the currently executed line when a debugger is closed
|
||||
function! s:standardCloseHandlers.removeCurrentMarker(debugger) dict
|
||||
let a:debugger.state.std.location={}
|
||||
sign unplace 1
|
||||
@ -211,6 +237,8 @@ endfunction
|
||||
|
||||
sign define vebugger_current text=->
|
||||
sign define vebugger_breakpoint text=** linehl=ColorColumn
|
||||
|
||||
"Update all the marks(currently executed line and breakpoints) for a file
|
||||
function! vebugger#std#updateMarksForFile(state,filename)
|
||||
let l:filename=fnamemodify(a:filename,":p")
|
||||
if bufexists(l:filename)
|
||||
@ -232,6 +260,7 @@ function! vebugger#std#updateMarksForFile(state,filename)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
"Toggle a breakpoint on and off
|
||||
function! vebugger#std#toggleBreakpoint(file,line)
|
||||
let l:debugger=vebugger#getActiveDebugger()
|
||||
let l:debuggerState=empty(l:debugger)
|
||||
@ -257,6 +286,7 @@ function! vebugger#std#toggleBreakpoint(file,line)
|
||||
call vebugger#std#updateMarksForFile(l:debuggerState,a:file)
|
||||
endfunction
|
||||
|
||||
"Clear all breakpoints
|
||||
function! vebugger#std#clearBreakpoints()
|
||||
let l:debugger=vebugger#getActiveDebugger()
|
||||
let l:debuggerState=empty(l:debugger) ? {} : l:debugger.state
|
||||
@ -274,6 +304,7 @@ function! vebugger#std#clearBreakpoints()
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
"Ask the active debugger to evaluate an expression
|
||||
function! vebugger#std#eval(expression)
|
||||
let l:debugger=vebugger#getActiveDebugger()
|
||||
if !empty(l:debugger) && !empty(l:debugger.std_eval)
|
||||
@ -281,6 +312,7 @@ function! vebugger#std#eval(expression)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
"Ask the active debugger to execute a statement
|
||||
function! vebugger#std#execute(statement)
|
||||
let l:debugger=vebugger#getActiveDebugger()
|
||||
if !empty(l:debugger) && !empty(l:debugger.std_eval)
|
||||
|
@ -1,6 +1,7 @@
|
||||
|
||||
"Shamefully stolen from http://stackoverflow.com/a/6271254/794380
|
||||
"Returns the visually selected text
|
||||
function! vebugger#util#get_visual_selection()
|
||||
"Shamefully stolen from http://stackoverflow.com/a/6271254/794380
|
||||
" Why is this not a built-in Vim script function?!
|
||||
let [lnum1, col1] = getpos("'<")[1:2]
|
||||
let [lnum2, col2] = getpos("'>")[1:2]
|
||||
@ -10,6 +11,8 @@ function! vebugger#util#get_visual_selection()
|
||||
return join(lines, "\n")
|
||||
endfunction
|
||||
|
||||
"Prompts the user with a filtered list of process, and returns the process id
|
||||
"the user selects
|
||||
function! vebugger#util#selectProcessOfFile(ofFile)
|
||||
let l:fileName=fnamemodify(a:ofFile,':t')
|
||||
let l:resultLines=split(vimproc#system('ps -o pid,user,comm,start,state,tt -C '.fnameescape(l:fileName)),'\r\n\|\n\|\r')
|
||||
@ -32,6 +35,8 @@ function! vebugger#util#selectProcessOfFile(ofFile)
|
||||
return str2nr(matchlist(l:chosenLine,'\v^\s*\d+\)\s+(\d+)')[1])
|
||||
endfunction
|
||||
|
||||
"Escape args(from a debugger's extra arguments) as a command line arguments
|
||||
"string
|
||||
function! vebugger#util#commandLineArgsForProgram(debuggerArgs)
|
||||
if has_key(a:debuggerArgs,'args')
|
||||
if type(a:debuggerArgs.args)==type([])
|
||||
@ -44,6 +49,7 @@ function! vebugger#util#commandLineArgsForProgram(debuggerArgs)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
"Escape a single argument for the command line
|
||||
function! s:argEscape(arg)
|
||||
if has('win32')
|
||||
return shellescape(a:arg)
|
||||
|
200
doc/vebugger.txt
Normal file
200
doc/vebugger.txt
Normal file
@ -0,0 +1,200 @@
|
||||
*vebugger.txt*
|
||||
|
||||
|
||||
Author: Idan Arye <https://github.com/someboddy/>
|
||||
License: Same terms as Vim itself (see |license|)
|
||||
|
||||
Version: 1.0.0
|
||||
|
||||
INTRODUCTION *vebugger*
|
||||
|
||||
Vebugger is yet another debugger frontend plugin for Vim, created because I
|
||||
wasn't happy with the other debugger plugins I found. Vebugger currently
|
||||
supports:
|
||||
* Tracking the currently executed command in the source code
|
||||
* Debugger flow commands - step-in, set-over, set-out and continue
|
||||
* Breakpoints management
|
||||
* Evaluating expressions in the current executed scope
|
||||
* Messing with the program's state(changing values, calling functions)
|
||||
|
||||
Vebugger is built as a generic framework for building frontends for
|
||||
interactive shell debugger, and comes with implementations for:
|
||||
* GDB - doesn't need introdcution...
|
||||
* JDB - a Java debugger
|
||||
* PDB - a Python module for debugging Python scripts
|
||||
* RDebug - a Ruby command line option for debugging Ruby scripts
|
||||
Other implementations can be added with ease.
|
||||
|
||||
Vebugger is built under the following assumptions:
|
||||
* While command line debuggers share enough in common to make the creation
|
||||
of such a framework as Vebugger possible, the differences between them are
|
||||
too great to be expressed with regular expression. To support them all at
|
||||
least some code has to be written.
|
||||
* Unlike IDE users, Vim users tend to understand the tools the operate behind
|
||||
the scenes. While Vebugger automates the common features, it allows you to
|
||||
"open the hood" and interact with the debugger's shell directly so you could
|
||||
utilize the full power of your debugger.
|
||||
* I have no intention to aim for the lowest common denominator. If one
|
||||
debugger has a cool feature I want to support, I'll implement it even if the
|
||||
other debuggers don't have it.
|
||||
|
||||
|
||||
CONFIGURATION *vebugger-configuration*
|
||||
|
||||
If you want to use the keymaps, you need to choose a leader for them by
|
||||
setting *g:vebugger_leader* in your vimrc.
|
||||
|
||||
Example: >
|
||||
let g:vebugger_leader='<Leader>d'
|
||||
<
|
||||
|
||||
LAUNCHING DEBUGGERS *vebugger-launching*
|
||||
|
||||
A debugger's implementation is responsible for starting it. The standard is to
|
||||
have a "start" function that accepts two arguments: The file to launch(EXE
|
||||
file or main script file) and a dictionary of other arguments. There should
|
||||
also be a command for launching the debugger with more ease.
|
||||
|
||||
|
||||
LAUNCHING GDB *vebugger-gdb*
|
||||
|
||||
GDB can be launched with *vebuger#gdb#start*
|
||||
>
|
||||
call vebugger#gdb#start('a.out',{'args':['hello','world']})
|
||||
<
|
||||
|
||||
The supported extra arguments are:
|
||||
* "args": Command line arguments for the debugged program
|
||||
* "pid": Process id to attach to
|
||||
You can't specify both "args" and "pid".
|
||||
|
||||
GDB can also be launched with the *VBGstartGDB* command:
|
||||
>
|
||||
VBGstartGDB a.out hello world
|
||||
<
|
||||
The *VBGattachGDB* command searches for processes launched from the EXE to
|
||||
attach to, and attaches to them:
|
||||
>
|
||||
VBGattachGDB a.out
|
||||
<
|
||||
|
||||
LAUNCHING JDB *vebugger-jdb*
|
||||
|
||||
JDB is launched with *vebugger#jdb#start*
|
||||
>
|
||||
call vebugger#jdb#start('Main',{
|
||||
\'classpath':'classes',
|
||||
\'srcpath':'src',
|
||||
\'args':['hello','world']})
|
||||
<
|
||||
Unlike in the other debuggers, the first argument here is not the name of a
|
||||
file - it's the name of the class to run. The supported extra arguments are:
|
||||
* "args": Command line arguments for the debugged program
|
||||
* "classpath": Where to look for class files
|
||||
* "srcpath": Where to look for source files
|
||||
If you don't supply "classpath" and "srcpath", Vebugger will assume you are
|
||||
using the current directory for source files and class files.
|
||||
|
||||
JDB does not have a command for starting it, since you usually want to supply
|
||||
"classpath" and "srcpath".
|
||||
|
||||
|
||||
LAUNCHING RDEBUG *vebugger-rdebug*
|
||||
|
||||
RDebug is launched with *vebugger#rdebug#start*
|
||||
>
|
||||
call vebugger#rdebug#start('script.rb',{'args':['hello','world']})
|
||||
<
|
||||
The supported extra arguments are:
|
||||
* "args": Command line arguments for the debugged script
|
||||
|
||||
RDebug can also be launched with the *VBGstartRDebug* command:
|
||||
>
|
||||
VBGstartRDebug script.rb hello world
|
||||
<
|
||||
|
||||
LAUNCHING PDB *vebugger-pdb*
|
||||
|
||||
PDB is launched with *vebugger#pdb#start*
|
||||
>
|
||||
call vebugger#pdb#start('script.py',{'args':['hello','world']})
|
||||
<
|
||||
The supported extra arguments are:
|
||||
* "args": Command line arguments for the debugged script
|
||||
|
||||
PDB can also be launched with the *VBGstartPDB* command:
|
||||
>
|
||||
VBGstartPDB script.py hello world
|
||||
<
|
||||
|
||||
USING THE DEBUGGERS *vebugger-usage* *vebugger-commands*
|
||||
|
||||
Once you have launched a debugger, you can use the following commands to
|
||||
interact with it:
|
||||
|
||||
|
||||
CONTROL THE EXECUTION OF THE PROGRAM *vebugger-execution-control*
|
||||
|
||||
*:VBGstepOver* Continue the execution, stopping at the next statement.
|
||||
*:VBGstepIn* Same as VBGstepOver but stepps into functions.
|
||||
*:VBGstepOut* Continue the execution until the end of the current function.
|
||||
*:VBGcontinue* Continue the execution.
|
||||
|
||||
MANAGE BREAKPOINTS *vebugger-breakpoints*
|
||||
|
||||
*:VBGtoggleBreakpoint* Toggle a breakpoint. The file and line should be supplied as arguments.
|
||||
*:VBGtoggleBreakpointThisLine* Toggle a breakpoint for the current line.
|
||||
*:VBGclearBreakpints* Clear all breakpoints.
|
||||
|
||||
EVALUATE EXPRESSIONS *vebugger-evalutate*
|
||||
|
||||
*:VBGeval* Evaluate and print the expression supplied as argument.
|
||||
*:VBGevalSelectedText* Evaluate and print the selected text.
|
||||
*:VBGevalWordUnderCursor* Evaluate the <cword> under the cursor
|
||||
|
||||
EXECUTE STATEMENTS *vebugger-execute*
|
||||
|
||||
*:VBGexecute* Execute the statement supplied as argument.
|
||||
*:VBGexecuteSelectedText* Execute the selected text.
|
||||
|
||||
TERMINATING THE DEBUGGER *vebugger-terminate*
|
||||
|
||||
*:VBGkill* Terminates the debugger
|
||||
|
||||
OPENING THE HOOD *vebugger-open-the-hood*
|
||||
|
||||
You can open the hood and interact with the running debugger directly using
|
||||
the following commands:
|
||||
|
||||
*:VBGtoggleTerminalBuffer* Opens a buffer that shows everything printed from
|
||||
the debugger interactive shell.
|
||||
*:VBGrawWrite* Sends a line supplied as argument to the debugger interactive shell.
|
||||
*:VBGrawWriteSelectedText* Sends the selected text to the debugger interactive
|
||||
shell.
|
||||
|
||||
|
||||
KEYMAPS *vebugger-keymaps*
|
||||
|
||||
If you set|g:vebugger_leader| in your vimrc you'll get keymaps for the
|
||||
Vebugger commands. The keymaps all start with the leader you set, following
|
||||
with:
|
||||
|
||||
i |:VBGstepIn|
|
||||
o |:VBGstepOver|
|
||||
O |:VBGstepOut|
|
||||
c |:VBGcontinue|
|
||||
|
||||
b |:VBGtoggleBreakpointThisLine|
|
||||
B |:VBGclearBreakpints|
|
||||
|
||||
e |:VBGevalWordUnderCursor| in normal mode
|
||||
|:VBGevalSelectedText| in select mode
|
||||
E Prompt for an argument for |:VBGeval|
|
||||
|
||||
x |:VBGexecute| current line in normal mode.
|
||||
|:VBGexecuteSelectedText| in select mode
|
||||
X Prompt for an argument for |:VBGexecute|
|
||||
|
||||
t |:VBGtoggleTerminalBuffer|
|
||||
r Select mode only - |:VBGrawWriteSelectedText|
|
||||
R Prompt for an argument for |:VBGrawWrite|
|
Loading…
x
Reference in New Issue
Block a user