Skip to content

Commit

Permalink
Merge pull request #2697 from rodcloutier/multisplit_support
Browse files Browse the repository at this point in the history
Add support for grid layout
  • Loading branch information
jpoon authored Oct 5, 2018
2 parents da38f43 + f902afa commit 4a14b14
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 84 deletions.
117 changes: 49 additions & 68 deletions src/cmd_line/commands/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import { Message } from './../../util/message';
const untildify = require('untildify');

export enum FilePosition {
CurrentWindow,
NewWindow,
NewWindowVerticalSplit,
NewWindowHorizontalSplit,
}

export interface IFileCommandArguments extends node.ICommandArgs {
Expand All @@ -32,103 +32,83 @@ export class FileCommand extends node.CommandBase {
get arguments(): IFileCommandArguments {
return this._arguments;
}

getActiveViewColumn(): vscode.ViewColumn {
const active = vscode.window.activeTextEditor;

if (!active) {
return vscode.ViewColumn.One;
async execute(): Promise<void> {
if (this._arguments.bang) {
await vscode.commands.executeCommand('workbench.action.files.revert');
return;
}

return active.viewColumn!;
}

getViewColumnToRight(): vscode.ViewColumn {
const active = vscode.window.activeTextEditor;
// Need to do this before the split since it loses the activeTextEditor
let editorFilePath = vscode.window.activeTextEditor!.document.uri.fsPath;

if (!active) {
return vscode.ViewColumn.One;
// Do the split if requested
let split = false;
if (this._arguments.position === FilePosition.NewWindowVerticalSplit) {
await vscode.commands.executeCommand('workbench.action.splitEditorRight');
split = true;
}

switch (active.viewColumn) {
case vscode.ViewColumn.One:
return vscode.ViewColumn.Two;
case vscode.ViewColumn.Two:
return vscode.ViewColumn.Three;
if (this._arguments.position === FilePosition.NewWindowHorizontalSplit) {
await vscode.commands.executeCommand('workbench.action.splitEditorDown');
split = true;
}

return active.viewColumn!;
}

async execute(): Promise<void> {
if (this._arguments.bang) {
await vscode.commands.executeCommand('workbench.action.files.revert');
return;
}
let hidePreviousEditor = async function() {
if (split === true) {
await vscode.commands.executeCommand('workbench.action.previousEditor');
await vscode.commands.executeCommand('workbench.action.closeActiveEditor');
}
};

// No name was specified
if (this._arguments.name === undefined) {
// Open an empty file
if (this._arguments.position === FilePosition.CurrentWindow) {
await vscode.commands.executeCommand('workbench.action.files.newUntitledFile');
} else {
await vscode.commands.executeCommand('workbench.action.splitEditor');
if (this._arguments.createFileIfNotExists === true) {
await vscode.commands.executeCommand('workbench.action.files.newUntitledFile');
await vscode.commands.executeCommand('workbench.action.closeOtherEditors');
await hidePreviousEditor();
}
return;
}

let filePath = '';

// Using the empty string will request to open a file
if (this._arguments.name === '') {
if (this._arguments.position === FilePosition.NewWindow) {
await vscode.commands.executeCommand('workbench.action.splitEditor');
// No name on split is fine and just return
if (split === true) {
return;
}

const fileList = await vscode.window.showOpenDialog({});
if (fileList) {
const doc = await vscode.workspace.openTextDocument(fileList[0]);
vscode.window.showTextDocument(doc);
filePath = fileList[0].fsPath;
}
return;
}

this._arguments.name = <string>untildify(this._arguments.name);

let filePath = this._arguments.name;
if (!path.isAbsolute(this._arguments.name)) {
let curFilePath = vscode.window.activeTextEditor!.document.uri.fsPath;
filePath = path.join(path.dirname(curFilePath), this._arguments.name);

if (!fs.existsSync(filePath)) {
} else {
// Using a filename, open or create the file
this._arguments.name = <string>untildify(this._arguments.name);
filePath = path.isAbsolute(this._arguments.name)
? this._arguments.name
: path.join(path.dirname(editorFilePath), this._arguments.name);

if (filePath !== editorFilePath && !fs.existsSync(filePath)) {
// if file does not exist and does not have an extension
// try to find it with the same extension
if (path.extname(filePath) === '') {
const pathWithExt = filePath + path.extname(curFilePath);
const pathWithExt = filePath + path.extname(editorFilePath);
if (fs.existsSync(pathWithExt)) {
filePath = pathWithExt;
}
}
if (this._arguments.createFileIfNotExists) {
fs.closeSync(fs.openSync(filePath, 'w'));
} else {
Message.ShowError('This file ' + filePath + ' does not exist.');
return;
}
}
}

// create file
if (!fs.existsSync(filePath)) {
if (this.arguments.createFileIfNotExists) {
fs.closeSync(fs.openSync(filePath, 'w'));
} else {
Message.ShowError('The file ' + filePath + ' does not exist.');
return;
}
}
const doc = await vscode.workspace.openTextDocument(filePath);

let folder = vscode.Uri.file(filePath);
await vscode.commands.executeCommand(
'vscode.open',
folder,
this._arguments.position === FilePosition.NewWindow
? this.getViewColumnToRight()
: this.getActiveViewColumn()
);
vscode.window.showTextDocument(doc);

if (this.arguments.lineNumber) {
vscode.window.activeTextEditor!.revealRange(
Expand All @@ -138,5 +118,6 @@ export class FileCommand extends node.CommandBase {
)
);
}
await hidePreviousEditor();
}
}
23 changes: 13 additions & 10 deletions src/cmd_line/subparser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,19 +71,22 @@ export const commandParsers = {

tabm: tabCmd.parseTabMovementCommandArgs,

s: parseSubstituteCommandArgs,

e: fileCmd.parseEditFileCommandArgs,
ene: fileCmd.parseEditNewFileCommandArgs,
enew: fileCmd.parseEditNewFileCommandArgs,

s: parseSubstituteCommandArgs,
sp: fileCmd.parseEditFileInNewHorizontalWindowCommandArgs,
split: fileCmd.parseEditFileInNewHorizontalWindowCommandArgs,
vs: fileCmd.parseEditFileInNewVerticalWindowCommandArgs,
vsp: fileCmd.parseEditFileInNewVerticalWindowCommandArgs,
vsplit: fileCmd.parseEditFileInNewVerticalWindowCommandArgs,

new: fileCmd.parseEditNewFileInNewHorizontalWindowCommandArgs,
vne: fileCmd.parseEditNewFileInNewVerticalWindowCommandArgs,
vnew: fileCmd.parseEditNewFileInNewVerticalWindowCommandArgs,

vs: fileCmd.parseEditFileInNewWindowCommandArgs,
vsp: fileCmd.parseEditFileInNewWindowCommandArgs,
sp: fileCmd.parseEditFileInNewWindowCommandArgs,
split: fileCmd.parseEditFileInNewWindowCommandArgs,
vsplit: fileCmd.parseEditFileInNewWindowCommandArgs,
ne: fileCmd.parseEditNewFileInNewWindowCommandArgs,
vne: fileCmd.parseEditNewFileInNewWindowCommandArgs,
new: fileCmd.parseEditNewFileInNewWindowCommandArgs,
vnew: fileCmd.parseEditNewFileInNewWindowCommandArgs,
only: parseOnlyCommandArgs,

set: parseOptionsCommandArgs,
Expand Down
40 changes: 34 additions & 6 deletions src/cmd_line/subparsers/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,33 @@ export function parseEditFileCommandArgs(args: string): node.FileCommand {

return new node.FileCommand({
name: name.trim(),
position: node.FilePosition.CurrentWindow,
bang: bang,
createFileIfNotExists: true,
});
}

// Note that this isn't really implemented.
export function parseEditNewFileInNewWindowCommandArgs(args: string): node.FileCommand {
export function parseEditNewFileCommandArgs(): node.FileCommand {
return new node.FileCommand({
name: undefined,
position: node.FilePosition.NewWindow,
createFileIfNotExists: true,
});
}

export function parseEditFileInNewVerticalWindowCommandArgs(args: string): node.FileCommand {
let name = '';

if (args) {
let scanner = new Scanner(args);
name = scanner.nextWord();
}

return new node.FileCommand({
name: name,
position: node.FilePosition.NewWindowVerticalSplit,
});
}

export function parseEditFileInNewWindowCommandArgs(args: string): node.FileCommand {
export function parseEditFileInNewHorizontalWindowCommandArgs(args: string): node.FileCommand {
let name = '';

if (args) {
Expand All @@ -42,6 +54,22 @@ export function parseEditFileInNewWindowCommandArgs(args: string): node.FileComm

return new node.FileCommand({
name: name,
position: node.FilePosition.NewWindow,
position: node.FilePosition.NewWindowHorizontalSplit,
});
}

export function parseEditNewFileInNewVerticalWindowCommandArgs(): node.FileCommand {
return new node.FileCommand({
name: undefined,
createFileIfNotExists: true,
position: node.FilePosition.NewWindowVerticalSplit,
});
}

export function parseEditNewFileInNewHorizontalWindowCommandArgs(): node.FileCommand {
return new node.FileCommand({
name: undefined,
createFileIfNotExists: true,
position: node.FilePosition.NewWindowHorizontalSplit,
});
}
43 changes: 43 additions & 0 deletions test/cmd_line/split.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import * as vscode from 'vscode';

import { getAndUpdateModeHandler } from '../../extension';
import { commandLine } from '../../src/cmd_line/commandLine';
import { ModeHandler } from '../../src/mode/modeHandler';
import {
assertEqual,
cleanUpWorkspace,
setupWorkspace,
WaitForEditorsToClose,
} from './../testUtils';

suite('Horizontal split', () => {
let modeHandler: ModeHandler;

setup(async () => {
await setupWorkspace();
modeHandler = await getAndUpdateModeHandler();
});

teardown(cleanUpWorkspace);

test('Run :sp', async () => {
await commandLine.Run('sp', modeHandler.vimState);
await WaitForEditorsToClose(2);

assertEqual(vscode.window.visibleTextEditors.length, 2, 'Editor did not split in 1 sec');
});

test('Run :split', async () => {
await commandLine.Run('split', modeHandler.vimState);
await WaitForEditorsToClose(2);

assertEqual(vscode.window.visibleTextEditors.length, 2, 'Editor did not split in 1 sec');
});

test('Run :new', async () => {
await commandLine.Run('split', modeHandler.vimState);
await WaitForEditorsToClose(2);

assertEqual(vscode.window.visibleTextEditors.length, 2, 'Editor did not split in 1 sec');
});
});
21 changes: 21 additions & 0 deletions test/cmd_line/vsplit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,25 @@ suite('Vertical split', () => {

assertEqual(vscode.window.visibleTextEditors.length, 2, 'Editor did not split in 1 sec');
});

test('Run :vsplit', async () => {
await commandLine.Run('vsplit', modeHandler.vimState);
await WaitForEditorsToClose(2);

assertEqual(vscode.window.visibleTextEditors.length, 2, 'Editor did not split in 1 sec');
});

test('Run :vnew', async () => {
await commandLine.Run('vnew', modeHandler.vimState);
await WaitForEditorsToClose(2);

assertEqual(vscode.window.visibleTextEditors.length, 2, 'Editor did not split in 1 sec');
});

test('Run :vne', async () => {
await commandLine.Run('vne', modeHandler.vimState);
await WaitForEditorsToClose(2);

assertEqual(vscode.window.visibleTextEditors.length, 2, 'Editor did not split in 1 sec');
});
});

0 comments on commit 4a14b14

Please sign in to comment.