Update tabs sample to match finalized API and link to website

This commit is contained in:
Logan Ramos
2022-05-27 14:46:59 -04:00
parent 1fedd4b932
commit 9f3373f057
6 changed files with 21 additions and 15709 deletions

View File

@ -1,6 +1,6 @@
# Tabs API Sample
This sample demonstrates usage of [the tabs api](https://code.visualstudio.com/api/advanced-topics/using-proposed-api). This sample utilizes the tabs API to create a simple tab cleaner. Tabs will be closed after a configurable amount of inactivity. This threshold can be set via the `tabs.maxInactiveTime` setting.
This sample demonstrates usage of [the tabs api](https://code.visualstudio.com/api/references/vscode-api#Tab) . This sample utilizes the tabs API to create a simple tab cleaner. Tabs will be closed after a configurable amount of inactivity. This threshold can be set via the `tabs.maxInactiveTime` setting.
## VS Code API

View File

@ -7,15 +7,14 @@
"": {
"name": "tabs-api-sample",
"version": "0.0.1",
"hasInstallScript": true,
"license": "MIT",
"devDependencies": {
"@types/node": "^16.11.7",
"@types/vscode": "^1.67.0",
"@typescript-eslint/eslint-plugin": "^5.17.0",
"@typescript-eslint/parser": "^5.17.0",
"eslint": "^8.12.0",
"typescript": "^4.6.3",
"vscode-dts": "^0.3.3"
"typescript": "^4.6.3"
},
"engines": {
"vscode": "^1.67.0"
@ -108,6 +107,12 @@
"integrity": "sha512-GZ7bu5A6+4DtG7q9GsoHXy3ALcgeIHP4NnL0Vv2wu0uUB/yQex26v0tf6/na1mm0+bS9Uw+0DFex7aaKr2qawQ==",
"dev": true
},
"node_modules/@types/vscode": {
"version": "1.67.0",
"resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.67.0.tgz",
"integrity": "sha512-GH8BDf8cw9AC9080uneJfulhSa7KHSMI2s/CyKePXoGNos9J486w2V4YKoeNUqIEkW4hKoEAWp6/cXTwyGj47g==",
"dev": true
},
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "5.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.17.0.tgz",
@ -1008,15 +1013,6 @@
"integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
"dev": true
},
"node_modules/kleur": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
"integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==",
"dev": true,
"engines": {
"node": ">=6"
}
},
"node_modules/levn": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
@ -1082,12 +1078,6 @@
"node": "*"
}
},
"node_modules/minimist": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
"dev": true
},
"node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@ -1186,19 +1176,6 @@
"node": ">= 0.8.0"
}
},
"node_modules/prompts": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/prompts/-/prompts-2.2.1.tgz",
"integrity": "sha512-VObPvJiWPhpZI6C5m60XOzTfnYg/xc/an+r9VYymj9WJW3B/DIH+REzjpAACPf8brwPeP+7vz3bIim3S+AaMjw==",
"dev": true,
"dependencies": {
"kleur": "^3.0.3",
"sisteransi": "^1.0.3"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/punycode": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
@ -1333,12 +1310,6 @@
"node": ">=8"
}
},
"node_modules/sisteransi": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.3.tgz",
"integrity": "sha512-SbEG75TzH8G7eVXFSN5f9EExILKfly7SUvVY5DhhYLvfhKqhDFY0OzevWa/zwak0RLRfWS5AvfMWpd9gJvr5Yg==",
"dev": true
},
"node_modules/slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
@ -1475,20 +1446,6 @@
"integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==",
"dev": true
},
"node_modules/vscode-dts": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/vscode-dts/-/vscode-dts-0.3.3.tgz",
"integrity": "sha512-JfOsWL0NvfVw0UF9bcTjlv1Onz3Ted7cgpPWKWMnHGB+72t/tn8WFDeKLZO42l2k9KJq/NGS9rFC5gZbyI4FTg==",
"dev": true,
"dependencies": {
"minimist": "^1.2.0",
"prompts": "^2.1.0",
"rimraf": "^3.0.0"
},
"bin": {
"vscode-dts": "index.js"
}
},
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
@ -1599,6 +1556,12 @@
"integrity": "sha512-GZ7bu5A6+4DtG7q9GsoHXy3ALcgeIHP4NnL0Vv2wu0uUB/yQex26v0tf6/na1mm0+bS9Uw+0DFex7aaKr2qawQ==",
"dev": true
},
"@types/vscode": {
"version": "1.67.0",
"resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.67.0.tgz",
"integrity": "sha512-GH8BDf8cw9AC9080uneJfulhSa7KHSMI2s/CyKePXoGNos9J486w2V4YKoeNUqIEkW4hKoEAWp6/cXTwyGj47g==",
"dev": true
},
"@typescript-eslint/eslint-plugin": {
"version": "5.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.17.0.tgz",
@ -2244,12 +2207,6 @@
"integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
"dev": true
},
"kleur": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
"integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==",
"dev": true
},
"levn": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
@ -2300,12 +2257,6 @@
"brace-expansion": "^1.1.7"
}
},
"minimist": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
"dev": true
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@ -2380,16 +2331,6 @@
"integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
"dev": true
},
"prompts": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/prompts/-/prompts-2.2.1.tgz",
"integrity": "sha512-VObPvJiWPhpZI6C5m60XOzTfnYg/xc/an+r9VYymj9WJW3B/DIH+REzjpAACPf8brwPeP+7vz3bIim3S+AaMjw==",
"dev": true,
"requires": {
"kleur": "^3.0.3",
"sisteransi": "^1.0.3"
}
},
"punycode": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
@ -2462,12 +2403,6 @@
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"dev": true
},
"sisteransi": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.3.tgz",
"integrity": "sha512-SbEG75TzH8G7eVXFSN5f9EExILKfly7SUvVY5DhhYLvfhKqhDFY0OzevWa/zwak0RLRfWS5AvfMWpd9gJvr5Yg==",
"dev": true
},
"slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
@ -2564,17 +2499,6 @@
"integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==",
"dev": true
},
"vscode-dts": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/vscode-dts/-/vscode-dts-0.3.3.tgz",
"integrity": "sha512-JfOsWL0NvfVw0UF9bcTjlv1Onz3Ted7cgpPWKWMnHGB+72t/tn8WFDeKLZO42l2k9KJq/NGS9rFC5gZbyI4FTg==",
"dev": true,
"requires": {
"minimist": "^1.2.0",
"prompts": "^2.1.0",
"rimraf": "^3.0.0"
}
},
"which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",

View File

@ -1,5 +1,4 @@
{
"enabledApiProposals": ["tabs"],
"name": "tabs-api-sample",
"displayName": "tabs-api-sample",
"description": "Sample showing how to use the tabs api",
@ -20,7 +19,7 @@
"main": "./out/extension.js",
"browser": "./out/extension.js",
"contributes": {
"configuration":{
"configuration": {
"title": "Tabs API Sample",
"id": "tabsSample",
"properties": {
@ -36,17 +35,14 @@
"vscode:prepublish": "npm run compile",
"compile": "tsc -p ./",
"lint": "eslint . --ext .ts,.tsx",
"watch": "tsc -watch -p ./",
"download-api": "vscode-dts dev",
"postdownload-api": "vscode-dts main",
"postinstall": "npm run download-api"
"watch": "tsc -watch -p ./"
},
"devDependencies": {
"@types/node": "^16.11.7",
"@types/vscode": "^1.67.0",
"@typescript-eslint/eslint-plugin": "^5.17.0",
"@typescript-eslint/parser": "^5.17.0",
"eslint": "^8.12.0",
"typescript": "^4.6.3",
"vscode-dts": "^0.3.3"
"typescript": "^4.6.3"
}
}

View File

@ -17,11 +17,11 @@ export function activate(context: vscode.ExtensionContext) {
}));
context.subscriptions.push(vscode.window.tabGroups.onDidChangeTabs(tabChangeEvent => {
// If tabs are closed no longer track their activity
for (const removedTab of tabChangeEvent.removed) {
for (const removedTab of tabChangeEvent.closed) {
activityMap.delete(removedTab);
}
// Update activity map last active time on changed tabs
const changedTabs = [...tabChangeEvent.added, ...tabChangeEvent.changed];
const changedTabs = [...tabChangeEvent.opened, ...tabChangeEvent.changed];
for (const tab of changedTabs) {
// Reset the timer for the tabs last activity
activityMap.set(tab, Date.now());

File diff suppressed because it is too large Load Diff

View File

@ -1,252 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
declare module 'vscode' {
// https://github.com/Microsoft/vscode/issues/15178
// TODO@API name alternatives for TabKind: TabInput, TabOptions,
/**
* The tab represents a single text based resource
*/
export class TabKindText {
/**
* The uri represented by the tab.
*/
readonly uri: Uri;
constructor(uri: Uri);
}
/**
* The tab represents two text based resources
* being rendered as a diff.
*/
export class TabKindTextDiff {
/**
* The uri of the original text resource.
*/
readonly original: Uri;
/**
* The uri of the modified text resource.
*/
readonly modified: Uri;
constructor(original: Uri, modified: Uri);
}
/**
* The tab represents a custom editor.
*/
export class TabKindCustom {
/**
* The uri which the tab is representing.
*/
readonly uri: Uri;
/**
* The type of custom editor.
*/
readonly viewType: string;
constructor(uri: Uri, viewType: string);
}
/**
* The tab represents a webview.
*/
export class TabKindWebview {
/**
* The type of webview. Maps to {@linkcode WebviewPanel.viewType WebviewPanel's viewType}
*/
readonly viewType: string;
constructor(viewType: string);
}
/**
* The tab represents a notebook.
*/
export class TabKindNotebook {
/**
* The uri which the tab is representing.
*/
readonly uri: Uri;
/**
* The type of notebook. Maps to {@linkcode NotebookDocument.notebookType NotebookDocuments's notebookType}
*/
readonly notebookType: string;
constructor(uri: Uri, notebookType: string);
}
/**
* The tabs represents two notebooks in a diff configuration.
*/
export class TabKindNotebookDiff {
/**
* The uri of the original notebook.
*/
readonly original: Uri;
/**
* The uri of the modified notebook.
*/
readonly modified: Uri;
readonly notebookType: string;
constructor(original: Uri, modified: Uri, notebookType: string);
}
/**
* The tab represents a terminal in the editor area.
*/
export class TabKindTerminal {
constructor();
}
/**
* Represents a tab within a {@link TabGroup group of tabs}.
* Tabs are merely the graphical representation within the editor area.
* A backing editor is not a guarantee.
*/
export interface Tab {
/**
* The text displayed on the tab
*/
readonly label: string;
/**
* The group which the tab belongs to
*/
readonly group: TabGroup;
/**
* Defines the structure of the tab i.e. text, notebook, custom, etc.
* Resource and other useful properties are defined on the tab kind.
*/
readonly kind: TabKindText | TabKindTextDiff | TabKindCustom | TabKindWebview | TabKindNotebook | TabKindNotebookDiff | TabKindTerminal | unknown;
/**
* Whether or not the tab is currently active.
* This is dictated by being the selected tab in the group
*/
readonly isActive: boolean;
/**
* Whether or not the dirty indicator is present on the tab
*/
readonly isDirty: boolean;
/**
* Whether or not the tab is pinned (pin icon is present)
*/
readonly isPinned: boolean;
/**
* Whether or not the tab is in preview mode.
*/
readonly isPreview: boolean;
}
export namespace window {
/**
* Represents the grid widget within the main editor area
*/
export const tabGroups: TabGroups;
}
export interface TabChangeEvent {
// TODO@API consider: opened
readonly added: readonly Tab[];
// TODO@API consider: closed (aligns with TabGroups.close(...))
readonly removed: readonly Tab[];
readonly changed: readonly Tab[];
}
/**
* Represents a group of tabs. A tab group itself consists of multiple tab
*/
export interface TabGroup {
/**
* Whether or not the group is currently active.
*
* *Note* that only one tab group is active at a time, but that multiple tab
* groups can have an {@link TabGroup.aciveTab active tab}.
*
* @see {@link Tab.isActive}
*/
readonly isActive: boolean;
/**
* The view column of the group
*/
readonly viewColumn: ViewColumn;
/**
* The active {@link Tab tab} in the group. This is the tab which contents are currently
* being rendered.
*
* *Note* that there can be one active tab per group but there can only be one {@link TabGroups.activeTabGroup active group}.
*/
readonly activeTab: Tab | undefined;
/**
* The list of tabs contained within the group.
* This can be empty if the group has no tabs open.
*/
readonly tabs: readonly Tab[];
}
export interface TabGroups {
/**
* All the groups within the group container
*/
readonly all: readonly TabGroup[];
/**
* The currently active group
*/
readonly activeTabGroup: TabGroup;
/**
* An {@link Event event} which fires when {@link TabGroup tab groups} have changed.
*/
// TODO@API consider `TabGroupChangeEvent` similar to `TabChangeEvent`
readonly onDidChangeTabGroups: Event<readonly TabGroup[]>;
/**
* An {@link Event event} which fires when {@link Tab tabs} have changed.
*/
readonly onDidChangeTabs: Event<TabChangeEvent>;
/**
* Closes the tab. This makes the tab object invalid and the tab
* should no longer be used for further actions.
* Note: In the case of a dirty tab, a confirmation dialog will be shown which may be cancelled. If cancelled the tab is still valid
*
* @param tab The tab to close.
* @param preserveFocus When `true` focus will remain in its current position. If `false` it will jump to the next tab.
* @returns A promise that resolves to `true` when all tabs have been closed
*/
close(tab: Tab | readonly Tab[], preserveFocus?: boolean): Thenable<boolean>;
/**
* Closes the tab group. This makes the tab group object invalid and the tab group
* should no longer be used for furhter actions.
* @param tabGroup The tab group to close.
* @param preserveFocus When `true` focus will remain in its current position.
* @returns A promise that resolves to `true` when all tab groups have been closed
*/
close(tabGroup: TabGroup | readonly TabGroup[], preserveFocus?: boolean): Thenable<boolean>;
/**
* Moves a tab to the given index within the column.
* If the index is out of range, the tab will be moved to the end of the column.
* If the column is out of range, a new one will be created after the last existing column.
*
* @package tab The tab to move.
* @param viewColumn The column to move the tab into
* @param index The index to move the tab to
*/
// TODO@API remove for now
move(tab: Tab, viewColumn: ViewColumn, index: number, preserveFocus?: boolean): Thenable<void>;
}
}