Vscode: Add an API for splitting a terminal

Created on 9 Mar 2018  路  14Comments  路  Source: microsoft/vscode

Here are two options:

export interface TerminalOptions {
  splitFrom?: Terminal
}

or

export interface Terminal {
  split(options: TerminalOptions): Terminal;
}

/cc @fabiospampinato

api api-proposal feature-request integrated-terminal

Most helpful comment

Has there been any movement on this?

All 14 comments

They both look pretty good to me.

Maybe I'm leaning a bit toward the latter, especially if split direction and shell/args/env inheriting were to be implemented in the future, I think this:

export interface TerminalSplitOptions {
  direction: string,
  inherit: boolean
};

export interface Terminal {
  split(options: TerminalOptions, splitOptions?: TerminalSplitOptions): Terminal;
}

Looks a little nicer than this:

export interface TerminalOptions {
  splitFrom?: Terminal
  splitDirection?: string,
  splitInherit?: boolean
}

Has there been any movement on this?

Bump, looks like there hasn't been anything for quite a while. Is this still being worked? Thanks!

Bump again

Note to self: we should probably align to how editor splitting works in the API, also if terminal tabs could be pulled into the editor area how does that affect things?

Adding to October to discuss, it won't happen in October though.

Discussed this in the API meeting today.

Creation vs placement

One big thing that has blocked this has been wanting to wait to see how the API ends up looking once positioning is more dynamic within the editor area and when terminal tabs (https://github.com/microsoft/vscode/issues/10546) has arrived. I don't think we are actually blocked on this for the following reasons:

  • We should not try to combine creation and placement APIs. Take the editor for example, showTextDocument doesn't talk about creation it's primarily an API centered around placing a text document somewhere. I can imagine a showTerminal or moveTerminal API in the future which achieves this not just for moving terminal groups but also 'unsplitting' terminals, we can explore that more in the future though.
  • Splits are not tabs. When we add tabs, splits will remain within a single tab so they will be treated as a whole (ie. a 'terminal group', similar to editor groups).

Split direction

Terminals only split in a single direction, this was initially done for simplicity reasons and because the panel is typically quite narrow. We should probably stick to this philosophy when we allow terminals within tabs, for an elaborate layout it might be better to go with single terminal instances using the editor group's grid system.

Complexity around default split direction within the editor and the ability to toggle the split direction could be provided by commands exposed in the command palette.

Approach

We discussed the following two high-level approaches. Specifying how to split via options:

export interface TerminalOptions {
  splitFrom?: Terminal
}

Or via a method on Terminal:

export interface Terminal {
  split(options: TerminalOptions): Terminal;
}

We preferred the former, the wording needs some refinement but using "beside" to align with ViewColumn.Beside was suggested:

export interface TerminalOptions {
  splitBeside?: Terminal
}

This ties into a parallel discussion we're having in https://github.com/microsoft/vscode/issues/63052#issuecomment-541786538 which would see this terminal exposed on Terminal.creationOptions. An interesting note here is that if the parent that a terminal was split from is disposed then this will keep hold of the disposed terminal reference (just as if you held onto Terminal in some other way). This is how editors work and shouldn't be a big deal.

Restoring terminal layout

If an extension were to restore terminal layout exactly as it was between reloads then it could iterate over window.terminals and identify the layout based on Terminal.splitBeside, unless a terminal is disposed or unless (when we support it) you can unsplit terminals. At that point we would need a dynamic property that specifies what terminal is next to the current terminal, for example:

export interface Terminal {
    // splitBeside as well?
    adjacentTerminal: Terminal | undefined;
}

This is because while TerminalOptions.splitBeside will likely be accessible in the future via Terminal.creationOptions, that one must be static.

Can we add horizontal splitting support into this as well? It would be nice to split code and terminals panes horizontally..

@awarmfastbear I don't think we want to add 2 dimensional splitting to the terminal as that makes it a lot more complicated, however eventually terminal "tabs" will be able to be dragged into the editor space where you will be able to lay them out however you want. When you can do this you will still have single-dimensional splits _inside_ individual tabs.

eventually terminal "tabs" will be able to be dragged into the editor space

@Tyriar Thanks for the info, is there an issue # we can track for that feature?

As a temporally solution until an official API lands you can do something like this:

```js
async createNewSplitTerminal(): Promise {
return new Promise(async (resolve, reject) => {
await vscode.commands.executeCommand("workbench.action.terminal.split");

  vscode.window.onDidChangeActiveTerminal((terminal) => {
    if (terminal) {
      resolve(terminal);
    }
  });
});

}

Any updates?

need it...

Was this page helpful?
0 / 5 - 0 ratings