diff --git a/Cargo.lock b/Cargo.lock index 0b6fec8..c299d42 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -719,9 +719,9 @@ dependencies = [ [[package]] name = "cooklang-language-server" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9392d694ca71d1a931dc200be7a061d13f46e688c07e48cf4575569e2a9f6886" +checksum = "7f4f0ec7cf3dba205edeacb9868413fb43dda06d9c3bfd5d7b74d71273a04ebb" dependencies = [ "anyhow", "cooklang", diff --git a/Cargo.toml b/Cargo.toml index 63c8fb3..1db0504 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,7 +43,7 @@ cooklang-find = { version = "0.5.0" } cooklang-import = "0.8.7" cooklang-sync-client = { version = "0.4.8", optional = true } libsqlite3-sys = { version = "0.35", features = ["bundled"], optional = true } -cooklang-language-server = "0.2.0" +cooklang-language-server = "0.2.1" cooklang-reports = { version = "0.2.2" } directories = "6" fluent = "0.16" diff --git a/docs/README.md b/docs/README.md index 602c1cf..7709280 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,6 +1,6 @@ # CookCLI -A command-line interface for managing and working with Cooklang recipes. +CookCLI is a free, open-source command-line tool for working with [Cooklang](https://cooklang.org/docs/spec/) recipe files. It parses `.cook` files, generates combined shopping lists from multiple recipes, runs a local web server to browse your collection, imports recipes from websites, and scales servings — all from the terminal. ## Commands diff --git a/static/js/src/editor.js b/static/js/src/editor.js index 9397947..a5fa112 100644 --- a/static/js/src/editor.js +++ b/static/js/src/editor.js @@ -40,7 +40,8 @@ async function cooklangCompletions(context) { const textBefore = line.text.slice(0, pos - line.from); // Check for trigger characters (@, #, ~) - const match = textBefore.match(/[@#~]([a-zA-Z0-9_]*)$/); + // Include . / - in character class so @./path file references trigger completion + const match = textBefore.match(/[@#~]([a-zA-Z0-9_./\-]*)$/); if (!match) return null; const prefix = match[1]; @@ -53,9 +54,14 @@ async function cooklangCompletions(context) { return { from: from, + // Keep completion open while user types path chars; CodeMirror's + // built-in FuzzyMatcher handles client-side narrowing. + validFor: /^[a-zA-Z0-9_./\-]*$/, options: items.map(item => { - const type = item.kind === 6 ? 'variable' : item.kind === 14 ? 'keyword' : 'text'; - const text = item.insertText || item.label; + const type = item.kind === 17 ? 'file' : item.kind === 6 ? 'variable' : item.kind === 14 ? 'keyword' : 'text'; + // Prefer textEdit.newText (used by recipe references with explicit ranges), + // then insertText, then label + const text = item.textEdit?.newText || item.insertText || item.label; // Check if LSP sent a snippet (insertTextFormat === 2) if (item.insertTextFormat === 2 && text.includes('$')) {