(wild) Idea: continuous mode #19

teranex opened this Issue Nov 6, 2012 · 21 comments


None yet
6 participants

teranex commented Nov 6, 2012

Just a wild (maybe useless) idea: would it be possible to add a 'continuous mode'? This would be a mode where VDebug would automatically restart to listen (with a large enough timeout) after a request has ended. That would allow one to setup some breakpoints, start the debugger in Vim, and click through the php project until the page is reached which will trigger the breakpoints.
Now most of the times I set my breakpoints, start clicking around to reach the correct page, and before the final click need to remember to, at that moment, start the debugger in vim before continuing.

(obviously this is most useful if you have configured XDebug to automatically open a debug session on the server)


joonty commented Nov 6, 2012

I like it as a concept, it sounds pretty cool.

The only thing is that it wouldn't work if breaking at the first line of the code is enabled - it would stop on every page load! But I can't see any reason why this wouldn't be achievable, so I'll take a look at getting it into the next version.

teranex commented Nov 6, 2012

Breaking at the first line is indeed something which should be disabled, but since this is already possible to configure I don't think it is a problem to expect the user to disable this (or maybe do it automatically in this mode?)

Cool, looking forward to testing it :)!

serebrov commented Nov 9, 2012

+1 for this feature. I came to vim from Netbeans and this is how debug mode works there - you launch it once and it works until you stop it explicitely (the same in Eclipse and other IDEs I tried). This is very convenient when you need to debug through redirects or when you didn't caught the bug from the first try.


joonty commented Nov 13, 2012

This is now available to try! It's currently only in the dev branch, but it would be great if you guys could give it a spin and see whether it works for you.

Basically, Vdebug will start listening immediately after a debugging session finishes, and will start up again on a new request. If you stop the debugger (<F6>) then it won't start listening, or you can Ctrl-C it when it's listening for a connection.

Let me know if there are any improvements I can make.

Thanks for the suggestion!

I tried it and it works very good.
Some notices:

  • Every time when debugger starts/stops listening there are two messages in status line "Debug session has ended" and "Waiting for connection ...". Because of this when it stops on the breakpoint there is vim's message "Press ENTER or type command to continue" and I have to hit "Enter" each time. Maybe there is a way to prevent several messages to appear in status line? If not then maybe do not display "Debug session has ended" at all (there is "stopped" status in the DebuggerStatus block)?
  • With "break_on_open" set to 0 - several sequential requests which do not lead to stop also display several "Waiting for connection ..." messages - is there a way to prevent this (this is related to previous notice)?
  • With "break_on_open" set to 0 - while debugger listens for connection the Vim's UI is blocked and it is not possible to set additional breakpoints. I guess it can be hard or impossible to do, but maybe there is a way to listen and do not block Vim UI at the same time?

In general this new feature is awesome, thanks! Recently I tried several existing debugging solutions for Vim and no other plugins allow to do continuous debugging.

teranex commented Nov 14, 2012

I also tested the feature and found it works really well, except for the small points which are already mentioned by @sebgoo.


joonty commented Nov 14, 2012

Hi guys, thanks very much for the great feedback!

@sebgoo your first two points are very helpful, and I'll get to work on finding a fix for those.

Your final point is a bit more tricky - Python listens in a loop for connections, and since Vim is single threaded it can't run that loop and handle other inputs. I think the only way is to cancel the listening, set the breakpoint and start it up again. It's very annoying though!

Thanks again

Regarding the last point - I suspected something like this. Maybe it is possible to do like this:

  • Plugin checks whether connection is available and if not sets timer (or something else to get launched after some interval)
  • Vim handles it's UI
  • After some interval Vim calls plugin and it checks connection again
  • and so on

So idea is to not wait for connection constantly, but check it time to time.
Anyway if this is not possible or hard to do then it not worth it - it is easy to handle this manually - I stop listening and than set additional breakpoints and run debugger again.


joonty commented Nov 16, 2012

Nice idea, but unfortunately it's not going to be possible. The reason is that Vdebug acts as the server socket that Xdebug (or other engine) will try to connect to. Therefore, Vdebug has to listen in a loop, waiting for incoming connections.

It's not a problem in multi-threaded applications, as the server socket can be created in a new thread, but sadly not possible in Vim :(

Still, I'll see how far I can get in optimising this feature.

Thanks for explanation.
I think this problem (blocking Vim UI while listening) is not related to the current issue (continuous mode) and can be moved to another issue.
And maybe some solution can be found for this later. Another idea - maybe listener can be launched as separate process? There are several Vim plugins which targeted on asynchronous launching of external processes and capturing their output. Here some links

P.S. It is sebgoo, accidentally posted from another github account.


Chronial commented Apr 19, 2013

Your final point is a bit more tricky - Python listens in a loop for connections, and since Vim is single threaded it can't run that loop and handle other inputs. I think the only way is to cancel the listening, set the breakpoint and start it up again. It's very annoying though!

Just a note here: This is not quite correct – you can use Python threads within vim.


joonty commented May 10, 2013

@Chronial you're right, and I've seen the light since originally replying in this issue.

If/when this feature gets implemented it will be a major new release, and I foresee at least two bug-fix releases before then. Still, it would/will be awesome...


joonty commented Jan 14, 2014

After all this time, I'd like to finally announce that I've got a working prototype of this. :shipit:

You can get a sneak preview in the bg-connection branch. It doesn't have any documentation yet, and it's not ready for production, but give it a go if you fancy!

@joonty Thanks! It works very good.
For now I see only one issue in a following scenario (debugging a web app):

  • set a breakpoint somewhere
  • start debugging
  • now vdebug waits for connection and breakpoint marker is green
  • in the browser navigate to the page which triggers a breakpoint
  • switch back go vim - breakpoint is still green until you move a cursor
    So the breakpoint stays green until you move a cursor - not a big issue, but for the first time I didn't realize that debugger is active already.

Thanks one more time this feature is awesome! I will test it more and report issues if any will be found.


joonty commented Jan 16, 2014

Hi @serebrov,

Thanks for giving it a go and providing some feedback!

One thing that probably is worth mentioning is that I've added a vim function, vdebug:statusline(). This returns a useful status message for vdebug, such as vdebug(listening) or vdebug(ready) (for when a connection has been made). You can add that to your vim status line.

The problem that you raised is one that I've known about. Unfortunately, it's the nature of moving the socket listening in to the background, which is that the background thread can't start the debugger when it's ready (vim explodes with segfaults) - instead Vim has to regularly probe the background thread to see whether a connection has been made.

To overcome this I used the vim autocommands CursorHold and CursorMoved. Basically, if you leave Vim long enough OR touch it at all, then it should start. You can turn this feature off by setting the vdebug option auto_start to 0.

These autocommands use vim's updatetime to work out how often to check the connection. By default it's 4000 milliseconds, so you could try setting it to a lower value?

Sorry, that's very detailed. Unfortunately, by it's nature it's a complicated problem! Thanks again for giving it a go.

@Joony Thanks for information.
This is strange but I can not reproduce the problem with green breakpoint anymore. Now when I switch to vim from the browser the breakpoint marker is already red. Before I had wait for a long time (at least 30 seconds) and it did not turn red. And I have updatetime=2000. I will notify you if I find a stable way to reproduce this issue.

Regarding auto_start=0 - now if I set it then debug process does not start at all - browser waits for connection, but debugger UI does not appear in vim. Is auto_start related to other vdebug settings? I have break_on_open=0 and continious_mode=1.

Also found to more things:

  1. In the DebugWatch window - if I expand some complex variable (object / array) then empty line appears above it. So it looks like:
 ⬦ $currentUpdateId = (uninitialized)

 ▾ $this = (UiController [14])
   ⬦ $this->layout = (string [2]) `ui`

And each time I expand / collapse $this it adds more and more space.

  1. When I debug python or php script it looks like this:
  2. open a script, set breakpoint
  3. start debugger
  4. vdebug reports "Found connection, starting debugger"
  5. vim UI is blocked until the breakpoint is reached
  6. vim UI unblocks and I can debug from the breakpoint line
    It would be better if there were no block at the step (4).

joonty commented Jan 16, 2014

Hi @serebrov,

I think I may have confused things with mentioning auto_start. This should be set to 0 if you don't want vdebug to open automatically after a connection has been established. If you set it to 0 then you have to manually start the debugger when a connection is made, with <F5>. Hope that makes sense.

As for the extra line issue, that's been documented in #119.

And finally, the debugger will block when vdebug is actually running. I made the decision to make the connection listening non-blocking, but the actual debugger is still blocking. The reason for this is exactly the same as what I was describing before - trying to use Vim in a multi-threaded way just isn't practical. You can get away with using CursorHold and CursorMoved when waiting for a connection, but it just wouldn't work when using the debugger.

So I'm afraid that will always be the case! What is it that you're wanting to do when vim is blocked?

For auto_start - I get what option does and just tried to test it too. Along with manual start with it works and makes sense.

For debugger block - it is OK to have it this way. Anyway an issue with blocking is most important for web app debugging.
For scripts - the only usecase I have is when I forgot to set a breakpoint. I often use debugger for long-running scripts like functional GUI tests and if vim UI would not be blocked I could have a chance to set the breakpoint if I forgot it or set additional breakpoints.
But as I said it is not very important and it is OK to have it like it is now.


joonty commented Jan 16, 2014

Ah I see, that makes sense.

If I'm honest, I'm not sure that Xdebug would allow you to set a breakpoint while it's running - I think it only reads from the socket when it's paused. I may be wrong about that, but if I'm right then it would mean that making everything non-blocking wouldn't help.

Thanks, I really appreciate all your feedback!

Hi, might I suggest closing this ? I thought this mode didn't exist yet (since the issue is still open) and just stumbled upon on it in the documentation by luck. Like you said here @joonty.

I think this problem (blocking Vim UI while listening) is not related to the current issue (continuous mode) and can be moved to another issue.

Anyone reading this that cares for the solution, the option is

let g:vdebug_options['continuous_mode'] = 1

which you might have to combo with:

let g:vdebug_options['break_on_open'] = 0
let g:vdebug_options['continuous_mode'] = 1

Thanks by the way, this mode is working great 👍


joonty commented Dec 8, 2015

Hi @Dudemullet, thanks for raising this.

While there is a continuous mode in version 1, it doesn't quite fit the brief of the original request, as it blocks the user after a debugging session has ended, until the next one starts. In version 2 I have it working so that it doesn't block, but there are still some things that need to be done to get it production ready. So I said it's not related in a previous comment, but it sort of is related! :P

The reason I left this open was so I could notify everyone in the thread when I get version 2 out. That will happen at some point, promise!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment