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

Multiple extensions registering the 'type' command #13441

Open
wmaurer opened this issue Oct 10, 2016 · 12 comments
Open

Multiple extensions registering the 'type' command #13441

wmaurer opened this issue Oct 10, 2016 · 12 comments
Labels
api feature-request Request for new features or functionality
Milestone

Comments

@wmaurer
Copy link

wmaurer commented Oct 10, 2016

  • VSCode Version: 1.5.3
  • OS Version: Windows 10

Steps to Reproduce:

  1. Install and enable VSCodeVim and vscode-jumpy
  2. Open a file with text
  3. Run the command Jumpy Word Mode. Two letter decorations should appear at the start of each word
  4. Type in the two letter code for that word. Jumpy functionality should enact a 'Jump' to the cursor position of that decorator.
  5. It doesn't work :-( The keystrokes are being processed by VSCodeVim, not Jumpy.

I am the author of vscode-jumpy (repo). A user has reported that Jumpy does not work in combination with VSCodeVim: wmaurer/vscode-jumpy#1.

It seems that both extensions are doing a registerCommand('type'), but VSCodeVim seems to take priority over vscode-jumpy. Is there are way to manage which extension has priority, so that it can receive and process the keystrokes?
Ideally I want to Jumpy to receive and process the next two keystrokes after enabling Jumpy Word Mode, but then let the rest of the keystrokes forward to VSCodeVim.

@alexdima
Copy link
Member

We added registerCommand("type") especially to enable vim mode to be implemented from an extension. We didn't want to bake vim mode in the core, and there can be only one handler. We never considered typing being something collaborative (in this case between vscode-jumpy and VSCodeVim). Today, the last one wins.

@alexdima alexdima added feature-request Request for new features or functionality api labels Oct 27, 2016
@alexdima alexdima added this to the Backlog milestone Oct 27, 2016
@alexdima alexdima removed their assignment Oct 27, 2016
@samdesota
Copy link

samdesota commented Nov 10, 2016

Could this be changed to something like ahandleKeys function? Something like:

...

vscode.commands.registerCommand("start-mode", () => {
   // Latest attached handler receives the keys first.
   const subscription = vscode.handleKeys((evt) => {
     // event will bubble to the next handler if you don't cancel
     evt.stopPropagation()
   })   

   // End subscription to return the key priority to the previous holder.
   setTimeout(() => subscription.unsubscribe(), 3000)
})

Would really like to use vscode-jumpy, I imagine this would be fairly easy to implement?

@staltz
Copy link

staltz commented Nov 15, 2016

For what it's worth, Atom is able to handle both jumpy and vim emulation (and probably more).

@samdesota
Copy link

samdesota commented Nov 15, 2016

@alexandrudima I'd really like this feature, if you would point me in the right direction in the source and discuss a pull request I'd be glad to work on it.

@lucax88x
Copy link

I have the same precise issue by using my extension (codeacejumper)

@aratakokubun
Copy link

I would like to turn off vim keybinding while activating jumpy line or word mode.
Is there any possible solution to do this? (ex: create a extension or set keymap)

@Shinikami
Copy link

Hey, all.
May we have this issue updated, please?

@wd
Copy link

wd commented Nov 15, 2018

It's has been 2 years, still can't get emacs-keymap work with ace-jump ext, does anyone have solution about this issue ?

@thieman
Copy link
Contributor

thieman commented Jan 21, 2019

If my reading of registerCommand is right, it already seems to implement the stack-like behavior we'd need for an extension to temporarily claim the type handler and then return it to the previous claimant (the Ace Jump usecase). https://github.com/Microsoft/vscode/blob/v1.19.3/src/vs/platform/commands/test/commands.test.ts#L25

@alexandrudima am I misunderstanding anything there?

I think there is a separate use case worth discussing though, which is extensions that want to be notified when typing happens but do not need exclusive control over changes to the output buffer. These might be well-served by an onDidType event or similar, which I don't think is provided currently. Thoughts on that, as well?

edit: I'm actually seeing references to an onDidType event that I didn't see in vscode.d.ts, I'll have to see if I can get to that

@Domiii
Copy link

Domiii commented Feb 1, 2020

I like @thieman's ideas, especially (2):

  1. Change commands to execute the entire (already existing) stack of event handlers instead of only the top
    • Con: This is likely going to be a breaking change, since currently, type command handlers pass the ball by invoking the default:type command instead of communicating their intentions back to the caller
  2. Expose the onWillType and onDidType events to the Extension API

@arstnei0
Copy link

Why is this problem still not solved? It's a big problem right?

@rgkirch
Copy link

rgkirch commented Nov 10, 2024

@thieman @alexdima If I copy that test into my extension then I get the error.

This is what I put in my extension:

		const command1 = function () { };
		const command2 = function () { };
		let reg1 = vscode.commands.registerCommand('foo', command1);
		let reg2 = vscode.commands.registerCommand('foo', command2);
		reg2.dispose();
		reg1.dispose();

IIUC, this is expected to work, right?

This is what's in the test:

	test('register/register/dispose', () => {
		const command1 = function () { };
		const command2 = function () { };

		// dispose overriding command
		let reg1 = CommandsRegistry.registerCommand('foo', command1);
		assert.ok(CommandsRegistry.getCommand('foo')!.handler === command1);

		let reg2 = CommandsRegistry.registerCommand('foo', command2);
		assert.ok(CommandsRegistry.getCommand('foo')!.handler === command2);
		reg2.dispose();

		assert.ok(CommandsRegistry.getCommand('foo')!.handler === command1);
		reg1.dispose();
		assert.ok(CommandsRegistry.getCommand('foo') === undefined);

Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api feature-request Request for new features or functionality
Projects
None yet
Development

No branches or pull requests