mirror of
https://github.com/VSCodeVim/Vim.git
synced 2024-08-16 15:50:35 +03:00
Add tabs movement and fix tab command with correct counting (#507)
This commit is contained in:
parent
00f094af7c
commit
caf3f0e859
44
ROADMAP.md
44
ROADMAP.md
@ -12,9 +12,9 @@
|
||||
|
||||
## Roadmap
|
||||
|
||||
These are the big Vim features, put generally in the order in which we plan to implement them.
|
||||
These are the big Vim features, put generally in the order in which we plan to implement them.
|
||||
|
||||
Status | Command
|
||||
Status | Command
|
||||
---|--------
|
||||
:white_check_mark: | Normal Mode
|
||||
:white_check_mark: | Insert Mode
|
||||
@ -23,16 +23,16 @@ Status | Command
|
||||
:white_check_mark: | Number Prefixes
|
||||
:white_check_mark: | . Operator
|
||||
:warning: | Searching with / and ?
|
||||
:white_check_mark: | Correct Undo/Redo
|
||||
:white_check_mark: | Correct Undo/Redo
|
||||
:warning: | Command Remapping
|
||||
:warning: | Marks
|
||||
:warning: | Text Objects
|
||||
| Visual Block Mode
|
||||
| Macros
|
||||
:warning: | Buffer/Window/Tab
|
||||
:warning: | Buffer/Window/Tab
|
||||
|
||||
|
||||
Now follows an exhaustive list of every known Vim command that we could find.
|
||||
Now follows an exhaustive list of every known Vim command that we could find.
|
||||
|
||||
## Left-right motions
|
||||
|
||||
@ -243,9 +243,9 @@ Status | Command | Description
|
||||
|
||||
Status | Command | Description
|
||||
---|--------|------------------------------
|
||||
:white_check_mark: | v | start highlighting characters
|
||||
:white_check_mark: | V | start highlighting linewise
|
||||
| CTRL-V | start highlighting blockwise
|
||||
:white_check_mark: | v | start highlighting characters
|
||||
:white_check_mark: | V | start highlighting linewise
|
||||
| CTRL-V | start highlighting blockwise
|
||||
| o | exchange cursor position with start of highlighting
|
||||
| gv | start highlighting on previous visual area
|
||||
:white_check_mark: | v | highlight characters or stop highlighting
|
||||
@ -297,7 +297,7 @@ Status | Command | Description
|
||||
:arrow_down: | :so[urce]! {file} | read Vim commands from {file}
|
||||
:arrow_down: | :sl[eep] [sec] | don't do anything for [sec] seconds
|
||||
:arrow_down: | :1234: gs | goto Sleep for N seconds
|
||||
|
||||
|
||||
|
||||
## Marks and motions
|
||||
|
||||
@ -359,8 +359,8 @@ Status | Command | Description
|
||||
| CTRL-D | delete one shiftwidth of indent in front of the current line
|
||||
| 0 CTRL-D | delete all indent in the current line
|
||||
| ^ CTRL-D | delete all indent in the current line, restore indent in next line
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Scrolling
|
||||
|
||||
@ -397,17 +397,23 @@ Status | Command | Description
|
||||
| :vne[w] | Create a new window vertically and start editing an empty file in it.
|
||||
|
||||
|
||||
## Tabs
|
||||
## Tabs
|
||||
|
||||
Status | Command | Description
|
||||
---|--------|------------------------------
|
||||
:warning: | :1234: :tabe[dit] | Open a new tab page with an empty window, after the current tab page
|
||||
:warning: | :1234: :tabnew | Open a new tab page with an empty window, after the current tab page
|
||||
:warning: | :tabc[lose][!] :1234: | Close current tab page.
|
||||
:warning: | :tabo[nly][!] | Close all other tab pages.
|
||||
:white_check_mark: | :tabn[ext] :1234: | Go to tab page {count}. The first tab page has number one.
|
||||
:white_check_mark: | :tabn[ext] :1234: | Go to next tab page or tab page {count}. The first tab page has number one.
|
||||
| {count}<C-PageDown>, {count}gt | Same as above
|
||||
:white_check_mark: | :tabp[revious] :1234: | Go to the previous tab page. Wraps around from the first one to the last one.
|
||||
:white_check_mark: | :tabN[ext] :1234: | Same as above
|
||||
| {count}<C-PageUp>, {count}gT | Same as above
|
||||
:white_check_mark: | :tabfir[st] | Go to the first tab page.
|
||||
:white_check_mark: | :tabl[ast] | Go to the last tab page.
|
||||
:x: | :tabls | List the tab pages and the windows they contain.
|
||||
:x: | :tabm[ove] [N] | Move the current tab page to after tab page N.
|
||||
:warning: | :tabe[dit] {file} | Open a new tab page with an empty window, after the current tab page
|
||||
| :[count]tabe[dit], :[count]tabnew | Same as above
|
||||
:warning: | :tabnew {file} | Open a new tab page with an empty window, after the current tab page
|
||||
| :[count]tab {cmd} | Execute {cmd} and when it opens a new window open a new tab page instead.
|
||||
:warning: | :tabc[lose][!] :1234: | Close current tab page or close tab page {count}.
|
||||
:warning: | :tabo[nly][!] | Close all other tab pages.
|
||||
:white_check_mark: | :tabm[ove] [N] | Move the current tab page to after tab page N.
|
||||
:x: | :tabs | List the tab pages and the windows they contain.
|
||||
| :tabd[o] {cmd} | Execute {cmd} in each tab page.
|
||||
|
@ -10,12 +10,13 @@ export enum Tab {
|
||||
Last,
|
||||
New,
|
||||
Close,
|
||||
Only
|
||||
Only,
|
||||
Move
|
||||
}
|
||||
|
||||
export interface ITabCommandArguments extends node.ICommandArgs {
|
||||
tab: Tab;
|
||||
count: number;
|
||||
count?: number;
|
||||
}
|
||||
|
||||
//
|
||||
@ -45,25 +46,56 @@ export class TabCommand extends node.CommandBase {
|
||||
execute() : void {
|
||||
switch (this._arguments.tab) {
|
||||
case Tab.Next:
|
||||
this.executeCommandWithCount(this._arguments.count, "workbench.action.nextEditor");
|
||||
if (this._arguments.count /** not undefined or 0 */) {
|
||||
vscode.commands.executeCommand("workbench.action.openEditorAtIndex1");
|
||||
this.executeCommandWithCount(this._arguments.count! - 1, "workbench.action.nextEditor");
|
||||
} else {
|
||||
this.executeCommandWithCount(1, "workbench.action.nextEditor");
|
||||
}
|
||||
break;
|
||||
case Tab.Previous:
|
||||
this.executeCommandWithCount(this._arguments.count, "workbench.action.previousEditor");
|
||||
if (this._arguments.count !== undefined && this._arguments.count <= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
this.executeCommandWithCount(this._arguments.count || 1, "workbench.action.previousEditor");
|
||||
break;
|
||||
case Tab.First:
|
||||
this.executeCommandWithCount(this._arguments.count, "workbench.action.openEditorAtIndex1");
|
||||
this.executeCommandWithCount(1, "workbench.action.openEditorAtIndex1");
|
||||
break;
|
||||
case Tab.Last:
|
||||
this.executeCommandWithCount(this._arguments.count, "workbench.action.openLastEditorInGroup");
|
||||
this.executeCommandWithCount(1, "workbench.action.openLastEditorInGroup");
|
||||
break;
|
||||
case Tab.New:
|
||||
this.executeCommandWithCount(this._arguments.count, "workbench.action.files.newUntitledFile");
|
||||
this.executeCommandWithCount(1, "workbench.action.files.newUntitledFile");
|
||||
break;
|
||||
case Tab.Close:
|
||||
this.executeCommandWithCount(this._arguments.count, "workbench.action.closeActiveEditor");
|
||||
// Navigate the correct position
|
||||
if (this._arguments.count === undefined) {
|
||||
vscode.commands.executeCommand("workbench.action.closeActiveEditor");
|
||||
break;
|
||||
}
|
||||
|
||||
if (this._arguments.count === 0) {
|
||||
// Wrong paramter
|
||||
break;
|
||||
}
|
||||
|
||||
// TODO: Close Page {count}. Page count is one-based.
|
||||
break;
|
||||
case Tab.Only:
|
||||
this.executeCommandWithCount(this._arguments.count, "workbench.action.closeOtherEditors");
|
||||
this.executeCommandWithCount(1, "workbench.action.closeOtherEditors");
|
||||
break;
|
||||
case Tab.Move:
|
||||
if (this._arguments.count !== undefined) {
|
||||
if (this._arguments.count === 0) {
|
||||
vscode.commands.executeCommand("activeEditorMove", { to: "first" });
|
||||
} else {
|
||||
vscode.commands.executeCommand("activeEditorMove", { to: "position", amount: this._arguments.count);
|
||||
}
|
||||
} else {
|
||||
vscode.commands.executeCommand("activeEditorMove", { to: "last" });
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -23,6 +23,8 @@ export const commandParsers = {
|
||||
|
||||
tabp: tabCmd.parseTabPCommandArgs,
|
||||
tabprevious: tabCmd.parseTabPCommandArgs,
|
||||
tabN: tabCmd.parseTabPCommandArgs,
|
||||
tabNext: tabCmd.parseTabPCommandArgs,
|
||||
|
||||
tabfirst: tabCmd.parseTabFirstCommandArgs,
|
||||
tabfir: tabCmd.parseTabFirstCommandArgs,
|
||||
@ -40,6 +42,8 @@ export const commandParsers = {
|
||||
tabo: tabCmd.parseTabOnlyCommandArgs,
|
||||
tabonly: tabCmd.parseTabOnlyCommandArgs,
|
||||
|
||||
tabm: tabCmd.parseTabMovementCommandArgs,
|
||||
|
||||
e: fileCmd.parseEditFileCommandArgs,
|
||||
|
||||
s: parseSubstituteCommandArgs,
|
||||
|
@ -3,22 +3,22 @@
|
||||
import * as node from "../commands/tab";
|
||||
import {Scanner} from '../scanner';
|
||||
|
||||
function parseCount(args: string): number {
|
||||
function parseCount(args: string): number | undefined {
|
||||
if (!args) {
|
||||
return 1;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let scanner = new Scanner(args);
|
||||
scanner.skipWhiteSpace();
|
||||
|
||||
if (scanner.isAtEof) {
|
||||
return 1;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let c = scanner.next();
|
||||
let count = Number.parseInt(c);
|
||||
|
||||
if (Number.isInteger(count) && count > 0 ) {
|
||||
if (Number.isInteger(count) && count >= 0 ) {
|
||||
if (count > 999) {
|
||||
count = 999;
|
||||
}
|
||||
@ -29,6 +29,10 @@ function parseCount(args: string): number {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* :tabn[ext] Go to the next tab page.
|
||||
* :tabn[ext] {count} Go to tab page {count}.
|
||||
*/
|
||||
export function parseTabNCommandArgs(args : string) : node.TabCommand {
|
||||
return new node.TabCommand({
|
||||
tab: node.Tab.Next,
|
||||
@ -36,6 +40,10 @@ export function parseTabNCommandArgs(args : string) : node.TabCommand {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* :tabp[revious] Go to the previous tab page. Wraps around from the first one to the last one.
|
||||
* :tabp[revious] {count} Go {count} tab pages back.
|
||||
*/
|
||||
export function parseTabPCommandArgs(args : string) : node.TabCommand {
|
||||
return new node.TabCommand({
|
||||
tab: node.Tab.Previous,
|
||||
@ -43,41 +51,55 @@ export function parseTabPCommandArgs(args : string) : node.TabCommand {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* :tabfir[st] Go to the first tab page.
|
||||
*/
|
||||
export function parseTabFirstCommandArgs(args : string) : node.TabCommand {
|
||||
return new node.TabCommand({
|
||||
tab: node.Tab.First,
|
||||
count: 1
|
||||
tab: node.Tab.First
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* :tabl[ast] Go to the last tab page.
|
||||
*/
|
||||
export function parseTabLastCommandArgs(args : string) : node.TabCommand {
|
||||
return new node.TabCommand({
|
||||
tab: node.Tab.Last,
|
||||
count: 1
|
||||
tab: node.Tab.Last
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* :tabe[dit]
|
||||
* :tabnew Open a new tab page with an empty window, after the current tab page.
|
||||
*/
|
||||
export function parseTabNewCommandArgs(args: string) : node.TabCommand {
|
||||
// New Tab command should support `count`
|
||||
// And the new created Tab's position depends on `count`
|
||||
// For now VS Code only allows open tab next to current Tab
|
||||
// So `count == 0` is not possible. But we can workaround this once we can move tabs through API.
|
||||
// TODO: Tab New takes parameter file name.
|
||||
return new node.TabCommand({
|
||||
tab: node.Tab.New,
|
||||
count: 1
|
||||
tab: node.Tab.New
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* :tabc[lose][!] Close current tab page.
|
||||
* :tabc[lose][!] {count}. Close tab page {count}.
|
||||
*/
|
||||
export function parseTabCloseCommandArgs(args: string) : node.TabCommand {
|
||||
return new node.TabCommand({
|
||||
tab: node.Tab.Close,
|
||||
count: 1
|
||||
count: parseCount(args)
|
||||
});
|
||||
}
|
||||
|
||||
export function parseTabOnlyCommandArgs(args: string) : node.TabCommand {
|
||||
return new node.TabCommand({
|
||||
tab: node.Tab.Only,
|
||||
count: 1
|
||||
tab: node.Tab.Only
|
||||
});
|
||||
}
|
||||
|
||||
export function parseTabMovementCommandArgs(args: string) : node.TabCommand {
|
||||
return new node.TabCommand({
|
||||
tab: node.Tab.Move,
|
||||
count: parseCount(args)
|
||||
});
|
||||
}
|
Loading…
Reference in New Issue
Block a user