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

Emacs text registers #1643

Merged
merged 8 commits into from
Sep 12, 2023
Merged

Conversation

justinhopkins
Copy link
Contributor

Greetings whitphx!

First of all, thank you for maintaining awesome-emacs-mcx! It is unbelievably excellent for emacs nerds like myself.

I've been experimenting with implementing Emacs text registers. "Text registers" are effectively multiple clipboards that you can identify with a single keystroke. Full-blown emacs registers can do a lot, but so far I'm just trying to implement two commands - "register save" and "register insert".

This implementation seems to play nicely with the C-x r commands that work with rectangles.

There are some extensive changes, so I expect you may object to some design decisions. I'm happy to make changes based on your feedback.

Hope to hear from you

Reference:
https://www.gnu.org/software/emacs/manual/html_node/emacs/Text-Registers.html

^ From the documentation:

register save:
C-x r s r
Copy region into register r (copy-to-register).

register insert:
C-x r i r
Insert text from register r (insert-register).

…that play nicely with existing Rect-related commands
…that play nicely with existing Rect-related commands
Copy link
Owner

@whitphx whitphx left a comment

Choose a reason for hiding this comment

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

Thank you very much for your contribution!
Let me point out some things as comments.

Also, CI workflows have not been dispatched maybe because of misconfiguration. I updated the CI definition file on the main branch, so please update this branch with it and see if the CI is triggered.

src/emulator.ts Outdated
@@ -36,8 +38,25 @@ export interface IEmacsController {
registerDisposable: (disposable: vscode.Disposable) => void;
}

export class TextRegister {
Copy link
Owner

Choose a reason for hiding this comment

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

I think you can just use a Map class instead of wrapping it with TextRegister class.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed. I've updated it to just use a Map<string, string>

src/emulator.ts Outdated
i++;
}
const msg = "Running RegisterSaveCommand to " + arg + " with this selection: " + combinedtext;
vscode.window.showInformationMessage(msg);
Copy link
Owner

Choose a reason for hiding this comment

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

Please consider using MessageManager.showMessage which manages the lifespan of each message.

like this:

MessageManager.showMessage("Quit");

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Roger that; changed it

src/emulator.ts Outdated
@@ -93,6 +112,7 @@ export class EmacsEmulator implements IEmacsController, vscode.Disposable {
this.textEditor = textEditor;
this._nativeSelections = this.rectMode ? [] : textEditor.selections; // TODO: `[]` is workaround.

this.textRegister = new TextRegister();
Copy link
Owner

Choose a reason for hiding this comment

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

One EmacsEmulator instance is bound to one document, so looks like this text register is not shared among different documents.
Instead, I think it should be changed so that a single global text register object is initialized in the activate() function in extension.ts and it is passed to each EmacsEmulator instance like killRing.

@@ -541,4 +564,61 @@ export class EmacsEmulator implements IEmacsController, vscode.Disposable {
}
});
}

public saveRegister(arg: string): void {
Copy link
Owner

Choose a reason for hiding this comment

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

It would be great if you write tests for the new commands.
Just leave it if it's hard, as I will make some after merging the PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Understood. Please have a look at how I've modified EmulatorMap and EmacsEmulator to have a textRegister Map(). If this approach looks good, I'll start writing unit tests

let i = 0;
let combinedtext = "";
while (i < selections.length) {
combinedtext = combinedtext + this.textEditor.document.getText(selections[i]);
Copy link
Owner

Choose a reason for hiding this comment

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

While it's not needed in this PR, the copy/paste functions of the kill/yank commands should be shared with these methods. They are compatible with multi-cursors.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

A good point. Still researching

- Changed vscode.window.showInformationMessage() to MessageManager.showMessage()
- Made RegisterSaveCommand de-select the selection after saving the selection
…e document windows (multiple EmacsEmulator objects)
@justinhopkins
Copy link
Contributor Author

Thank you very much for your contribution! Let me point out some things as comments.

Also, CI workflows have not been dispatched maybe because of misconfiguration. I updated the CI definition file on the main branch, so please update this branch with it and see if the CI is triggered.

Re-merged with your changes on 'main' for changes from the .github/workflows/main.yaml.

Do you need me to do anything else for this PR? Would be happy to make changes if I've missed anything.

I'm also kind of waiting for your thoughts about how I've added textRegister as an object passed into the EmacsEmulator. If it looks alright, I'll go ahead and write some test cases for it.

@whitphx
Copy link
Owner

whitphx commented Sep 10, 2023

@justinhopkins Thank you so much for your contributions and sorry for my late reply.
The current implementation looks nice and I think it's ready to write the tests.
Should I leave this PR open until you write the tests, or merge it first?

Copy link
Owner

@whitphx whitphx left a comment

Choose a reason for hiding this comment

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

I tested this locally and found a few things.
Let me suggest them ;)


private acceptingRegisterSaveCommand = false;

public startRegisterSaveCommand(): void {
Copy link
Owner

Choose a reason for hiding this comment

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

Can you make this private?

Copy link
Owner

Choose a reason for hiding this comment

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

Sorry this was originally my bad.
Fixed the original code you referred to as the basis: #1680

src/commands/registers.ts Show resolved Hide resolved
src/emulator.ts Outdated Show resolved Hide resolved
src/emulator.ts Outdated Show resolved Hide resolved
- Made startRegisterSaveCommand() private
- Made textEditor.edit((editBuilder) ...) use await in saveRegister() method
@justinhopkins
Copy link
Contributor Author

@justinhopkins Thank you so much for your contributions and sorry for my late reply. The current implementation looks nice and I think it's ready to write the tests. Should I leave this PR open until you write the tests, or merge it first?

No worries! Just made changes based on your feedback. Please merge it first, and I'll follow-up with unit tests!
Thanks!

@whitphx
Copy link
Owner

whitphx commented Sep 12, 2023

OK, thanks!

@whitphx whitphx merged commit 42fda5b into whitphx:main Sep 12, 2023
6 checks passed
@whitphx
Copy link
Owner

whitphx commented Sep 15, 2023

Released in v0.50.0 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants