*breakpts.txt*  Set/View Vim breakpoints and browse functions visually
                    Requires Vim 7.1
            Last Change: 25-Oct-2007 @ 08:22
          Since Version: 4.0
                 Author: Hari Krishna Dara (hari.vim at gmail dot com)

The plugin provides a few features for debugging Vim scripts that are similar
to what IDEs normally have, such as browing source, managing breatpoints etc.
Setting breakpoints visually in functions is very important as you need to
specify the exact line number for the line you are interested in (which often
is difficult to find out if you use |line-continuation| characters to format
code). This also avoids typing in the |:breakadd| command while guessing what
the scriptids for your script are. It also defines a few convenience commands
that take the place of Vim built-in commands and add Vim command-line
completion feature.

The plugin also provided utilties to create various conditional breakpoints
programmatically to help debug complex and iterative logic. You can set a
condition, a skip count and an expire count for your breakpoint to be valid on
any particular line.

You can also simply use the plugin to browse Vim sripts and functions. It
provides a browser history type of features to drill into the code, by
navigating the function calls and return back to the previous function at any
time.

Here is a list of features:
    - Set/unset breakpoints in functions and scripts visually.
    - Save/clear/restore list of breakpoints across sessions.
    - Browse functions and script by navigating through the list of functions
      (and function references) and scripts.
    - Reload scripts when they change externally (during development)
    - Global functions to set/unset breakpoints programmatically with optional
      conditions.
    - Misc. alternative commands for the built-ins that typically work better
      (better completion and defaults).
    - Remote debugging ability to debug scripts in one Vim session using
      another Vim as the debugger.

==============================================================================
OVERVIEW                                    *breakpts-overview*

|breakpts-installation|     How to install the plugin.

|breakpts-usage|            A brief usage to get you quickly started.

|breakpts-commands|         A description of various ex commands and their
                               mappings that will be defined by the plugin.

|breakpts-settings|         An explanation of settings.

|breakpts-functions|        New API provided by the plugin.

|breakpts-tips|             Some useful tips.

|breakpts-limitations|      Current limitations of the plugin.

|breakpts-todo|             Some TODO items.

|breakpts-changes|          A change list for current version from previous
                               versions.

|breakpts-acknowledgements| Acknowledgements.

==============================================================================

                                            *breakpts-installation*
    - To install, download the latest versions of these two plugins:
        breakpts: http://www.vim.org/script.php?script_id=618
        genutils:  http://vim.sourceforge.net/script.php?script_id=197
    - Extract the zip archives in to your runtime directory (.vim or vimfiles
      under your HOME directory).
    - Make sure your vim has +signs feature.
    - Start a new instance or go to an existing instance of vim.
    - Execute:
>
        :helpt <your runtime directory>/doc
<
      This should generate the help tags for the breakpts plugin help.
    - Take a look at the |breakpts-settings| to change any default
      configuration and behavior.

    Optional:
    - Take a look at the |breakpts-winmanager| to configure with winmanager.
    - Choose a hotkey as described in |breakpts-usage|.
    - Considier installation the following two optional plugins:
      - If cmdalias plugin is installed, it will be used to create aliases for
        a few commands, to make it easier to type. Download the plugin from:
            http://www.vim.org/script.php?script_id=745
      - If foldutil plugin is installed, it will be used to foldaway the code
        such that the breakpoints are easier to see. Download the plugin from:
            http://www.vim.org/script.php?script_id=158

Later, if you need to temporarily disable the plugin without needing to remove
the file or move it into a different directory, you can set the
loaded_breakpts variable in your vimrc.

==============================================================================

                                            *breakpts-usage*
                                            *breakpts-navigation*
To use the plugin, start with the :BreakPts command to open a window with a
sorted list of all the functions that are currently defined in the current Vim
session. You can search for the function that you are interested in and use
<Enter> key (or :BPSelect command) to view its listing. You can navigate the
function calls by continuing to press <Enter> on the identifiers that you are
interested in the listings and create a history that you can navigate back by
using <BS> key (or :BPBack command) and forth by using <Tab> (or :BPForward
command). Instead o pressing <Enter> to select an identifier, you could also
use your mouse to double-click.

You can also define a hotkey to open the window. Choose a function key, such
as <F7> or a key sequence such as \b and put the following in your vimrc: >

        nmap <silent> <F7> <Plug>BreakPts
<
There is no default hotkey defined, so you *must* define one to use this
feature.

The :BreakPts command can take an option for you to specify what listing to
display in the Breakpts window. The available options are:

        Option  Description~
        +f      Show list of functions currently defined by all scripts (the
                default).
        +s      Show list of scripts currently loaded
        +b      Show list of breakpoints currently defined.

To open the window with a list of scripts, you can type: >

        :BreakPts +s
<
You can press <Enter> on a script or double-click using mouse to show the
listing for that script. If the script uses libraries, or calls functions from
other scripts (such as a command defined in plugin directory calling its
autoload companion), you can drill further into those functions.

To view the currently defined list of breakpoints, you can type: >

        :BreakPts +b
<
This allows you to disable and re-enable individual breakpoints.

                                            *:BPScripts*
                                            *:BPFunctions*
                                            *:BPPoints*
Once you are in the BreakPts window, you can switch between these modes using
the following buffer local commands:

        Command         Description~
        BPScripts       List scripts (:BreakPts +s)
        BPFunctions     List functions (:BreakPts +f)
        BPPoints        List breakpoints (:BreakPts +b)

The difference between these and the corresponding options is that these
presever the history.

                                            *:BPListFunc*
                                            *:BPListScript*
There are also commands defined in the BreakPts window, to directly jump to a
script of a function listing. Use :BPListFunc command with the function name as
argument or :BPListScript with a path as an argument (the path can be absolute
or relative to current directory or any directory in the 'runtimepath').
The :BPListScript is also the only way you can set a breakpoint in an unloaded
plugin (such as a ftplugin that is yet to be loaded), as :BPScripts can only
show what is already loaded. Both commands support completion on their
arguments.

NOTE: For script local functions, you can have vim fill in the <SNR> prefix
(instead of manually typing it in), by prefixing the function name with an
asterisk, before attempting to complete.

There are a number of other ex-mode commands that you can issue when you are in the
BreakPts window and these are described under |breakpts-commands|.
==============================================================================

                                            *breakpts-settings*
There are a few settings by which you can customize the behavior of this plugin.

- Set g:brkptsDefStartMode to "scripts", "functions" or "breakpts" to start
  the browser in that mode.
- Set g:brkptsModFuncHeader to a false value, if you don't want to change
  "function" to "function!" while listing functions. Making this change will
  normally make it easier for you to block copy the function and redefine it
  while still in debug mode (kind of like incremental update).
- Set the '!' flag in viminfo if you want to save the breaklist across
  sessions (see usage above).
  defines two commands, [b and ]b (or :BPPrevious and :BPNext). Also, if
- If foldutil.vim plugin is found to be installed, the plugin
  automatically folds all the lines that do not have a breakpoint (with a
  context of g:brkptsFoldContext, which has a default value of 3). This
  feature is disabled if foldutil.vim is not found to be installed, but you
  can also set g:brkptsCreateFolds to 0 to explicitly disable it.

                                            *breakpts-maps*
The default maps for debug commands are defined based on the MS Visual Studio,
but you can easily configure them.

  Here is a table of all the mappings and their default key associations:
  
    Mapping               Default       Description~
    BreakPtsContKey       <F5>          Continue execution (>cont).
    BreakPtsQuitKey       <S-F5>        Quit debug mode (>quit).
    BreakPtsNextKey       <F12>         Exeute next command (>next).
    BreakPtsStepKey       <F11>         Step into next command (>step).
    BreakPtsFinishKey     <S-F11>       Finish executing current
                                        function/script (>finish).
    BreakPtsClearAllKey   <C-S-F9>      Clear all breakpoints.

  E.g., to change the mapping for the BreakPtsContKey to <F8>, place the
  following in your vimrc:

    nmap <script> <silent> <Plug>BreakPtsContKey <F8>
==============================================================================

                                            *breakpts-commands*
There are a number of commands available local to the [BreakPts] window 
Here is a full list of such commands:

        Command         Description ~
        BPBack          History navigation.
        BPForward       History navigation.
        BPSelect        Select the current item (drilldown)
        BPOpen          Open the current script for editing.
        BPToggle        Toggle breakpoint at the current line.
        BPRefresh       Refresh/reload the current view.
        BPNext          Take cursor to the next breakpoint in the current
                        view.
        BPPrevious      Take cursor to the next breakpoint in the current
                        view.
        BPReload        Reload the current script.
        BPClearCounters Clear all counters for conditional breakpoints.
        BPClearAll      Remove all breakpoints.
        BPSave          Save all breakpoints in the given global variable.
        BPScripts       List scripts
        BPFunctions     List functions
        BPPoints        List breakpoints

                                            *:BPSave*
You can save the breakpoints into a global variable using the :BPSave command
while in the BreakPts window (or using the :BreakPtsSave in other windows). The
command takes in the name of a global variable where the commands to recreate
the breakpoints will be saved. You can later reload these breakpoints by simply
executing the variable: >

      :BPSave BL
      :BPClearAll
      .
      .
      :exec BL
<
You can also use this technique to save and restore breakpoints across sessions.
For this to work, just make sure that the '!' option in 'viminfo' is set:

      :set viminfo^=!

and use a variable name that starts with an uppercase letter and contain only
uppercase letters and underscore characters (see help on 'viminfo'). When you
are no longer interested in saving and restoring a breaklist, it is advisable to
unlet the corresponding global variable.

                                            *:BPReload*
In the scripts view, you can use :BPReload (or O) to reload the script that the
cursor is currently on locally or remotely. The command also reloads the script
that you are currently listing.

This command is very much like running the |:source| on the script except that
it can work remotely and for plugins, it can make sure the corresponding
"g:loaded_<plugin name>" variable is first unlet so that it will actually
sourced. This is also useful to reload autoload scripts, but since they don't
use a guaring variable to prevent sourcing multiple times, no variable unletting
is done.

NOTE: Don't use this command to reload scripts such as ftplugin, indent, syntax,
colors or compiler plugins as these will automatically be reloaded by Vim at
appropriate times.

TIP: Desing your plugin and autoload scripts such that you can reload them in to
your debug session without needing to restart Vim. This considerably speeds up
your debug/development time. To support reloading, guard all the script local
variables against an |exists()| block such that they will not get initialized
the second time. >

        if !exists('s:onevar')
            let s:onevar = 'one'
            let s:twovar = 'two'
        endif
<
This effectively allows redefining the functions and you can immediately see
them in effect. However, if you introduce a new script-local variable, you will
have to manually set it in the script context when you are in the debug
mode, or restart Vim.

                                            *:BPRefresh*
The contents of BreakPts window is cached, so to see the latest listing at any
time, refresh the window by pressing 'R' (or :BPRefresh) command. You also need
to refresh to see the breakpoints added/removed manually.

NOTE: This commands results in a loss of forward history.

                                            *:BPToggle*
                                            *:BPClearAll*
To toggle a breakpoint at any line, press <F9> (or :BPToggle) command.  The
plugin uses Vim's |:sign| feature to visually indicate the existence of a
breakpoint. You can also use :BPClearAll command to clear all the breakpoints
when you are in the BreakPts window (or :BreakPtsClearAll in other windows).

                                            *:BPOpen*
While viewing the list of scripts, you can open a script for editing in a new
window using o (or :BPOpen) command. This is just a convenience command.

                                            *:BPNext*
                                            *:BPPrevious*
These commands help you locate breakpoints in a large script or function. The
BPPrevious command is mapped [b and BPNext command is mapped to ]b.
==============================================================================

                                            *breakpts-utilities*
The plugin comes with a few custom commands or variants of the built-in ones
with improvements. These commands are available globally (means, can be
executed from any window).

The Where command when used at the debug prompt, prints the context of the
current line (this is exactly the same information that Vim prints after
returning to the debug (>) prompt.

Here is a set of command that are identical to the built-in commands with
simply better command-line completion support. If cmdalias.vim is found to be
installed, the built-in commands will be aliased to these custom commands.
  - :Runtime (for |:runtime|) allows you to do partial file completions from
    your 'runtimepath'.
  - :Debug (for |:debug|) allows you to do command-completions.
  - :Breakadd (for |:breakadd|) allows you to complete on the function name or
    file path (from 'runtimepath').
  - :Breakdel (for |:breakdel|) allows you to complete on the existing
    breakpoints (obtained from :breaklist).
==============================================================================

                                            *breakpts-visual-debugging*
                                            *breakpts-remote-debugging*
To connect to a remote Vim using the |clientserver| functionality, open the
BreakPts window and use the :BPRemoteServ command with the Vim server name as
the argument (with no arguments the same command prints the current remote
server name). You can browse the functions/scripts and set breakpoints in the
remote session exactly as you would in the local session. To get back to the
local vim session, use the same command with "." as the server name.

Once the remote vim is in the debug mode (stopped at the > prompt), you can
use :BPDWhere command to view the context of the remote session. The current
line is marked with the BreakPtsContext highlighting group (by default same as
Visual). You can also execute the :debug mode commands in the remote session
as follows:

      Remote command    Local command   Local map
      >next             :BPDNext        <F12>
      >step             :BPDStep        <F11> 
      >cont             :BPDCont        <F5>
      >quit             :BPDQuit        <S-F5>
      >finish           :BPDFinish      <S-F11>

The commands are simply relayed to the remote debugging session using the
|client-server| features of Vim.

==============================================================================

                                            *breakpts-functions*
The plugin provides a se tof global functions which can be used to insert or
remove breakpoints programmatically and conditionally. The BPBreak() function
works similar to the VB break command (and like the new ":breakadd here"
command, but also works inside functions). They can also be executed at the
debug prompt (great to insert or clear breakpoints at the current line, or a
few lines down below (which itself is useful with >cont)). To insert the
breakpoint, programmatically or at the debug prompt, you execute the return
value of the function, e.g., >
    exec BPBreak(1)
<
Here is a list of all the functions: >
      " Adds/removes breakpoint conditionally only if the hit count is >
      " skipCnt and <= expireCnt, at the given offset.
      function BPBreakIfCount(skipCnt, expireCnt, cond, offset)
      " Unconditional add breakpoint at the given offset.
      function BPBreak(offset)
      " Conditionally add breakpoint at the given offset.
      function BPBreakIf(cond, offset)
      " Unconditionally remove breakpoint at the given offset.
      function BPDeBreak(offset)
<
For conditional breakpoints that use skipCnt and expireCnt, you need to
call :BreakPtsClearBPCounters before each invocation of the script.

==============================================================================

                                            *breakpts-winmanager*
To configure, you can specify "BreakPts" as one of the windows. E.g: >

  let g:winManagerWindowLayout = 'FileExplorer,BreakPts'
<
You can then switch between FileExplorer and BreakPts by pressing ^N
and ^P.
==============================================================================

                                            *breakpts-experimental*
You can create any number of BreakPts buffers by running :BreakPtsSetupBuf
command while inside the buffer. This command converts the buffer by turning
on the appropriate settings. This allows you to display as many windows as you
want each with different lists/listings.

E.g., you can convert a :new buffer to display the :breaklist (by
executing the :BPPoints command) and use it to enable/disable
breakpoints. >
    :new
    :BreakPtsSetupBuf
    :BPPoints
<
==============================================================================

                                            *breakpts-known-issues*
- exec BPBreak() during debugging, with -ve index always works like the
  current line only.
- BPListFunc and BPListScript use default Vim completion, but they should
  really use custom completion which reads the list from current remote
  Vim server.
- How do I detect if the execution of the command has finished, so that I
  can terminate s:WaitForDbgPrompt()?
- If you set a breakpoint during the startup, it doesn't work. Also,
  BPBreak seems to misbehave 'file' as 'func' in this case.
  exec 'breakadd file 3' expand('<sfile>')
  exec BPBreak(1)
  call input(expand('<sfile>'))
- BPRemoteServ should have a global equivalent.
- The :BPListFunc should also support SID search.
- How can I generate context without executing a normal command?
  Using remote_expr() doesn't seem feasible. The same is applicable to
  executing debug mode commands.
- Delete functions from the function list.

                                            *breakpts-todo*
                                            *breakpts-wishlist*
- Need a Where command for local use (at debug prompt).
- Implement BPDRunToCursor. Create a temporary breakpoint and clear it
  when hit.
- It should be possible to run ctags to get all the local variables in the
  current function and automatically show their values. We should also
  be able to show the argument values automatically.
- How about a :BPDEvaluate command that takes in an expression and
  evaluates it in the remote vim and shows the result (using
  remote_expr() to be safe)?
- It should also be possible to create watch expressions to be evaluated
  everytime the context is refreshed (using the :BPEvaluation infra.).
- How about opening an editable function listing window extracted from the
  remote vim, and allow users to redefine it after modifying it?
- Can I make better use of the stack produced by the context? I can
  maintain a local stack of current line numbers for them. But still Vim
  will not be able to go up and down the stack, so may be not that
  important.
- A menu will be useful for those who are used to menus.
- We need a debug console to show the output of various debug commands.
- A statusbar (with current function/script name etc.) will be useful.
- It is possible for the debuggee scripts to provide a standard interface
  (see perforce plugin for example) for the plugin to poke into and obtain
  the script local values. This allows us to show the local variables at
  any time, and without needing to execute them at debug prompt remotely.

==============================================================================

                                            *breakpts-acknowledgements*
- Thanks a lot to David Fishburn (fishburn at sybase dot com) for
  providing a lot of feedback, ideas and patches, and helping me with
  finding problems. The plugin is much more usable and bug free because of
  him.
- Bram and Michael Geddes (mgeddes at au dot mediacommand dot com) for
  fixing the Vim crashes with remote debugging.


 vim6:tw=80:ts=8:ft=help:ai:sw=4:et
