From 3f386a9a4f1df0260dc47357ec5daa07941589ed Mon Sep 17 00:00:00 2001 From: Leonard Hecker Date: Mon, 26 Jan 2026 23:14:28 +0100 Subject: [PATCH 1/8] Syntax Highlighting V2 --- .cargo/debug_refcell.toml | 3 + .vscode/launch.json | 2 +- Cargo.lock | 57 + Cargo.toml | 4 +- assets/highlighting-tests/COMMIT_EDITMSG | 62 + assets/highlighting-tests/bash.sh | 71 + assets/highlighting-tests/batch.bat | 41 + assets/highlighting-tests/diff.diff | 142 ++ assets/highlighting-tests/git-rebase-todo | 54 + assets/highlighting-tests/markdown.md | 75 ++ assets/highlighting-tests/powershell.ps1 | 78 ++ assets/highlighting-tests/properties.conf | 13 + assets/highlighting-tests/yaml.yml | 43 + crates/edit/Cargo.toml | 2 + crates/edit/benches/lib.rs | 104 +- crates/edit/build/main.rs | 21 + crates/edit/src/bin/edit/apperr.rs | 2 + crates/edit/src/bin/edit/documents.rs | 43 +- crates/edit/src/bin/edit/draw_menubar.rs | 16 +- crates/edit/src/bin/edit/draw_statusbar.rs | 64 +- crates/edit/src/bin/edit/main.rs | 8 + crates/edit/src/bin/edit/settings.rs | 107 ++ crates/edit/src/bin/edit/state.rs | 6 + crates/edit/src/buffer/line_cache.rs | 116 -- crates/edit/src/buffer/mod.rs | 91 +- crates/edit/src/framebuffer.rs | 22 +- crates/edit/src/helpers.rs | 11 - crates/edit/src/lib.rs | 2 +- crates/edit/src/lsh/cache.rs | 86 ++ crates/edit/src/lsh/definitions.rs | 4 + crates/edit/src/lsh/highlighter.rs | 149 ++ crates/edit/src/lsh/mod.rs | 33 + crates/edit/src/sys/unix.rs | 7 +- crates/lsh-bin/Cargo.toml | 14 + crates/lsh-bin/src/main.rs | 198 +++ crates/lsh/Cargo.toml | 12 + crates/lsh/definitions/diff.lsh | 12 + .../lsh/definitions/git_commit_messsage.lsh | 25 + crates/lsh/definitions/git_ignore.lsh | 8 + crates/lsh/definitions/git_rebase_todo.lsh | 27 + crates/lsh/definitions/json.lsh | 37 + crates/lsh/definitions/lsh.lsh | 48 + crates/lsh/definitions/markdown.lsh | 202 +++ crates/lsh/definitions/powershell.lsh | 62 + crates/lsh/definitions/properties.lsh | 52 + crates/lsh/definitions/utility.lsh | 21 + crates/lsh/definitions/yaml.lsh | 78 ++ crates/lsh/src/compiler/backend.rs | 745 ++++++++++ crates/lsh/src/compiler/frontend.rs | 729 ++++++++++ crates/lsh/src/compiler/generator.rs | 313 +++++ crates/lsh/src/compiler/helpers.rs | 29 + crates/lsh/src/compiler/mod.rs | 1197 +++++++++++++++++ crates/lsh/src/compiler/optimizer.rs | 210 +++ crates/lsh/src/compiler/regex.rs | 501 +++++++ crates/lsh/src/compiler/tokenizer.rs | 281 ++++ crates/lsh/src/engine.rs | 427 ++++++ crates/lsh/src/lib.rs | 57 + crates/{edit => stdext}/src/glob.rs | 0 crates/stdext/src/helpers.rs | 20 + crates/stdext/src/lib.rs | 4 +- crates/stdext/src/varint.rs | 142 ++ i18n/edit.toml | 39 + 62 files changed, 6878 insertions(+), 151 deletions(-) create mode 100644 .cargo/debug_refcell.toml create mode 100644 assets/highlighting-tests/COMMIT_EDITMSG create mode 100644 assets/highlighting-tests/bash.sh create mode 100644 assets/highlighting-tests/batch.bat create mode 100644 assets/highlighting-tests/diff.diff create mode 100644 assets/highlighting-tests/git-rebase-todo create mode 100644 assets/highlighting-tests/markdown.md create mode 100644 assets/highlighting-tests/powershell.ps1 create mode 100644 assets/highlighting-tests/properties.conf create mode 100644 assets/highlighting-tests/yaml.yml create mode 100644 crates/edit/src/bin/edit/settings.rs delete mode 100644 crates/edit/src/buffer/line_cache.rs create mode 100644 crates/edit/src/lsh/cache.rs create mode 100644 crates/edit/src/lsh/definitions.rs create mode 100644 crates/edit/src/lsh/highlighter.rs create mode 100644 crates/edit/src/lsh/mod.rs create mode 100644 crates/lsh-bin/Cargo.toml create mode 100644 crates/lsh-bin/src/main.rs create mode 100644 crates/lsh/Cargo.toml create mode 100644 crates/lsh/definitions/diff.lsh create mode 100644 crates/lsh/definitions/git_commit_messsage.lsh create mode 100644 crates/lsh/definitions/git_ignore.lsh create mode 100644 crates/lsh/definitions/git_rebase_todo.lsh create mode 100644 crates/lsh/definitions/json.lsh create mode 100644 crates/lsh/definitions/lsh.lsh create mode 100644 crates/lsh/definitions/markdown.lsh create mode 100644 crates/lsh/definitions/powershell.lsh create mode 100644 crates/lsh/definitions/properties.lsh create mode 100644 crates/lsh/definitions/utility.lsh create mode 100644 crates/lsh/definitions/yaml.lsh create mode 100644 crates/lsh/src/compiler/backend.rs create mode 100644 crates/lsh/src/compiler/frontend.rs create mode 100644 crates/lsh/src/compiler/generator.rs create mode 100644 crates/lsh/src/compiler/helpers.rs create mode 100644 crates/lsh/src/compiler/mod.rs create mode 100644 crates/lsh/src/compiler/optimizer.rs create mode 100644 crates/lsh/src/compiler/regex.rs create mode 100644 crates/lsh/src/compiler/tokenizer.rs create mode 100644 crates/lsh/src/engine.rs create mode 100644 crates/lsh/src/lib.rs rename crates/{edit => stdext}/src/glob.rs (100%) create mode 100644 crates/stdext/src/varint.rs diff --git a/.cargo/debug_refcell.toml b/.cargo/debug_refcell.toml new file mode 100644 index 000000000000..98ec4965922b --- /dev/null +++ b/.cargo/debug_refcell.toml @@ -0,0 +1,3 @@ +[unstable] +build-std = ["std"] +build-std-features = ["debug_refcell"] diff --git a/.vscode/launch.json b/.vscode/launch.json index 7142960c4f9d..aaed2864490b 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -10,7 +10,7 @@ "program": "${workspaceFolder}/target/debug/edit", "cwd": "${workspaceFolder}", "args": [ - "${workspaceFolder}/crates/edit/src/bin/edit/main.rs" + "${workspaceFolder}/assets/highlighting-tests/json.json" ], }, { diff --git a/Cargo.lock b/Cargo.lock index 8375271b12fe..4f39ccae9dbc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -47,6 +47,38 @@ version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" +[[package]] +name = "argh" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34ff18325c8a36b82f992e533ece1ec9f9a9db446bd1c14d4f936bac88fcd240" +dependencies = [ + "argh_derive", + "argh_shared", + "rust-fuzzy-search", +] + +[[package]] +name = "argh_derive" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b2b83a50d329d5d8ccc620f5c7064028828538bdf5646acd60dc1f767803" +dependencies = [ + "argh_shared", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "argh_shared" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a464143cc82dedcdc3928737445362466b7674b5db4e2eb8e869846d6d84f4f6" +dependencies = [ + "serde", +] + [[package]] name = "autocfg" version = "1.5.0" @@ -226,6 +258,7 @@ version = "1.2.1" dependencies = [ "criterion", "libc", + "lsh", "stdext", "toml-span", "windows-sys", @@ -348,6 +381,24 @@ version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +[[package]] +name = "lsh" +version = "0.0.0" +dependencies = [ + "regex-syntax", + "stdext", +] + +[[package]] +name = "lsh-bin" +version = "0.0.0" +dependencies = [ + "anyhow", + "argh", + "lsh", + "stdext", +] + [[package]] name = "memchr" version = "2.7.6" @@ -507,6 +558,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "rust-fuzzy-search" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a157657054ffe556d8858504af8a672a054a6e0bd9e8ee531059100c0fa11bb2" + [[package]] name = "rustversion" version = "1.0.22" diff --git a/Cargo.toml b/Cargo.toml index fb53ab464f5f..99ef8715a6ac 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ resolver = "2" edition = "2024" license = "MIT" repository = "https://github.com/microsoft/edit" -rust-version = "1.88" +rust-version = "1.92" # We use `opt-level = "s"` as it significantly reduces binary size. # We could then use the `#[optimize(speed)]` attribute for spot optimizations. @@ -28,5 +28,7 @@ lto = "thin" # Similarly, speed up linking by a ton [workspace.dependencies] edit = { path = "./crates/edit" } +lsh = { path = "./crates/lsh" } +lsh-bin = { path = "./crates/lsh-bin" } stdext = { path = "./crates/stdext" } unicode-gen = { path = "./crates/unicode-gen" } diff --git a/assets/highlighting-tests/COMMIT_EDITMSG b/assets/highlighting-tests/COMMIT_EDITMSG new file mode 100644 index 000000000000..cfba35d08da9 --- /dev/null +++ b/assets/highlighting-tests/COMMIT_EDITMSG @@ -0,0 +1,62 @@ +lsh: flip legacy flag, add follow-up hook & diff test + +Refactors placeholder logic and introduces a lightweight follow-up hook. +Adds diff highlighting test and removes outdated asset to streamline visuals. + +# Please enter the commit message for your changes. Lines starting +# with '#' will be ignored, and an empty message aborts the commit. +# +# On branch foobar +# Your branch is up to date with 'origin/foobar'. +# +# Changes to be committed: +# renamed: foo.rs -> bar.rs +# modified: src/lsh/definitions.rs +# deleted: assets/old_logo.svg +# new file: baz.rs +# +# ------------------------ >8 ------------------------ +# Do not modify or remove the line above. +# Everything below it will be ignored. +diff --git a/src/lsh/definitions.rs b/src/lsh/definitions.rs +index a1b2c3d..d4c3b2a 100644 +--- a/src/lsh/definitions.rs ++++ b/src/lsh/definitions.rs +@@ -12,9 +12,11 @@ // context line 12 + // context line 13 +-// old placeholder logic A +-const LEGACY_FLAG: bool = true; +-// end legacy block ++// updated placeholder logic A ++const LEGACY_FLAG: bool = false; // flipped for test ++// added note: migration in progress ++// end legacy block + // context line 19 + // context line 20 +@@ -42,7 +44,12 @@ // context line 42 + // context line 43 +- do_placeholder_action(alpha, beta); ++ // Split actions for clarity ++ do_placeholder_prepare(alpha); ++ do_placeholder_action(alpha, beta); ++ if (enable_extra()) { ++ do_placeholder_followup(beta); ++ } + // context line 50 + // context line 51 + // context line 52 +@@ -90,6 +97,15 @@ // context line 90 + // context line 91 + // context line 92 ++/// Added lightweight fake helper ++fn enable_extra() -> bool { ++ // Pretend this consults a config value ++ true ++} ++ ++// Temporary debug instrumentation (to be removed) ++const _DEBUG_HOOK: &str = "lsh:extra"; ++ + // context line 93 + // context line 94 + // context line 95 diff --git a/assets/highlighting-tests/bash.sh b/assets/highlighting-tests/bash.sh new file mode 100644 index 000000000000..dfd5238724db --- /dev/null +++ b/assets/highlighting-tests/bash.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env bash + +# This is a comment + +readonly VAR1="Hello" # String literal +VAR2=42 # Integer literal +VAR3=$((VAR2 + 8)) # Arithmetic expansion +VAR4=$(echo "World") # Command substitution + +function greet() { # Function definition + local name="$1" # Local variable, parameter expansion + echo "${VAR1}, $name! $VAR4" # String, parameter expansion, variable +} + +greet "User" # Function call, string literal + +if [[ $VAR2 -gt 40 && $VAR3 -eq 50 ]]; then # Conditional, test, operators + echo "Numbers are correct" # String literal +elif (( VAR2 < 40 )); then # Arithmetic test + echo 'VAR2 is less than 40' # Single-quoted string +else + echo "Other case" +fi + +for i in {1..3}; do # Brace expansion, for loop + echo "Loop $i" # String, variable +done + +case "$VAR4" in # Case statement + World) echo "It's World";; # Pattern, string + *) echo "Unknown";; # Wildcard +esac + +arr=(one two three) # Array +echo "${arr[1]}" # Array access + +declare -A assoc # Associative array +assoc[key]="value" +echo "${assoc[key]}" + +# Here document +cat < /dev/null + +# Background job +sleep 1 & + +# Arithmetic assignment +let VAR2+=1 + +# Process substitution +diff <(echo foo) <(echo bar) + +# Command grouping +{ echo "Group 1"; echo "Group 2"; } + +# Escaped characters +echo "A quote: \" and a backslash: \\" + +# End of file diff --git a/assets/highlighting-tests/batch.bat b/assets/highlighting-tests/batch.bat new file mode 100644 index 000000000000..962ef66007af --- /dev/null +++ b/assets/highlighting-tests/batch.bat @@ -0,0 +1,41 @@ +@echo off +REM --- String, Variable, Label, Command, Operator, Number, Delimiter, Comment --- + +:: Label +:Start + +:: Variable assignment and usage +set "VAR1=Hello" +set VAR2=World + +:: String with spaces and special characters +set "STR=Batch ^& CMD!" + +:: Arithmetic operation (number, operator) +set /a SUM=5+10 + +:: IF statement (keyword, operator, string, variable) +if "%VAR1%"=="Hello" ( + echo %VAR1%, %VAR2%! %STR% +) else ( + echo Not matched! +) + +:: FOR loop (keyword, variable, delimiter, string) +for %%F in (*.bat) do ( + echo Found file: %%F +) + +:: CALL command (keyword, label) +call :SubRoutine + +:: GOTO command (keyword, label) +goto :End + +:: Subroutine with parameter +:SubRoutine +echo In subroutine with SUM=%SUM% +goto :eof + +:End +REM End of script diff --git a/assets/highlighting-tests/diff.diff b/assets/highlighting-tests/diff.diff new file mode 100644 index 000000000000..8d033f94bfcd --- /dev/null +++ b/assets/highlighting-tests/diff.diff @@ -0,0 +1,142 @@ +diff --git a/src/lsh/definitions.rs b/src/lsh/definitions.rs +index a1b2c3d..d4c3b2a 100644 +--- a/src/lsh/definitions.rs ++++ b/src/lsh/definitions.rs +@@ -12,9 +12,11 @@ // context line 12 + // context line 13 +-// old placeholder logic A +-const LEGACY_FLAG: bool = true; +-// end legacy block ++// updated placeholder logic A ++const LEGACY_FLAG: bool = false; // flipped for test ++// added note: migration in progress ++// end legacy block + // context line 19 + // context line 20 +@@ -42,7 +44,12 @@ // context line 42 + // context line 43 +- do_placeholder_action(alpha, beta); ++ // Split actions for clarity ++ do_placeholder_prepare(alpha); ++ do_placeholder_action(alpha, beta); ++ if (enable_extra()) { ++ do_placeholder_followup(beta); ++ } + // context line 50 + // context line 51 + // context line 52 +@@ -90,6 +97,15 @@ // context line 90 + // context line 91 + // context line 92 ++/// Added lightweight fake helper ++fn enable_extra() -> bool { ++ // Pretend this consults a config value ++ true ++} ++ ++// Temporary debug instrumentation (to be removed) ++const _DEBUG_HOOK: &str = "lsh:extra"; ++ + // context line 93 + // context line 94 + // context line 95 + +diff --git a/src/tui.rs b/src/tui.rs +index 1122334..5566778 100644 +--- a/src/tui.rs ++++ b/src/tui.rs +@@ -5,8 +5,13 @@ // context line 5 + // context line 6 + // context line 7 +-// previous rendering stub +-render_placeholder(frame); ++// refined rendering sequence ++begin_frame(frame); ++render_header(frame); ++render_body(frame); ++render_footer(frame); ++end_frame(frame); ++ + // context line 14 + // context line 15 + // context line 16 + +diff --git a/README.md b/README.md +index 9aa9aa9..1bb1bb1 100644 +--- a/README.md ++++ b/README.md +@@ -1,6 +1,11 @@ + # Project Title +-Some brief description here. ++Some brief description here (updated). ++ ++Experimental notes: ++- Added fake diff example ++- Demonstrates multi-hunk & multi-file patch ++ + ## Usage + Run the binary as needed. + +diff --git a/Cargo.toml b/Cargo.toml +index cafe123..fade321 100644 +--- a/Cargo.toml ++++ b/Cargo.toml +@@ -8,7 +8,10 @@ edition = "2021" + # context + [features] +-default = [] ++default = ["experimental-preview"] ++experimental-preview = [] ++ ++# NOTE: Above feature is placeholder & fake + + [dependencies] + # context +@@ -20,6 +23,7 @@ anyhow = "1" + # context + # instrumentation (fake addition) + tracing = "0.1" ++tracing-subscriber = "0.3" + +diff --git a/src/feature/experimental.rs b/src/feature/experimental.rs +new file mode 100644 +index 0000000..abc1234 +--- /dev/null ++++ b/src/feature/experimental.rs +@@ -0,0 +1,24 @@ ++//! Placeholder experimental module (fake content). ++//! This file exists only to demonstrate a multi-file diff. ++#![allow(dead_code)] ++ ++pub struct ExperimentalToggle { ++ enabled: bool, ++} ++ ++impl ExperimentalToggle { ++ pub fn new() -> Self { ++ Self { enabled: true } ++ } ++ pub fn enabled(&self) -> bool { ++ self.enabled ++ } ++} ++ ++pub fn run_experimental_path() { ++ if ExperimentalToggle::new().enabled() { ++ // Fake behavior ++ eprintln!("(fake) running experimental path"); ++ } ++} ++ + +diff --git a/assets/old_logo.svg b/assets/old_logo.svg +deleted file mode 100644 +index 55aa55a..0000000 +--- a/assets/old_logo.svg ++++ /dev/null +@@ -1,5 +0,0 @@ +- +- +- +- X +- diff --git a/assets/highlighting-tests/git-rebase-todo b/assets/highlighting-tests/git-rebase-todo new file mode 100644 index 000000000000..d051d1222924 --- /dev/null +++ b/assets/highlighting-tests/git-rebase-todo @@ -0,0 +1,54 @@ +pick 3f9d2ab # chore(ci): add initial pipeline +pick e12c0ff # feat(io): introduce streaming reader +reword 7ac14d0 feat(io): add zero-copy buffered writer +edit 4d92b67 fix(io): handle partial UTF-8 sequences at buffer boundary +pick 8bb3a21 docs: expand README performance section +squash 1c02f55 docs: tidy wording in performance section +pick 54ae91b feat(cli): add --color=auto detection +fixup 0b77c3e feat(cli): typo in help text +fixup -c 2f4e8ab feat(cli): adjust arg parsing error message +pick 6d8e5f1 refactor(core): split large module into submodules +break +pick a41e9d3 test(core): add regression tests for issue #410 +exec cargo test --package edit --lib --quiet +pick c3bb921 perf(render): SIMD accelerate line diffing +drop 91d0f2e debug(render): temporary logging (to be dropped) +label pre-merge-split +pick d2f7ac4 feat(ui): add mouse wheel smooth scrolling +pick f1a4bd9 feat(ui): add high-DPI awareness +label post-ui +update-ref refs/heads/feature/ui-stack-post +reset pre-merge-split +merge -C 5ab77e3 post-ui # Merge UI feature stack +pick d8c4b91 build: bump version to 0.9.0 + +# Rebase 3f9d2ab..d8c4b91 onto d8c4b91 (18 commands) +# +# Commands: +# p, pick = use commit +# r, reword = use commit, but edit the commit message +# e, edit = use commit, but stop for amending +# s, squash = use commit, but meld into previous commit +# f, fixup [-C | -c] = like "squash" but keep only the previous +# commit's log message, unless -C is used, in which case +# keep only this commit's message; -c is same as -C but +# opens the editor +# x, exec = run command (the rest of the line) using shell +# b, break = stop here (continue rebase later with 'git rebase --continue') +# d, drop = remove commit +# l, label