Vim Tips Wiki
Tip 357 Printable Monobook Previous Next

created November 1, 2002 · complexity advanced · author Suresh Govindachar · version 6.0

This tip shows how to enhance the gdbvim script#84 by making the outputs from gdb appear in a "console buffer" inside vim.

"1.a) In gdbvim.vim, one needs to add the following two buffer
" manipulation functions:
" Buffer manipulation functions {{{1
" function! s:GdbFocusBuf(nameref) {{{2
" move the focus to the buffer nameref -- create
" it if it doesn't exist
" return the number of the currently focused buffer
function! s:GdbFocusBuf(nameref)
  let l:oldnr = bufnr("%")
  let l:win_nu = bufwinnr(a:nameref)
  if l:win_nu > 0
    execute l:win_nu "wincmd w"
    if bufexists(a:nameref)
      execute "sbuffer" a:nameref
      execute "new" a:nameref
  return l:oldnr

" function! s:GdbAppendBuf(nameref, stuff) {{{2
" append stuff to buffer nameref
function! s:GdbAppendBuf(nameref, stuff)
  let l:oldnr = s:GdbFocusBuf(a:nameref)
  call append("$", a:stuff)
  execute "normal G\<End>"
  return l:oldnr

"1.b) And modify the two source file management functions
" to be as follows:
" Source file management functions {{{1
" function! Gdb_Bpt(id, file, linenum) {{{2

function! Gdb_Bpt(id, file, linenum)
  let s:nowfile = a:file
  let l:curnr = s:GdbFocusBuf(a:file)
  execute "sign unplace ". a:id
  execute "sign place " . a:id ." name=breakpoint line=".a:linenum." file=".a:file
  execute a:linenum

" function! Gdb_CurrFileLine(file, line) {{{2
function! Gdb_CurrFileLine(file, line)
  if a:file != 0
    let s:nowfile=a:file
  let l:curnr = s:GdbFocusBuf(s:nowfile)
  execute "silent! " . a:line . "foldopen"
  execute "sign unplace ". 1
  execute "sign place " . 1 ." name=current line=".a:line." file=".s:nowfile
  execute a:line

"1.c) And add the following console function:
" function! Gdb_Console(stuff, set_prompt) {{{2
function! Gdb_Console(stuff, set_prompt)
  let l:fooey = s:GdbAppendBuf("console", a:stuff)
  if a:set_prompt == 1
    " What needs to happen here is to enter command mode
    " with the partial command ":Gdb " typed out.
    " The following line shows what doesn't work
    " call input(":Gdb ")

"1.d) And while we are modifying gdbvim.vim, we could also
" add a text section to the definitions of the signs:
sign define breakpoint linehl=DebugBreak text=bb
sign define current linehl=DebugStop text=cc

#2) The subroutine worker in the perl script gdbvim needs to
# be modified as indicated below. The key points to note
# are the two calls the vim-script function Gdb_Console().
# this function processes the gdb output, prints it and sends vim commands
sub worker # {{{
  vim_call('Gdb_interf_init(\"'.$PIPE.'\", \"'.$ENV{"PWD"}.'\")');
  print GDB_WTR "set prompt (gdb)\\n\n";
  while (<GDB_RDR>)
    if (/^.*?gdb\)/)
      print RL_WTR "READ\n";
      chomp ;
      print $_ . " ";
      vim_call("Gdb_Console(\\\"$_\\\", 1)");
      my $stuff = $_;
      s/Breakpoint ([0-9]+) at 0x.*: file ([^,]+), line ([0-9]+)./Gdb_Bpt($1,\\\"$2\\\",$3)/ ||
      s/Breakpoint ([0-9]+), 0x.*at ([^,]+):([0-9]+)/Gdb_CurrFileLine(\\\"$2\\\",$3)/ ||
      s/^\s*0x.*\s+at\s+(\S+):([0-9]+)/Gdb_CurrFileLine(\\\"$1\\\",$2)/ ||
      s/\032\032([^:]*):([0-9]+).*/Gdb_CurrFileLine(\\\"$1\\\", $2)/ ||
      s/^\s*0x\S+\s*([0-9]+)\s+.*/Gdb_CurrFileLine(0, $1)/
  print $stuff;
  # the next substitution is because I couldn't figure out how to
  # pass (from perl) double quotes inside string arguments to
  # vim-script functions
  $stuff =~ s/"/'/g;
  vim_call("Gdb_Console(\\\"$stuff\\\", 0)");
  close GDB_RDR; close GDB_WTR;
}; # }}}

That's all the modifications -- and now gdbvim will show the output of gdb inside a vim. (Errors from gdb won't show up in the console but still go to the terminal.)


In the preceding, the second argument to Gdb_Console(stuff, set_prompt) is not used. The purpose of the second argument was to try to provide the user with the ":Gdb " prompt in gvim. This result can actually be achieved in the perl script by executing the following command immediately after the first call to Gdb_Console in sub worker:

system("/usr/local/bin/gvim --servername $VIMNAME -u NONE -U NONE --remote-send \":Gdb \"");