Skip to content

Instantly share code, notes, and snippets.

@x-yuri
Last active July 31, 2024 06:11
Show Gist options
  • Save x-yuri/c6bcb99c9ca81330fd27a74684194323 to your computer and use it in GitHub Desktop.
Save x-yuri/c6bcb99c9ca81330fd27a74684194323 to your computer and use it in GitHub Desktop.
vscode notes

vscode notes

The shellIntegration-bash.sh is started this way:

(VS Code Internal)
TerminalService.constructor() -> this._initializePrimaryBackend()
TerminalService._initializePrimaryBackend() -> reconnectedPromise.then(() => this._setConnected() )
TerminalService._setConnected() -> this.onDidChangeConnectionState.fire()
TerminalViewPane.renderBody() -> this._terminalService.onDidChangeConnectionState(() => this._initializeTerminal() )
TerminalViewPane._initializeTerminal() -> this._terminalService.createTerminal()
TerminalService.createTerminal() -> this._createTerminal()
TerminalService._createTerminal() -> this._terminalGroupService.createGroup()
TerminalGroupService.createGroup() -> this._instantiationService.createInstance(TerminalGroup)
...
TerminalGroup.constructor() -> this.addInstance()
TerminalGroup.addInstance() -> this._terminalInstanceService.createInstance()
TerminalInstanceService.createInstance() -> this._instantiationService.createInstance(TerminalInstance)
...
TerminalInstance.constructor() -> this._xtermReadyPromise.then(() => this._createProcess() )
TerminalInstance._createProcess() -> this._processManager.createProcess()
TerminalProcessManager.createProcess() -> this._launchLocalProcess()
TerminalProcessManager._launchLocalProcess() -> backend.createProcess()
LocalTerminalBackend.createProcess() -> this._proxy.createProcess()
ProxyChannel.toService() -> return new Proxy() -> get('createProcess') -> channel.call()
getDelayedChannel() -> {call: () => promise.then(() => c.call() )}
ChannelClient.getChannel() -> {call: () => that.requestPromise() }
ChannelClient.requestPromise() -> new Promise(() => this.sendRequest() )
ChannelClient.sendRequest() -> this.send()
ChannelClient.send() -> this.sendBuffer()
ChannelClient.sendBuffer() -> this.protocol.send()
Protocol.send() -> this.port.postMessage()
(pty host)
Event.fromNodeEventEmitter() -> result.fire()
Emitter.fire() -> this._deliverQueue()
Emitter._deliverQueue() -> this._deliver()
Emitter._deliver() -> listener.value()
ChannelServer.constructor() -> this.protocol.onMessage(() => this.onRawMessage() )
ChannelServer.onRawMessage() -> this.onPromise()
ChannelServer.onPromise() -> channel.call()
-> ProxyChannel.fromService() -> new class {call: () => target.apply() }
-> traceRpc() -> descriptor[fnKey] = () => fn.apply()
-> PtyService.createProcess() -> new TerminalProcess()
-> PtyService.createProcess() -> new PersistentTerminalProcess()
-> PtyService.createProcess() -> return id
ChannelServer.onPromise() -> promise.then(() => this.sendResponse() )
ChannelServer.sendResponse() -> this.send()
ChannelServer.send() -> this.sendBuffer()
ChannelServer.sendBuffer() -> this.protocol.send()
Protocol.send() -> this.port.postMessage()
...
(VS Code Internal)
LocalTerminalBackend.createProcess() -> id = this._proxy.createProcess()
LocalTerminalBackend.createProcess() -> new LocalPty()
LocalPty.constructor() -> super()
LocalTerminalBackend.createProcess() -> return pty
TerminalProcessManager._launchLocalProcess() -> return backend.createProcess()
TerminalProcessManager.createProcess() -> newProcess = this._launchLocalProcess()
TerminalProcessManager.createProcess() -> newProcess.start()
LocalPty.start() -> this._proxy.start()
...
(pty host)
traceRpc() -> descriptor[fnKey] = () => fn.apply()
PtyService.start() -> pty.start()
PersistentTerminalProcess.start() -> this._terminalProcess.start()
TerminalProcess.start() -> this.setupPtyProcess()
TerminalProcess.setupPtyProcess() -> spawn()

Launching a debug session

Eventually there are 3 windows here: a window with a vscode repository, a window with a vscode-js-debug repository and a window with a nextjs project.

After F5 in the first window the second window appears.

After F5 in the second window a new debug session is started:

name: Extension
request: launch
type: extensionHost (pwa-extensionHost)

It sends $startDASession and $sendDAMessage (command: launch) to the debugger:

After the launch request is processed (RawDebugSession.launchOrAttach() -> this.send()) the third window appears and apparently another instance of VS Code Internal is launched (for vscode-js-debug).

Both instances of VS Code Internal receive an AttachSession event. The second instance doesn't have the target session, so the handler does nothing. The first instance sends $startDASession and $sendDAMessage (command: attach) to the debugger:

Then a MainThreadDebugService.$startDebugging() RPC call is received by the first instance:

Config:

name: Extension Host [0]
type: pwa-chrome
request: launch

Which creates a child debug session, sends $startDASession and $sendDAMessage (command: launch) to the debugger:

Press F5 in the third window (the second VS Code Internal instance). This sends $startDASession to vscode-js-debug:

name: Next.js: debug server-side
type: node-terminal
request: launch

vscode-js-debug receives it, starts a named pipe server and starts listening to requests:

Then we're back in the second VS Code Internal instance, which sends a launch request to vscode-js-debug:

Which vscode-js-debug receives. In response it sends a npm run dev command to MainThreadTerminalService:

MainThreadTerminalService receives it and sends it to the pty host:

Pty host receives it and sends it to the shellIntegration-bash.sh process:

Pty host uses ps to discover new child processes:

TerminalProcess.setupPtyProcess() -> new ChildProcessMonitor()
TerminalProcess._doWrite() -> this._childProcessMonitor?.handleInput()
ChildProcessMonitor.handleInput() -> this._refreshActive()
ChildProcessMonitor._refreshActive() -> listProcesses()
listProcesses() -> new Promise(() => exec('ps.sh') )

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