They moved the location of the main application.
But also:
- ignore multiple responses for the same request
- ignore protocol violations for variablesReference (assume 0)
- ignore protocol violations for missing 'name' (assume basename of
path)
The java architecture is a little different:
- the debugger is a jdt.ls extension bundle.
- to start the server, you send a startDebugSession command to jdt.ls
- this returns a tcl port to connect to for DAP
Loading of jdt.ls and the extension are out of scope for vimspector
currently and instead you can tell it to ask you for a port to connect
to.
After connexting to that port, vimspector works as normal.
To support TCP/IP was pretty simple: we provide the same API from
vimscript as the job-based (stdin/out) comms layer, but instead just
directly use a channel.
The only wrinkle was that the java debug adapter broke the protocol on
runInTerminal and didn't return a 'cwd', so we make one up.
We expand environment variables, ~ and workspaceRoot. The latter is to
match vscode and typical launch configs. As we don't know what the
workspeace root might be, we use the location of the .vimspector.json.
Like VSCode does, compbine console and stdout, and allow you to enter
commands in the console. It's all a bit janky right now and the
insertion point isn't ideal (as not all output is interactive) and some
output is asynchronous via a somewhat different channel.
This is starting to get horribly hacky and needs refactoring into
proper classes. Expandable variables now have the following additional
magic properties:
- '_expanded': True (expanded), False (collapsed), none = no preference
- '_variables': Current of child variables
- '_old_variables': The previous state of the '_variables' list when
refreshing
Remember that '_result' (the magic property of a watch expression) is
also treated like an expandable variable, so also has these magic
parameters.
This required working around some sort of bug where the server returns
an invalid content length. Either that or we are somehow processing the
same message twice with additional escaping? It's really strange.
This involves some horrible forceful reading on exit to ensure that we
get a response to the disconnect request. This ensures that any debugee
is killed cleanly.
This shows stack traces as children of a thread, removing one of the
UI splits. However, we still have the somewhat awkward concepts of
"current" thread and "current" stack frame. These are messy and
incredibly fiddly. And in any case, probably wrong _most_ of the time.
This introduced more hacks than it should. In particular, the sequence
about stack trace requesting became very messy. When we attach, we don't
instantly get a stopped event. This required making the Pause command
actually work (sort of). In this case we often won't have a proper
current thread.
Instead we sort of request all threads whenever we get a thread event,
thought his is horribly hacky and we should really just use the thread
event as-is. We then attempt to pause ALL threads on pause and continue
requests when we don't know the current thread.
Another issue is that when pausing it's likely we don't have the source
location info for the pause location (something like select() or
whatever), so we only set the current frame to the lowest one we have
source for. This sort of roughly matches what you want.
This whole thing makes it clear that threads and stack trace in separate
panes makes no sense. We need to replicate the hierarchy in the
variables view for threads and stack traces.
This is a huge hack, setting it manually and never resetting it. Just
displaying the value (no breakdown) etc.
I'm tempted to drop this functionality altogether as it is of limited
use when you have the locals and watch windows.
This actually restricts us to a single debugging pane, but that's really
already a restriction of the vim-side (only one job, etc.). Support for
multiple sessions isn't a priority.
You can currently only add them, not remoove them and you have to pass
the expression in the function call, but once added the variable
breakdown works nicely.
This is a mess, with a load of duplication, but it's a step. When you
request a breakpoint, we add one (in state ENABLED). You can then toggle
it again to change to DISABLED. And once more to delete it.
Once we start the debug server, that all changes and we just start
sending the breakpoints directly to the server and updating based on the
responses. This is far from ideal and somewhat jarring, but this
approach allows me to play around with ideas about what the user
experience should look like.
For line-breakpoints we already know it, so just use what we said
originally. For method breakpoints, we have no clue. While some servers
return a line, it could be in any file, so we just ignore them.