<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>ruby_debugger/exception.vim</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -17,6 +17,7 @@ command! -nargs=1 RdbCommand :call g:RubyDebugger.send_command(&lt;q-args&gt;)
 command! -nargs=0 RdbTest :call g:RubyDebugger.run_test() 
 command! -nargs=1 RdbEval :call g:RubyDebugger.eval(&lt;q-args&gt;)
 command! -nargs=1 RdbCond :call g:RubyDebugger.conditional_breakpoint(&lt;q-args&gt;)
+command! -nargs=1 RdbCatch :call g:RubyDebugger.catch_exception(&lt;q-args&gt;)
 
 if exists(&quot;g:ruby_debugger_loaded&quot;)
   &quot;finish
@@ -352,7 +353,7 @@ endfunction
 
 &quot; *** Public interface (start)
 
-let RubyDebugger = { 'commands': {}, 'variables': {}, 'settings': {}, 'breakpoints': [], 'frames': [] }
+let RubyDebugger = { 'commands': {}, 'variables': {}, 'settings': {}, 'breakpoints': [], 'frames': [], 'exceptions': [] }
 let g:RubyDebugger.queue = s:Queue.new()
 
 
@@ -364,6 +365,7 @@ function! RubyDebugger.start(...) dict
   echo &quot;Loading debugger...&quot;
   call g:RubyDebugger.server.start(script)
 
+  let g:RubyDebugger.exceptions = []
   for breakpoint in g:RubyDebugger.breakpoints
     call g:RubyDebugger.queue.add(breakpoint.command())
   endfor
@@ -397,8 +399,12 @@ function! RubyDebugger.receive_command() dict
         call g:RubyDebugger.commands.jump_to_breakpoint(cmd)
       elseif match(cmd, '&lt;suspended ') != -1
         call g:RubyDebugger.commands.jump_to_breakpoint(cmd)
+      elseif match(cmd, '&lt;exception ') != -1
+        call g:RubyDebugger.commands.handle_exception(cmd)
       elseif match(cmd, '&lt;breakpointAdded ') != -1
         call g:RubyDebugger.commands.set_breakpoint(cmd)
+      elseif match(cmd, '&lt;catchpointSet ') != -1
+        call g:RubyDebugger.commands.set_exception(cmd)
       elseif match(cmd, '&lt;variables&gt;') != -1
         call g:RubyDebugger.commands.set_variables(cmd)
       elseif match(cmd, '&lt;error&gt;') != -1
@@ -515,6 +521,23 @@ function! RubyDebugger.conditional_breakpoint(exp) dict
 endfunction
 
 
+&quot; Catch all exceptions with given name
+function! RubyDebugger.catch_exception(exp) dict
+  if has_key(g:RubyDebugger, 'server') &amp;&amp; g:RubyDebugger.server.is_running()
+    let quoted = s:quotify(a:exp)
+    let exception = s:Exception.new(quoted)
+    call add(g:RubyDebugger.exceptions, exception)
+    if s:breakpoints_window.is_open()
+      call s:breakpoints_window.open()
+      exe &quot;wincmd p&quot;
+    endif
+    call g:RubyDebugger.queue.execute()
+  else
+    echo &quot;Sorry, but you can set Exceptional Breakpoints only with running debugger&quot;
+  endif
+endfunction
+
+
 &quot; Next
 function! RubyDebugger.next() dict
   call g:RubyDebugger.queue.add(&quot;next&quot;)
@@ -594,6 +617,23 @@ function! RubyDebugger.commands.jump_to_breakpoint(cmd) dict
 endfunction
 
 
+&quot; &lt;exception file=&quot;test.rb&quot; line=&quot;1&quot; type=&quot;NameError&quot; message=&quot;some exception message&quot; threadId=&quot;4&quot; /&gt;
+&quot; Show message error and jump to given file/line
+function! RubyDebugger.commands.handle_exception(cmd) dict
+  let message_match = matchlist(a:cmd, 'message=&quot;\(.\{-}\)&quot;')
+  call g:RubyDebugger.commands.jump_to_breakpoint(a:cmd)
+  echo &quot;Exception message: &quot; . s:unescape_html(message_match[1])
+endfunction
+
+
+&quot; &lt;catchpointSet exception=&quot;NoMethodError&quot;/&gt;
+&quot; Confirm setting of exception catcher
+function! RubyDebugger.commands.set_exception(cmd) dict
+  let attrs = s:get_tag_attributes(a:cmd)
+  call g:RubyDebugger.logger.put(&quot;Exception successfully set: &quot; . attrs.exception)
+endfunction
+
+
 &quot; &lt;breakpointAdded no=&quot;1&quot; location=&quot;test.rb:2&quot; /&gt;
 &quot; Add debugger info to breakpoints (pid of debugger, debugger breakpoint's id)
 &quot; Assign rest breakpoints to debugger recursively, if there are breakpoints
@@ -1038,6 +1078,8 @@ function! s:WindowBreakpoints.render() dict
   for breakpoint in g:RubyDebugger.breakpoints
     let breakpoints .= breakpoint.render()
   endfor
+  let exceptions = map(copy(g:RubyDebugger.exceptions), 'v:val.render()')
+  let breakpoints .= &quot;\nException breakpoints: &quot; . join(exceptions, &quot;, &quot;)
   return breakpoints
 endfunction
 
@@ -1611,6 +1653,49 @@ endfunction
 
 &quot; *** Breakpoint class (end)
 
+&quot; *** Exception class (start)
+&quot; These are ruby exceptions we catch with 'catch Exception' command
+&quot; (:RdbCatch)
+
+let s:Exception = { }
+
+&quot; ** Public methods
+
+&quot; Constructor of new exception.
+function! s:Exception.new(name)
+  let var = copy(self)
+  let var.name = a:name
+  call var._log(&quot;Trying to set exception: &quot; . var.name)
+  call g:RubyDebugger.queue.add(var.command())
+  return var
+endfunction
+
+
+&quot; Command for setting exception (e.g.: 'catch NameError')
+function! s:Exception.command() dict
+  return 'catch ' . self.name
+endfunction
+
+
+&quot; Output format for Breakpoints Window
+function! s:Exception.render() dict
+  return self.name
+endfunction
+
+
+&quot; ** Private methods
+
+
+function! s:Exception._log(string) dict
+  call g:RubyDebugger.logger.put(a:string)
+endfunction
+
+
+&quot; *** Exception class (end)
+
+
+
+
 &quot; *** Frame class (start)
 
 let s:Frame = { }</diff>
      <filename>additionals/plugin/ruby_debugger_test.vim</filename>
    </modified>
    <modified>
      <diff>@@ -17,6 +17,7 @@ command! -nargs=1 RdbCommand :call g:RubyDebugger.send_command(&lt;q-args&gt;)
 command! -nargs=0 RdbTest :call g:RubyDebugger.run_test() 
 command! -nargs=1 RdbEval :call g:RubyDebugger.eval(&lt;q-args&gt;)
 command! -nargs=1 RdbCond :call g:RubyDebugger.conditional_breakpoint(&lt;q-args&gt;)
+command! -nargs=1 RdbCatch :call g:RubyDebugger.catch_exception(&lt;q-args&gt;)
 
 if exists(&quot;g:ruby_debugger_loaded&quot;)
   &quot;finish</diff>
      <filename>ruby_debugger/before.vim</filename>
    </modified>
    <modified>
      <diff>@@ -15,6 +15,23 @@ function! RubyDebugger.commands.jump_to_breakpoint(cmd) dict
 endfunction
 
 
+&quot; &lt;exception file=&quot;test.rb&quot; line=&quot;1&quot; type=&quot;NameError&quot; message=&quot;some exception message&quot; threadId=&quot;4&quot; /&gt;
+&quot; Show message error and jump to given file/line
+function! RubyDebugger.commands.handle_exception(cmd) dict
+  let message_match = matchlist(a:cmd, 'message=&quot;\(.\{-}\)&quot;')
+  call g:RubyDebugger.commands.jump_to_breakpoint(a:cmd)
+  echo &quot;Exception message: &quot; . s:unescape_html(message_match[1])
+endfunction
+
+
+&quot; &lt;catchpointSet exception=&quot;NoMethodError&quot;/&gt;
+&quot; Confirm setting of exception catcher
+function! RubyDebugger.commands.set_exception(cmd) dict
+  let attrs = s:get_tag_attributes(a:cmd)
+  call g:RubyDebugger.logger.put(&quot;Exception successfully set: &quot; . attrs.exception)
+endfunction
+
+
 &quot; &lt;breakpointAdded no=&quot;1&quot; location=&quot;test.rb:2&quot; /&gt;
 &quot; Add debugger info to breakpoints (pid of debugger, debugger breakpoint's id)
 &quot; Assign rest breakpoints to debugger recursively, if there are breakpoints</diff>
      <filename>ruby_debugger/commands.vim</filename>
    </modified>
    <modified>
      <diff>@@ -1,6 +1,6 @@
 &quot; *** Public interface (start)
 
-let RubyDebugger = { 'commands': {}, 'variables': {}, 'settings': {}, 'breakpoints': [], 'frames': [] }
+let RubyDebugger = { 'commands': {}, 'variables': {}, 'settings': {}, 'breakpoints': [], 'frames': [], 'exceptions': [] }
 let g:RubyDebugger.queue = s:Queue.new()
 
 
@@ -12,6 +12,7 @@ function! RubyDebugger.start(...) dict
   echo &quot;Loading debugger...&quot;
   call g:RubyDebugger.server.start(script)
 
+  let g:RubyDebugger.exceptions = []
   for breakpoint in g:RubyDebugger.breakpoints
     call g:RubyDebugger.queue.add(breakpoint.command())
   endfor
@@ -45,8 +46,12 @@ function! RubyDebugger.receive_command() dict
         call g:RubyDebugger.commands.jump_to_breakpoint(cmd)
       elseif match(cmd, '&lt;suspended ') != -1
         call g:RubyDebugger.commands.jump_to_breakpoint(cmd)
+      elseif match(cmd, '&lt;exception ') != -1
+        call g:RubyDebugger.commands.handle_exception(cmd)
       elseif match(cmd, '&lt;breakpointAdded ') != -1
         call g:RubyDebugger.commands.set_breakpoint(cmd)
+      elseif match(cmd, '&lt;catchpointSet ') != -1
+        call g:RubyDebugger.commands.set_exception(cmd)
       elseif match(cmd, '&lt;variables&gt;') != -1
         call g:RubyDebugger.commands.set_variables(cmd)
       elseif match(cmd, '&lt;error&gt;') != -1
@@ -163,6 +168,23 @@ function! RubyDebugger.conditional_breakpoint(exp) dict
 endfunction
 
 
+&quot; Catch all exceptions with given name
+function! RubyDebugger.catch_exception(exp) dict
+  if has_key(g:RubyDebugger, 'server') &amp;&amp; g:RubyDebugger.server.is_running()
+    let quoted = s:quotify(a:exp)
+    let exception = s:Exception.new(quoted)
+    call add(g:RubyDebugger.exceptions, exception)
+    if s:breakpoints_window.is_open()
+      call s:breakpoints_window.open()
+      exe &quot;wincmd p&quot;
+    endif
+    call g:RubyDebugger.queue.execute()
+  else
+    echo &quot;Sorry, but you can set Exceptional Breakpoints only with running debugger&quot;
+  endif
+endfunction
+
+
 &quot; Next
 function! RubyDebugger.next() dict
   call g:RubyDebugger.queue.add(&quot;next&quot;)</diff>
      <filename>ruby_debugger/public.vim</filename>
    </modified>
    <modified>
      <diff>@@ -19,6 +19,8 @@ function! s:WindowBreakpoints.render() dict
   for breakpoint in g:RubyDebugger.breakpoints
     let breakpoints .= breakpoint.render()
   endfor
+  let exceptions = map(copy(g:RubyDebugger.exceptions), 'v:val.render()')
+  let breakpoints .= &quot;\nException breakpoints: &quot; . join(exceptions, &quot;, &quot;)
   return breakpoints
 endfunction
 </diff>
      <filename>ruby_debugger/window_breakpoints.vim</filename>
    </modified>
    <modified>
      <diff>@@ -12,6 +12,7 @@ ruby_debugger/var_child.vim
 ruby_debugger/var_parent.vim
 ruby_debugger/logger.vim
 ruby_debugger/breakpoint.vim
+ruby_debugger/exception.vim
 ruby_debugger/frame.vim
 ruby_debugger/server.vim
 ruby_debugger/after.vim</diff>
      <filename>ruby_debugger_plan.txt</filename>
    </modified>
    <modified>
      <diff>@@ -54,7 +54,8 @@ class VimRubyDebugger
           output = read_socket(response, @rdebug)
           @result &lt;&lt; output
           # If we stop at breakpoint, add taking of local variables into queue
-          if output =~ /&lt;breakpoint / || output =~ /&lt;suspended /
+          stop_commands = [ '&lt;breakpoint ', '&lt;suspended ', '&lt;exception ' ]
+          if stop_commands.any? { |c| output.include?(c) }
             @queue &lt;&lt; &quot;var local&quot; 
             @queue &lt;&lt; &quot;where&quot;
           end</diff>
      <filename>vim/bin/ruby_debugger.rb</filename>
    </modified>
    <modified>
      <diff>@@ -17,6 +17,7 @@ command! -nargs=1 RdbCommand :call g:RubyDebugger.send_command(&lt;q-args&gt;)
 command! -nargs=0 RdbTest :call g:RubyDebugger.run_test() 
 command! -nargs=1 RdbEval :call g:RubyDebugger.eval(&lt;q-args&gt;)
 command! -nargs=1 RdbCond :call g:RubyDebugger.conditional_breakpoint(&lt;q-args&gt;)
+command! -nargs=1 RdbCatch :call g:RubyDebugger.catch_exception(&lt;q-args&gt;)
 
 if exists(&quot;g:ruby_debugger_loaded&quot;)
   &quot;finish
@@ -352,7 +353,7 @@ endfunction
 
 &quot; *** Public interface (start)
 
-let RubyDebugger = { 'commands': {}, 'variables': {}, 'settings': {}, 'breakpoints': [], 'frames': [] }
+let RubyDebugger = { 'commands': {}, 'variables': {}, 'settings': {}, 'breakpoints': [], 'frames': [], 'exceptions': [] }
 let g:RubyDebugger.queue = s:Queue.new()
 
 
@@ -364,6 +365,7 @@ function! RubyDebugger.start(...) dict
   echo &quot;Loading debugger...&quot;
   call g:RubyDebugger.server.start(script)
 
+  let g:RubyDebugger.exceptions = []
   for breakpoint in g:RubyDebugger.breakpoints
     call g:RubyDebugger.queue.add(breakpoint.command())
   endfor
@@ -397,8 +399,12 @@ function! RubyDebugger.receive_command() dict
         call g:RubyDebugger.commands.jump_to_breakpoint(cmd)
       elseif match(cmd, '&lt;suspended ') != -1
         call g:RubyDebugger.commands.jump_to_breakpoint(cmd)
+      elseif match(cmd, '&lt;exception ') != -1
+        call g:RubyDebugger.commands.handle_exception(cmd)
       elseif match(cmd, '&lt;breakpointAdded ') != -1
         call g:RubyDebugger.commands.set_breakpoint(cmd)
+      elseif match(cmd, '&lt;catchpointSet ') != -1
+        call g:RubyDebugger.commands.set_exception(cmd)
       elseif match(cmd, '&lt;variables&gt;') != -1
         call g:RubyDebugger.commands.set_variables(cmd)
       elseif match(cmd, '&lt;error&gt;') != -1
@@ -515,6 +521,23 @@ function! RubyDebugger.conditional_breakpoint(exp) dict
 endfunction
 
 
+&quot; Catch all exceptions with given name
+function! RubyDebugger.catch_exception(exp) dict
+  if has_key(g:RubyDebugger, 'server') &amp;&amp; g:RubyDebugger.server.is_running()
+    let quoted = s:quotify(a:exp)
+    let exception = s:Exception.new(quoted)
+    call add(g:RubyDebugger.exceptions, exception)
+    if s:breakpoints_window.is_open()
+      call s:breakpoints_window.open()
+      exe &quot;wincmd p&quot;
+    endif
+    call g:RubyDebugger.queue.execute()
+  else
+    echo &quot;Sorry, but you can set Exceptional Breakpoints only with running debugger&quot;
+  endif
+endfunction
+
+
 &quot; Next
 function! RubyDebugger.next() dict
   call g:RubyDebugger.queue.add(&quot;next&quot;)
@@ -594,6 +617,23 @@ function! RubyDebugger.commands.jump_to_breakpoint(cmd) dict
 endfunction
 
 
+&quot; &lt;exception file=&quot;test.rb&quot; line=&quot;1&quot; type=&quot;NameError&quot; message=&quot;some exception message&quot; threadId=&quot;4&quot; /&gt;
+&quot; Show message error and jump to given file/line
+function! RubyDebugger.commands.handle_exception(cmd) dict
+  let message_match = matchlist(a:cmd, 'message=&quot;\(.\{-}\)&quot;')
+  call g:RubyDebugger.commands.jump_to_breakpoint(a:cmd)
+  echo &quot;Exception message: &quot; . s:unescape_html(message_match[1])
+endfunction
+
+
+&quot; &lt;catchpointSet exception=&quot;NoMethodError&quot;/&gt;
+&quot; Confirm setting of exception catcher
+function! RubyDebugger.commands.set_exception(cmd) dict
+  let attrs = s:get_tag_attributes(a:cmd)
+  call g:RubyDebugger.logger.put(&quot;Exception successfully set: &quot; . attrs.exception)
+endfunction
+
+
 &quot; &lt;breakpointAdded no=&quot;1&quot; location=&quot;test.rb:2&quot; /&gt;
 &quot; Add debugger info to breakpoints (pid of debugger, debugger breakpoint's id)
 &quot; Assign rest breakpoints to debugger recursively, if there are breakpoints
@@ -1038,6 +1078,8 @@ function! s:WindowBreakpoints.render() dict
   for breakpoint in g:RubyDebugger.breakpoints
     let breakpoints .= breakpoint.render()
   endfor
+  let exceptions = map(copy(g:RubyDebugger.exceptions), 'v:val.render()')
+  let breakpoints .= &quot;\nException breakpoints: &quot; . join(exceptions, &quot;, &quot;)
   return breakpoints
 endfunction
 
@@ -1611,6 +1653,49 @@ endfunction
 
 &quot; *** Breakpoint class (end)
 
+&quot; *** Exception class (start)
+&quot; These are ruby exceptions we catch with 'catch Exception' command
+&quot; (:RdbCatch)
+
+let s:Exception = { }
+
+&quot; ** Public methods
+
+&quot; Constructor of new exception.
+function! s:Exception.new(name)
+  let var = copy(self)
+  let var.name = a:name
+  call var._log(&quot;Trying to set exception: &quot; . var.name)
+  call g:RubyDebugger.queue.add(var.command())
+  return var
+endfunction
+
+
+&quot; Command for setting exception (e.g.: 'catch NameError')
+function! s:Exception.command() dict
+  return 'catch ' . self.name
+endfunction
+
+
+&quot; Output format for Breakpoints Window
+function! s:Exception.render() dict
+  return self.name
+endfunction
+
+
+&quot; ** Private methods
+
+
+function! s:Exception._log(string) dict
+  call g:RubyDebugger.logger.put(a:string)
+endfunction
+
+
+&quot; *** Exception class (end)
+
+
+
+
 &quot; *** Frame class (start)
 
 let s:Frame = { }</diff>
      <filename>vim/plugin/ruby_debugger.vim</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>7e3e892d5fab5c8d956be43babe8820a2d6699e8</id>
    </parent>
  </parents>
  <author>
    <name>Anton Astashov</name>
    <email>anton@astashov.net</email>
  </author>
  <url>http://github.com/astashov/vim-ruby-debugger/commit/0aef16abe9271dd3dd4afd090d51c5be820eeffc</url>
  <id>0aef16abe9271dd3dd4afd090d51c5be820eeffc</id>
  <committed-date>2009-11-05T18:20:07-08:00</committed-date>
  <authored-date>2009-11-05T18:20:07-08:00</authored-date>
  <message>Added :RdbCatch command. It allows to set exception catchers, if exception is raised, it will show exception message and jump to file/line of the exception. Usage: ':RdbCatch ExceptionName'.</message>
  <tree>38084897445b75391ee7f5fe68f8be83f9ce3716</tree>
  <committer>
    <name>Anton Astashov</name>
    <email>anton@astashov.net</email>
  </committer>
</commit>
