codemirror6-plugin icon indicating copy to clipboard operation
codemirror6-plugin copied to clipboard

Expanding in CSS with Tab

Open shshaw opened this issue 1 year ago • 7 comments

Expansion in CSS can't be done with the Tab key when Autocomplete is enabled; it just indents the code. To expand an abbreviation, you have to select it from the autocomplete menu with the Enter key.

I'm not sure if this is an Emmet problem or with our specific CodeMirror setup, but Tab works fine in Markup.

https://github.com/user-attachments/assets/03df425e-48fa-4c01-b182-83a9a5949686

We do have Prec.high on the abbreviation tracker, so it should take precedence over the indentWithTab extension, which works fine in Markup but not in CSS.

Screenshot 2024-08-06 at 6 57 49 AM

Related: #16 #27

shshaw avatar Aug 06 '24 12:08 shshaw

In CSS, the plugin expects acceptCompletion command that should insert current completion. As docs says, the Tab key is not bound by default for a11y reasons

sergeche avatar Sep 14 '24 11:09 sergeche

What's odd is we have Tab bound correctly and working in HTML and other languages, but it doesn't work specifically in CSS.

I'll look into acceptCompletion to see if there's something we can configure to get it working right in CSS.

shshaw avatar Sep 14 '24 12:09 shshaw

Not sure if I should override Tab key on my side in this case. I think it will always run Emmet expand even if user picks another completion option

sergeche avatar Sep 15 '24 08:09 sergeche

I may have figured out a manual tab override, but it's not great.

Is there a way to detect if Emmet has an expansion / completion available from the current state?

shshaw avatar Sep 20 '24 22:09 shshaw

You can try to use pickedCompletion annotation from @codemirror/autocomplete package and get its value from transaction, like this: transaction.annotation(pickedCompletion). You can then check if it has type: 'emmet' value

sergeche avatar Sep 23 '24 08:09 sergeche

Thank you, @sergeche!

Looks like the autocomplete extension only uses Tab for snippet fields, which may not really interfere with the Emmet completion. It would be great to have an Emmet config option to allow Tab regardless of Completion (or a callback/custom logic for when to ignore Completions) in here to make it easier to keep Tab in place for style languages.

For now, see below for how I have to re-enable Tab. I have a list of the EmmetKnownSyntax values of style languages and when I activate Emmet with a specific syntax, I also add this Extension.

function expandAbbreviationWithTabInStyleLanguages(syntax: EmmetKnownSyntax) {
  if (EmmetKnownSyntaxOfStyles.has(syntax)) {
    // `Prec.highest` to ensure it's above the default `abbreviationTracker` and `indentWithTab`
    return Prec.highest(
      keymap.of([
        {
          key: 'Tab',
          run: styleLanguagesTabKeyHandler
        }
      ])
    );
  }

  return [];
}

const styleLanguagesTabKeyHandler: Command = (view: EditorView) => {
  const { state } = view;
  if (completionStatus(state) === 'active') {
    expandAbbreviation(view);
    return true;
  }

  // Return false to allow the default Tab behavior
  return false;
};

shshaw avatar Sep 23 '24 11:09 shshaw

I’ve just added a new autocompleteTab option in v0.4.0. You can specify syntaxes where Emmet can apply its own completion with Tab, see main.ts for example

sergeche avatar Sep 23 '24 16:09 sergeche

The new option is working as expected. Gracias!

shshaw avatar Oct 08 '24 18:10 shshaw