Skip to content

Commit 9af501d

Browse files
committed
Integrate LSH into edit
1 parent 0bfb7a3 commit 9af501d

17 files changed

Lines changed: 603 additions & 127 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/edit/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,15 @@ harness = false
1919
debug-latency = []
2020

2121
[dependencies]
22+
lsh.workspace = true
2223
stdext.workspace = true
2324

2425
[target.'cfg(unix)'.dependencies]
2526
libc = "0.2"
2627

2728
[build-dependencies]
2829
stdext.workspace = true
30+
lsh.workspace = true
2931
# The default toml crate bundles its dependencies with bad compile times. Thanks.
3032
# Thankfully toml-span exists. FWIW the alternative is yaml-rust (without the 2 suffix).
3133
toml-span = { version = "0.6", default-features = false }

crates/edit/build/main.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
#![allow(irrefutable_let_patterns)]
55

6+
use stdext::arena::scratch_arena;
7+
68
use crate::helpers::env_opt;
79

810
mod helpers;
@@ -24,12 +26,31 @@ fn main() {
2426
_ => TargetOs::Unix,
2527
};
2628

29+
compile_lsh();
2730
compile_i18n();
2831
configure_icu(target_os);
2932
#[cfg(windows)]
3033
configure_windows_binary(target_os);
3134
}
3235

36+
fn compile_lsh() {
37+
let scratch = scratch_arena(None);
38+
39+
let lsh_path = lsh::compiler::builtin_definitions_path();
40+
let out_dir = env_opt("OUT_DIR");
41+
let out_path = format!("{out_dir}/lsh_definitions.rs");
42+
43+
let mut generator = lsh::compiler::Generator::new(&scratch);
44+
match generator.read_directory(lsh_path).and_then(|_| generator.generate_rust()) {
45+
Ok(c) => std::fs::write(out_path, c).unwrap(),
46+
Err(err) => {
47+
panic!("failed to compile lsh definitions: {err}");
48+
}
49+
};
50+
51+
println!("cargo::rerun-if-changed={}", lsh_path.display());
52+
}
53+
3354
fn compile_i18n() {
3455
let i18n_path = "../../i18n/edit.toml";
3556

crates/edit/src/bin/edit/documents.rs

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use std::{fs, io};
88

99
use edit::buffer::{RcTextBuffer, TextBuffer};
1010
use edit::helpers::{CoordType, Point};
11+
use edit::lsh::{FILE_ASSOCIATIONS, Language, process_file_associations};
1112
use edit::{path, sys};
1213

1314
use crate::apperr;
@@ -20,6 +21,7 @@ pub struct Document {
2021
pub filename: String,
2122
pub file_id: Option<sys::FileId>,
2223
pub new_file_counter: usize,
24+
pub language_override: Option<Option<&'static Language>>,
2325
}
2426

2527
impl Document {
@@ -62,15 +64,41 @@ impl Document {
6264
fn set_path(&mut self, path: PathBuf) {
6365
let filename = path.file_name().unwrap_or_default().to_string_lossy().into_owned();
6466
let dir = path.parent().map(ToOwned::to_owned).unwrap_or_default();
67+
6568
self.filename = filename;
6669
self.dir = Some(DisplayablePathBuf::from_path(dir));
6770
self.path = Some(path);
68-
self.update_file_mode();
71+
72+
self.buffer.borrow_mut().set_ruler(if self.filename == "COMMIT_EDITMSG" { 72 } else { 0 });
73+
self.update_language();
74+
}
75+
76+
pub fn auto_detect_language(&mut self) {
77+
self.language_override = None;
78+
self.update_language();
6979
}
7080

71-
fn update_file_mode(&mut self) {
72-
let mut tb = self.buffer.borrow_mut();
73-
tb.set_ruler(if self.filename == "COMMIT_EDITMSG" { 72 } else { 0 });
81+
pub fn override_language(&mut self, lang: Option<&'static Language>) {
82+
self.language_override = Some(lang);
83+
self.update_language();
84+
}
85+
86+
fn update_language(&mut self) {
87+
self.buffer.borrow_mut().set_language(self.get_language());
88+
}
89+
90+
fn get_language(&self) -> Option<&'static Language> {
91+
if let Some(lang) = self.language_override {
92+
return lang;
93+
}
94+
95+
if let Some(path) = &self.path
96+
&& let Some(lang) = process_file_associations(FILE_ASSOCIATIONS, path)
97+
{
98+
return Some(lang);
99+
}
100+
101+
None
74102
}
75103
}
76104

@@ -140,6 +168,7 @@ impl DocumentManager {
140168
filename: Default::default(),
141169
file_id: None,
142170
new_file_counter: 0,
171+
language_override: None,
143172
};
144173
self.gen_untitled_name(&mut doc);
145174

@@ -201,6 +230,7 @@ impl DocumentManager {
201230
filename: Default::default(),
202231
file_id,
203232
new_file_counter: 0,
233+
language_override: None,
204234
};
205235
doc.set_path(path);
206236

crates/edit/src/bin/edit/draw_statusbar.rs

Lines changed: 60 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use edit::fuzzy::score_fuzzy;
66
use edit::helpers::*;
77
use edit::icu;
88
use edit::input::vk;
9+
use edit::lsh::LANGUAGES;
910
use edit::tui::*;
1011
use stdext::arena::scratch_arena;
1112
use stdext::arena_format;
@@ -28,15 +29,21 @@ pub fn draw_statusbar(ctx: &mut Context, state: &mut State) {
2829

2930
ctx.table_next_row();
3031

31-
if ctx.button("newline", if tb.is_crlf() { "CRLF" } else { "LF" }, ButtonStyle::default()) {
32-
let is_crlf = tb.is_crlf();
33-
tb.normalize_newlines(!is_crlf);
34-
}
32+
state.wants_language_picker |= ctx.button(
33+
"language",
34+
tb.language().map_or("Plain Text", |l| l.name),
35+
ButtonStyle::default(),
36+
);
3537
if state.wants_statusbar_focus {
3638
state.wants_statusbar_focus = false;
3739
ctx.steal_focus();
3840
}
3941

42+
if ctx.button("newline", if tb.is_crlf() { "CRLF" } else { "LF" }, ButtonStyle::default()) {
43+
let is_crlf = tb.is_crlf();
44+
tb.normalize_newlines(!is_crlf);
45+
}
46+
4047
state.wants_encoding_picker |=
4148
ctx.button("encoding", tb.encoding(), ButtonStyle::default());
4249
if state.wants_encoding_picker {
@@ -201,6 +208,55 @@ pub fn draw_statusbar(ctx: &mut Context, state: &mut State) {
201208
ctx.table_end();
202209
}
203210

211+
pub fn draw_dialog_language_change(ctx: &mut Context, state: &mut State) {
212+
let doc = state.documents.active_mut();
213+
let mut done = doc.is_none();
214+
215+
ctx.modal_begin("language", loc(LocId::LanguageSelectMode));
216+
if let Some(doc) = doc {
217+
let width = (ctx.size().width - 20).max(10);
218+
let height = (ctx.size().height - 10).max(10);
219+
220+
ctx.scrollarea_begin("scrollarea", Size { width, height });
221+
ctx.attr_background_rgba(ctx.indexed_alpha(IndexedColor::Black, 1, 4));
222+
ctx.inherit_focus();
223+
{
224+
ctx.list_begin("languages");
225+
ctx.inherit_focus();
226+
227+
let auto_detect = doc.language_override.is_none();
228+
let selected = if auto_detect { None } else { doc.buffer.borrow().language() };
229+
230+
if ctx.list_item(auto_detect, loc(LocId::LanguageAutoDetect))
231+
== ListSelection::Activated
232+
{
233+
doc.auto_detect_language();
234+
done = true;
235+
}
236+
237+
if ctx.list_item(selected.is_none(), "Plain Text") == ListSelection::Activated {
238+
doc.override_language(None);
239+
done = true;
240+
}
241+
242+
for lang in LANGUAGES {
243+
if ctx.list_item(Some(lang) == selected, lang.name) == ListSelection::Activated {
244+
doc.override_language(Some(lang));
245+
done = true;
246+
}
247+
}
248+
ctx.list_end();
249+
}
250+
ctx.scrollarea_end();
251+
}
252+
done |= ctx.modal_end();
253+
254+
if done {
255+
state.wants_language_picker = false;
256+
ctx.needs_rerender();
257+
}
258+
}
259+
204260
pub fn draw_dialog_encoding_change(ctx: &mut Context, state: &mut State) {
205261
let encoding = state.documents.active_mut().map_or("", |doc| doc.buffer.borrow().encoding());
206262
let reopen = state.wants_encoding_change == StateEncodingChange::Reopen;

crates/edit/src/bin/edit/main.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,9 @@ fn draw(ctx: &mut Context, state: &mut State) {
325325
if state.wants_save {
326326
draw_handle_save(ctx, state);
327327
}
328+
if state.wants_language_picker {
329+
draw_dialog_language_change(ctx, state);
330+
}
328331
if state.wants_encoding_change != StateEncodingChange::None {
329332
draw_dialog_encoding_change(ctx, state);
330333
}

crates/edit/src/bin/edit/state.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ pub struct State {
152152
pub search_options: buffer::SearchOptions,
153153
pub search_success: bool,
154154

155+
pub wants_language_picker: bool,
156+
155157
pub wants_encoding_picker: bool,
156158
pub wants_encoding_change: StateEncodingChange,
157159
pub encoding_picker_needle: String,
@@ -200,6 +202,8 @@ impl State {
200202
search_options: Default::default(),
201203
search_success: true,
202204

205+
wants_language_picker: false,
206+
203207
wants_encoding_picker: false,
204208
encoding_picker_needle: Default::default(),
205209
encoding_picker_results: Default::default(),

crates/edit/src/buffer/line_cache.rs

Lines changed: 0 additions & 116 deletions
This file was deleted.

0 commit comments

Comments
 (0)