diff --git a/README.md b/README.md index e97d79a..b24523d 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ to communication around the project.

Add variable completions.

- properties⁠?: fn(path: readonly string[], stateEditorState) → readonly Completion[]
+ properties⁠?: fn(path: readonly string[], stateEditorState, contextCompletionContext) → readonly Completion[]

Provides completions for properties completed under the given path. For example, when completing user.address., path will @@ -68,4 +68,11 @@ be ["user", "address"].

Returns a completion source for liquid templates. Optionally takes a configuration that adds additional custom completions.

- +
+ closePercentBrace: Extension
+ +

This extension will, when the user types a % between two +matching braces, insert two percent signs instead and put the +cursor between them.

+
+ \ No newline at end of file diff --git a/src/README.md b/src/README.md index 48fd599..7220029 100644 --- a/src/README.md +++ b/src/README.md @@ -29,3 +29,5 @@ to communication around the project. @LiquidCompletionConfig @liquidCompletionSource + +@closePercentBrace \ No newline at end of file diff --git a/src/complete.ts b/src/complete.ts index 7b360a4..7a190d9 100644 --- a/src/complete.ts +++ b/src/complete.ts @@ -1,4 +1,5 @@ -import {EditorState} from "@codemirror/state" +import {EditorState, EditorSelection} from "@codemirror/state" +import {EditorView} from "@codemirror/view" import {syntaxTree} from "@codemirror/language" import {CompletionContext, CompletionResult, Completion} from "@codemirror/autocomplete" import {SyntaxNode} from "@lezer/common" @@ -110,3 +111,19 @@ export function liquidCompletionSource(config: LiquidCompletionConfig = {}) { return options.length ? {options, from, validFor: /^[\w\u00c0-\uffff]*$/} : null } } + +/// This extension will, when the user types a `%` between two +/// matching braces, insert two percent signs instead and put the +/// cursor between them. +export const closePercentBrace = EditorView.inputHandler.of((view, from, to, text) => { + if (text != "%" || from != to || view.state.doc.sliceString(from - 1, to + 1) != "{}") + return false + view.dispatch(view.state.changeByRange(range => ({ + changes: {from: range.from, to: range.to, insert: "%%"}, + range: EditorSelection.cursor(range.from + 1) + })), { + scrollIntoView: true, + userEvent: "input.type" + }) + return true +}) diff --git a/src/liquid.ts b/src/liquid.ts index 394b306..b5e9b5c 100644 --- a/src/liquid.ts +++ b/src/liquid.ts @@ -4,8 +4,8 @@ import {html} from "@codemirror/lang-html" import {styleTags, tags as t} from "@lezer/highlight" import {parseMixed} from "@lezer/common" import {parser} from "./liquid.grammar" -import {liquidCompletionSource, LiquidCompletionConfig} from "./complete" -export {liquidCompletionSource, LiquidCompletionConfig} +import {liquidCompletionSource, LiquidCompletionConfig, closePercentBrace} from "./complete" +export {liquidCompletionSource, LiquidCompletionConfig, closePercentBrace} function directiveIndent(except: RegExp) { return (context: TreeIndentContext) => { @@ -88,6 +88,7 @@ export function liquid(config: LiquidCompletionConfig & { return new LanguageSupport(lang, [ base.support, lang.data.of({autocomplete: liquidCompletionSource(config)}), - base.language.data.of({closeBrackets: {brackets: ["{"]}}) + base.language.data.of({closeBrackets: {brackets: ["{"]}}), + closePercentBrace ]) }