Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiline yank writes to 0 register; fixes #1214 #3087

Merged
merged 6 commits into from
Oct 6, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions src/register/register.ts
Original file line number Diff line number Diff line change
Expand Up @@ -302,9 +302,7 @@ export class Register {
*/
private static processNumberedRegister(content: RegisterContent, vimState: VimState): void {
// Find the BaseOperator of the current actions
const baseOperator = vimState.recordedState.actionsRun.find(value => {
return value instanceof BaseOperator || value instanceof BaseCommand;
});
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previously, this code was initializing baseOperator to be CommandNumber in some cases. For example, 5Y is [CommandNumber, CommandYankFullLine], and because CommandNumber inherits from BaseCommand and comes first, baseOperator would be set to that.

Then, the blocks below specifically to handle yanks wouldn't be hit.

export class CommandNumber extends BaseCommand {

const baseOperator = vimState.recordedState.operator || vimState.recordedState.command;

if (baseOperator instanceof YankOperator || baseOperator instanceof CommandYankFullLine) {
// 'yank' to 0 only if no register was specified
Expand Down
2 changes: 1 addition & 1 deletion src/state/recordedState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ export class RecordedState {
* The command (e.g. i, ., R, /) the user wants to run, if there is one.
*/
public get command(): BaseCommand {
const list = _.filter(this.actionsRun, a => a instanceof BaseCommand);
const list = _.filter(this.actionsRun, a => a instanceof BaseCommand).reverse();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I could tell, this get command() isn't actually being used anywhere yet, so this should be a safe change.

However, the comment below brought me pause:

// TODO - disregard , then assert this is of length 1.

If there is only supposed to be one BaseCommand, how come 5Y is two commands? Not familiar with the VSCode Vim codebase, but just wanted to mention this in case it matters.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, what are your thoughts on handling this in the processNumberedRegister call instead? Changing this seems a little bit of a workaround since the get() is currently returning the stack the way it was executed (which seems OK to me)

Not too sure on the TODO comment :/

Copy link
Contributor Author

@jkillian jkillian Oct 5, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, since nobody else seems to be calling get command(), I guess we can define it however we wish. To me, returning the last command seems to make more sense - for example if I ran 5@q I'd expect .command to refer to the macro execution, CommandExecuteMacro as opposed to CommandNumber. Or for something like "aD, I'd expect the D command, CommandDeleteToLineEnd, instead of the register command,CommandRegister.

That said, you know the code better than I do, so happy to do it either way in the end! Both ways will accomplish the same purpose and get this working better which is what matters 😃

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting looks like the getter for operator is reversed, lets just go with this!


// TODO - disregard <Esc>, then assert this is of length 1.

Expand Down
43 changes: 43 additions & 0 deletions test/register/register.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,49 @@ suite('register', () => {
assertEqualLines(['test2', 'test2', 'test3']);
});

test("Multiline yank (`[count]yy`) stores text in Register '0'", async () => {
modeHandler.vimState.editor = vscode.window.activeTextEditor!;

await modeHandler.handleMultipleKeyEvents('itest1\ntest2\ntest3'.split(''));

await modeHandler.handleMultipleKeyEvents([
'<Esc>',
'g',
'g',
'2',
'y',
'y',
'd',
'd',
'"',
'0',
'P',
]);

assertEqualLines(['test1', 'test2', 'test2', 'test3']);
});

test("Multiline yank (`[count]Y`) stores text in Register '0'", async () => {
modeHandler.vimState.editor = vscode.window.activeTextEditor!;

await modeHandler.handleMultipleKeyEvents('itest1\ntest2\ntest3'.split(''));

await modeHandler.handleMultipleKeyEvents([
'<Esc>',
'g',
'g',
'2',
'Y',
'd',
'd',
'"',
'0',
'P',
]);

assertEqualLines(['test1', 'test2', 'test2', 'test3']);
});

test("Register '1'-'9' stores delete content", async () => {
modeHandler.vimState.editor = vscode.window.activeTextEditor!;

Expand Down