# HG changeset patch # User Michael Davis # Date 1747254567 14400 # Node ID 176f68aecad1dc2e15cc2c99560c7dd4ccae4446 # Parent 4a705a983d3830e85cfc8a96ef5277d4da599115 syntax: Fix language detection by shebang The switch to tree-house accidentally dropped some shebang parsing code from the loader's function to detect by shebang. This change restores that. The new code is slightly different as it's using a `regex_cursor` regex on the Rope rather than eagerly converting the text to a `Cow` and running a regular regex across it. diff -r 4a705a983d38 -r 176f68aecad1 helix-core/src/syntax.rs --- a/helix-core/src/syntax.rs Wed May 14 10:52:00 2025 -0300 +++ b/helix-core/src/syntax.rs Wed May 14 16:29:27 2025 -0400 @@ -312,7 +312,22 @@ } pub fn language_for_shebang(&self, text: RopeSlice) -> Option { - let shebang: Cow = text.into(); + // NOTE: this is slightly different than the one for injection markers in tree-house. It + // is anchored at the beginning. + use helix_stdx::rope::Regex; + use once_cell::sync::Lazy; + const SHEBANG: &str = r"^#!\s*(?:\S*[/\\](?:env\s+(?:\-\S+\s+)*)?)?([^\s\.\d]+)"; + static SHEBANG_REGEX: Lazy = Lazy::new(|| Regex::new(SHEBANG).unwrap()); + + let marker = SHEBANG_REGEX + .captures_iter(regex_cursor::Input::new(text)) + .map(|cap| text.byte_slice(cap.get_group(1).unwrap().range())) + .next()?; + self.language_for_shebang_marker(marker) + } + + fn language_for_shebang_marker(&self, marker: RopeSlice) -> Option { + let shebang: Cow = marker.into(); self.languages_by_shebang.get(shebang.as_ref()).copied() } @@ -351,7 +366,7 @@ let path: Cow = text.into(); self.language_for_filename(Path::new(path.as_ref())) } - InjectionLanguageMarker::Shebang(text) => self.language_for_shebang(text), + InjectionLanguageMarker::Shebang(text) => self.language_for_shebang_marker(text), } }