mirror of
https://github.com/VSCodeVim/Vim.git
synced 2024-09-20 00:27:41 +03:00
Implement a few simple ex commands
- `:p[rint]` and friends (arguments still unsupported) - `:te[rminal]` - `:asc[ii]`
This commit is contained in:
parent
3d37bb4898
commit
71d9c1670f
@ -2956,7 +2956,7 @@ class DecrementNumberStaircaseAction extends IncrementDecrementNumberAction {
|
||||
}
|
||||
|
||||
@RegisterAction
|
||||
class CommandUnicodeName extends BaseCommand {
|
||||
export class CommandUnicodeName extends BaseCommand {
|
||||
modes = [Mode.Normal];
|
||||
keys = ['g', 'a'];
|
||||
override runsOnceForEveryCursor() {
|
||||
|
9
src/cmd_line/commands/ascii.ts
Normal file
9
src/cmd_line/commands/ascii.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { CommandUnicodeName } from '../../actions/commands/actions';
|
||||
import { VimState } from '../../state/vimState';
|
||||
import { ExCommand } from '../../vimscript/exCommand';
|
||||
|
||||
export class AsciiCommand extends ExCommand {
|
||||
async execute(vimState: VimState): Promise<void> {
|
||||
await new CommandUnicodeName().exec(vimState.cursorStopPosition, vimState);
|
||||
}
|
||||
}
|
@ -67,7 +67,7 @@ export class CopyCommand extends ExCommand {
|
||||
}
|
||||
|
||||
public override async executeWithRange(vimState: VimState, range: LineRange): Promise<void> {
|
||||
const { start, end } = range.resolve(vimState)!;
|
||||
const { start, end } = range.resolve(vimState);
|
||||
this.copyLines(vimState, start, end);
|
||||
}
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ export class DeleteRangeCommand extends ExCommand {
|
||||
* Ex. if two lines are VisualLine highlighted, :<,>d3 will :d3
|
||||
* from the end of the selected lines.
|
||||
*/
|
||||
const { start, end } = range.resolve(vimState)!;
|
||||
const { start, end } = range.resolve(vimState);
|
||||
if (this.arguments.count) {
|
||||
vimState.cursorStartPosition = new Position(end, 0);
|
||||
await this.execute(vimState);
|
||||
|
@ -9,7 +9,7 @@ export class GotoLineCommand extends ExCommand {
|
||||
|
||||
public override async executeWithRange(vimState: VimState, range: LineRange): Promise<void> {
|
||||
vimState.cursorStartPosition = vimState.cursorStopPosition = vimState.cursorStopPosition
|
||||
.with({ line: range.resolve(vimState)!.end })
|
||||
.with({ line: range.resolve(vimState).end })
|
||||
.obeyStartOfLine(vimState.document);
|
||||
}
|
||||
}
|
||||
|
54
src/cmd_line/commands/print.ts
Normal file
54
src/cmd_line/commands/print.ts
Normal file
@ -0,0 +1,54 @@
|
||||
import { Parser, succeed } from 'parsimmon';
|
||||
import { VimState } from '../../state/vimState';
|
||||
import { StatusBar } from '../../statusBar';
|
||||
import { ExCommand } from '../../vimscript/exCommand';
|
||||
import { Address, LineRange } from '../../vimscript/lineRange';
|
||||
|
||||
type PrintArgs = {
|
||||
printNumbers: boolean;
|
||||
printText: boolean;
|
||||
};
|
||||
|
||||
// TODO: `:l[ist]` is more than an alias
|
||||
// TODO: `:z`
|
||||
export class PrintCommand extends ExCommand {
|
||||
// TODO: Print {count} and [flags]
|
||||
public static readonly argParser = (args: {
|
||||
printNumbers: boolean;
|
||||
printText: boolean;
|
||||
}): Parser<PrintCommand> => succeed(new PrintCommand(args));
|
||||
|
||||
private args: PrintArgs;
|
||||
constructor(args: PrintArgs) {
|
||||
super();
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
async execute(vimState: VimState): Promise<void> {
|
||||
// TODO: Wrong default for `:=`
|
||||
this.executeWithRange(vimState, new LineRange(new Address({ type: 'current_line' })));
|
||||
}
|
||||
|
||||
override async executeWithRange(vimState: VimState, range: LineRange): Promise<void> {
|
||||
const { end } = range.resolve(vimState);
|
||||
|
||||
// For now, we just print the last line.
|
||||
// TODO: Create a dynamic document if there's more than one line?
|
||||
const line = vimState.document.lineAt(end);
|
||||
let output: string;
|
||||
if (this.args.printNumbers) {
|
||||
if (this.args.printText) {
|
||||
output = `${line.lineNumber + 1} ${line.text}`;
|
||||
} else {
|
||||
output = `${line.lineNumber + 1}`;
|
||||
}
|
||||
} else {
|
||||
if (this.args.printText) {
|
||||
output = `${line.text}`;
|
||||
} else {
|
||||
output = '';
|
||||
}
|
||||
}
|
||||
StatusBar.setText(vimState, output);
|
||||
}
|
||||
}
|
@ -57,7 +57,7 @@ export class PutExCommand extends ExCommand {
|
||||
}
|
||||
|
||||
override async executeWithRange(vimState: VimState, range: LineRange): Promise<void> {
|
||||
const { end } = range.resolve(vimState)!;
|
||||
const { end } = range.resolve(vimState);
|
||||
await this.doPut(vimState, new Position(end, 0).getLineEnd());
|
||||
}
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ export class SortCommand extends ExCommand {
|
||||
}
|
||||
|
||||
override async executeWithRange(vimState: VimState, range: LineRange): Promise<void> {
|
||||
const { start, end } = range.resolve(vimState)!;
|
||||
const { start, end } = range.resolve(vimState);
|
||||
|
||||
await this.sortLines(vimState, start, end);
|
||||
}
|
||||
|
@ -412,7 +412,7 @@ export class SubstituteCommand extends ExCommand {
|
||||
}
|
||||
|
||||
override async executeWithRange(vimState: VimState, range: LineRange): Promise<void> {
|
||||
let { start, end } = range.resolve(vimState)!;
|
||||
let { start, end } = range.resolve(vimState);
|
||||
|
||||
if (this.arguments.count && this.arguments.count >= 0) {
|
||||
start = end;
|
||||
|
12
src/cmd_line/commands/terminal.ts
Normal file
12
src/cmd_line/commands/terminal.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { Parser, succeed } from 'parsimmon';
|
||||
import * as vscode from 'vscode';
|
||||
import { VimState } from '../../state/vimState';
|
||||
import { ExCommand } from '../../vimscript/exCommand';
|
||||
|
||||
export class TerminalCommand extends ExCommand {
|
||||
public static readonly argParser: Parser<TerminalCommand> = succeed(new TerminalCommand());
|
||||
|
||||
async execute(vimState: VimState): Promise<void> {
|
||||
await vscode.commands.executeCommand('workbench.action.createTerminalEditor');
|
||||
}
|
||||
}
|
@ -68,7 +68,7 @@ export class YankCommand extends ExCommand {
|
||||
* Ex. if two lines are VisualLine highlighted, :<,>y3 will :y3
|
||||
* from the end of the selected lines.
|
||||
*/
|
||||
const { start, end } = range.resolve(vimState)!;
|
||||
const { start, end } = range.resolve(vimState);
|
||||
if (this.arguments.count) {
|
||||
vimState.cursorStartPosition = new Position(end, 0);
|
||||
await this.execute(vimState);
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { all, alt, optWhitespace, Parser, regexp, seq, string, succeed } from 'parsimmon';
|
||||
import { AsciiCommand } from '../cmd_line/commands/ascii';
|
||||
import { BangCommand } from '../cmd_line/commands/bang';
|
||||
import { BufferDeleteCommand } from '../cmd_line/commands/bufferDelete';
|
||||
import { CloseCommand } from '../cmd_line/commands/close';
|
||||
@ -14,6 +15,7 @@ import { ClearJumpsCommand, JumpsCommand } from '../cmd_line/commands/jumps';
|
||||
import { DeleteMarksCommand, MarksCommand } from '../cmd_line/commands/marks';
|
||||
import { NohlCommand } from '../cmd_line/commands/nohl';
|
||||
import { OnlyCommand } from '../cmd_line/commands/only';
|
||||
import { PrintCommand } from '../cmd_line/commands/print';
|
||||
import { PutExCommand } from '../cmd_line/commands/put';
|
||||
import { QuitCommand } from '../cmd_line/commands/quit';
|
||||
import { ReadCommand } from '../cmd_line/commands/read';
|
||||
@ -24,6 +26,7 @@ import { SmileCommand } from '../cmd_line/commands/smile';
|
||||
import { SortCommand } from '../cmd_line/commands/sort';
|
||||
import { SubstituteCommand } from '../cmd_line/commands/substitute';
|
||||
import { TabCommand } from '../cmd_line/commands/tab';
|
||||
import { TerminalCommand } from '../cmd_line/commands/terminal';
|
||||
import { UndoCommand } from '../cmd_line/commands/undo';
|
||||
import { VsCodeCommand } from '../cmd_line/commands/vscode';
|
||||
import { WallCommand } from '../cmd_line/commands/wall';
|
||||
@ -50,11 +53,12 @@ type ArgParser = Parser<ExCommand>;
|
||||
export const builtinExCommands: ReadonlyArray<[[string, string], ArgParser | undefined]> = [
|
||||
[['', ''], succeed(new GotoLineCommand())],
|
||||
[['!', ''], BangCommand.argParser],
|
||||
[['#', ''], undefined],
|
||||
[['#', ''], PrintCommand.argParser({ printNumbers: true, printText: true })],
|
||||
// TODO: Ignore #! (shebang)
|
||||
[['&', ''], undefined],
|
||||
[['*', ''], undefined],
|
||||
[['<', ''], undefined],
|
||||
[['=', ''], undefined],
|
||||
[['=', ''], PrintCommand.argParser({ printNumbers: true, printText: false })],
|
||||
[['>', ''], undefined],
|
||||
[['@', ''], undefined],
|
||||
[['@@', ''], undefined],
|
||||
@ -74,7 +78,7 @@ export const builtinExCommands: ReadonlyArray<[[string, string], ArgParser | und
|
||||
[['argg', 'lobal'], undefined],
|
||||
[['argl', 'ocal'], undefined],
|
||||
[['argu', 'ment'], undefined],
|
||||
[['as', 'cii'], undefined],
|
||||
[['as', 'cii'], succeed(new AsciiCommand())],
|
||||
[['au', 'tocmd'], undefined],
|
||||
[['aug', 'roup'], undefined],
|
||||
[['aun', 'menu'], undefined],
|
||||
@ -267,7 +271,7 @@ export const builtinExCommands: ReadonlyArray<[[string, string], ArgParser | und
|
||||
[['keepa', 'lt'], undefined],
|
||||
[['keepj', 'umps'], undefined],
|
||||
[['keepp', 'atterns'], undefined],
|
||||
[['l', 'ist'], undefined],
|
||||
[['l', 'ist'], PrintCommand.argParser({ printNumbers: false, printText: true })],
|
||||
[['lN', 'ext'], undefined],
|
||||
[['lNf', 'ile'], undefined],
|
||||
[['la', 'st'], undefined],
|
||||
@ -359,7 +363,7 @@ export const builtinExCommands: ReadonlyArray<[[string, string], ArgParser | und
|
||||
[['noreme', 'nu'], undefined],
|
||||
[['norm', 'al'], undefined],
|
||||
[['nos', 'wapfile'], undefined],
|
||||
[['nu', 'mber'], undefined],
|
||||
[['nu', 'mber'], PrintCommand.argParser({ printNumbers: true, printText: true })],
|
||||
[['nun', 'map'], undefined],
|
||||
[['nunme', 'nu'], undefined],
|
||||
[['ol', 'dfiles'], undefined],
|
||||
@ -373,7 +377,7 @@ export const builtinExCommands: ReadonlyArray<[[string, string], ArgParser | und
|
||||
[['ou', 'nmap'], undefined],
|
||||
[['ounme', 'nu'], undefined],
|
||||
[['ow', 'nsyntax'], undefined],
|
||||
[['p', 'rint'], undefined],
|
||||
[['p', 'rint'], PrintCommand.argParser({ printNumbers: false, printText: true })],
|
||||
[['pa', 'ckadd'], undefined],
|
||||
[['packl', 'oadall'], undefined],
|
||||
[['pc', 'lose'], undefined],
|
||||
@ -522,7 +526,7 @@ export const builtinExCommands: ReadonlyArray<[[string, string], ArgParser | und
|
||||
[['tags', ''], undefined],
|
||||
[['tc', 'd'], undefined],
|
||||
[['tch', 'dir'], undefined],
|
||||
[['te', 'rminal'], undefined],
|
||||
[['te', 'rminal'], TerminalCommand.argParser],
|
||||
[['tf', 'irst'], undefined],
|
||||
[['th', 'row'], undefined],
|
||||
[['tj', 'ump'], undefined],
|
||||
|
@ -292,7 +292,7 @@ export class LineRange {
|
||||
return new LineRange(start);
|
||||
});
|
||||
|
||||
public resolve(vimState: VimState): { start: number; end: number } | undefined {
|
||||
public resolve(vimState: VimState): { start: number; end: number } {
|
||||
// TODO: *,4 is not a valid range
|
||||
const end = this.end ?? this.start;
|
||||
|
||||
@ -329,7 +329,7 @@ export class LineRange {
|
||||
}
|
||||
|
||||
public resolveToRange(vimState: VimState): Range {
|
||||
const { start, end } = this.resolve(vimState)!;
|
||||
const { start, end } = this.resolve(vimState);
|
||||
return new Range(new Position(start, 0), new Position(end, 0).getLineEnd());
|
||||
}
|
||||
|
||||
|
@ -219,6 +219,10 @@ suite('Ex command parsing', () => {
|
||||
exParseTest(':marks 0 1', new MarksCommand(['0', '1']));
|
||||
});
|
||||
|
||||
suite(':p[rint]', () => {
|
||||
// TODO
|
||||
});
|
||||
|
||||
suite(':pu[t]', () => {
|
||||
exParseTest(':put', new PutExCommand({ bang: false, register: undefined }));
|
||||
exParseTest(':put!', new PutExCommand({ bang: true, register: undefined }));
|
||||
|
Loading…
Reference in New Issue
Block a user