Skip to content

Commit 1b192ca

Browse files
committed
feat: opening new files and not having a 1-tick delay
1 parent 2118821 commit 1b192ca

File tree

21 files changed

+738
-44
lines changed

21 files changed

+738
-44
lines changed

glyph-config/src/lib.rs

+21-8
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use dirs::DIRS;
77
use glyph_core::command::{Context, MappableCommand};
88
use glyph_core::editor::Mode;
99
use glyph_core::highlights::HighlightGroup;
10-
use glyph_runtime::keymap::{LuaKeymapOpts, LuaMappableCommand};
10+
use glyph_runtime::keymap::{LuaKeymap, LuaKeymapOpts, LuaMappableCommand};
1111
use glyph_runtime::statusline::StatuslineConfig;
1212
use glyph_runtime::RuntimeMessage;
1313
use glyph_trie::Trie;
@@ -199,6 +199,16 @@ pub struct KeymapConfig<'cfg> {
199199
pub options: KeymapOptions,
200200
}
201201

202+
impl<'cfg> From<LuaKeymap<'cfg>> for KeymapConfig<'cfg> {
203+
fn from(lua_keymap: LuaKeymap<'cfg>) -> KeymapConfig<'cfg> {
204+
KeymapConfig {
205+
mode: lua_keymap.mode,
206+
command: lua_keymap.command.into(),
207+
options: lua_keymap.options.into(),
208+
}
209+
}
210+
}
211+
202212
#[derive(Debug)]
203213
pub struct Config<'cfg> {
204214
cursor: CursorConfig,
@@ -280,19 +290,22 @@ fn handle_setup_messages(messages: Vec<RuntimeMessage>) -> SetupMessagesResult {
280290

281291
for message in messages {
282292
match message {
283-
RuntimeMessage::Error(error) => println!("{error:?}"),
293+
RuntimeMessage::Error(error) => panic!("{error:?}"),
284294
RuntimeMessage::UpdateHighlightGroup(name, group) => _ = highlight_groups.insert(name, group),
285295
RuntimeMessage::UserCommandCreate(name, callback) => _ = user_commands.insert(name, callback),
286296
RuntimeMessage::SetKeymap(lua_keymap) => {
287-
let keymap = KeymapConfig {
288-
mode: lua_keymap.mode,
289-
command: lua_keymap.command.into(),
290-
options: lua_keymap.options.into(),
291-
};
292297
let mode_maps = keymaps.get_mut(&lua_keymap.mode).unwrap();
293-
mode_maps.add_word(&lua_keymap.keys, keymap);
298+
let keys = lua_keymap.keys.clone();
299+
let keymap = KeymapConfig::from(lua_keymap);
300+
mode_maps.add_word(keys, keymap);
294301
}
302+
// Some runtime messages are ignored here as we don't want to handle them within
303+
// configuration context.
304+
//
305+
// Only messages that change configuration values should be considered when loading
306+
// configuration.
295307
RuntimeMessage::Quit(_) => {}
308+
RuntimeMessage::OpenFile(_) => {}
296309
RuntimeMessage::Write(_) => {}
297310
};
298311
}

glyph-core/src/editor.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,16 @@ impl Editor {
166166
assert!(self.documents.contains_key(&id));
167167

168168
match action {
169-
OpenAction::Replace => todo!(),
169+
OpenAction::Replace => {
170+
let tab = self.focused_tab_mut();
171+
let window = tab
172+
.tree
173+
.get_window_mut(tab.tree.focus())
174+
.expect("no active window on the editor");
175+
176+
window.document = id;
177+
window.id
178+
}
170179
OpenAction::SplitVertical => {
171180
let tab = self.focused_tab_mut();
172181

glyph-core/src/syntax.rs

+63-10
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ impl Highlighter {
5757
pub fn add_document(&mut self, document: &Document) {
5858
let parser = self.get_or_create_parser(document.language());
5959

60-
let tree = parser.and_then(|p| p.parse(document.text().slice(..).to_string(), None));
60+
let tree = parser.and_then(|p| p.parse(document.text().to_string(), None));
6161

6262
let mut syntax = Syntax {
6363
language: document.language(),
@@ -67,9 +67,12 @@ impl Highlighter {
6767
};
6868

6969
if let Some(ref tree) = syntax.tree {
70+
// let mut file = std::fs::File::create("tree.sexp").unwrap();
71+
// print_highlights_sexp(tree, document.language(), &document.text().to_string(), &mut file).unwrap();
72+
7073
let mut cursor = tree_sitter::QueryCursor::new();
7174
let root = tree.root_node();
72-
let language = self.get_ts_language(document.language()).unwrap();
75+
let language = get_ts_language(document.language()).unwrap();
7376

7477
let query = self.queries.entry(document.language()).or_insert(
7578
tree_sitter::Query::new(&language.into(), &get_ts_query(document.language()).unwrap()).unwrap(),
@@ -143,7 +146,7 @@ impl Highlighter {
143146
return self.parsers.get_mut(&language);
144147
}
145148

146-
if let Some(ts_language) = self.get_ts_language(language) {
149+
if let Some(ts_language) = get_ts_language(language) {
147150
let mut parser = Parser::new();
148151
parser.set_language(&ts_language.into()).ok();
149152
self.parsers.insert(language, parser);
@@ -152,20 +155,70 @@ impl Highlighter {
152155

153156
None
154157
}
158+
}
155159

156-
fn get_ts_language(&self, language: LanguageId) -> Option<impl Into<Language>> {
157-
match language {
158-
LanguageId::Rust => Some(tree_sitter_rust::LANGUAGE),
159-
LanguageId::Lua => Some(tree_sitter_lua::LANGUAGE),
160-
_ => None,
161-
}
160+
fn get_ts_language(language: LanguageId) -> Option<impl Into<Language>> {
161+
match language {
162+
LanguageId::Rust => Some(tree_sitter_rust::LANGUAGE),
163+
LanguageId::Lua => Some(tree_sitter_lua::LANGUAGE),
164+
_ => None,
162165
}
163166
}
164167

165168
fn get_ts_query(language: LanguageId) -> Option<String> {
166169
match language {
167-
LanguageId::Rust => Some(tree_sitter_rust::HIGHLIGHTS_QUERY.to_string()),
170+
LanguageId::Rust => {
171+
let highlights = include_str!("../../languages/queries/rust/highlights.scm");
172+
Some(highlights.to_string())
173+
}
168174
LanguageId::Lua => Some(tree_sitter_lua::HIGHLIGHTS_QUERY.to_string()),
169175
_ => None,
170176
}
171177
}
178+
179+
// fn print_highlights_sexp<W: std::io::Write>(
180+
// tree: &Tree,
181+
// language_id: LanguageId,
182+
// source_code: &str,
183+
// writer: &mut W,
184+
// ) -> std::io::Result<()> {
185+
// let Some(language) = get_ts_language(language_id) else {
186+
// return Ok(());
187+
// };
188+
//
189+
// let Some(query) = get_ts_query(language_id) else {
190+
// return Ok(());
191+
// };
192+
//
193+
// let Ok(query) = tree_sitter::Query::new(&language.into(), &query) else {
194+
// return Ok(());
195+
// };
196+
//
197+
// let mut query_cursor = tree_sitter::QueryCursor::new();
198+
// let mut matches = query_cursor.matches(&query, tree.root_node(), source_code.as_bytes());
199+
//
200+
// let mut nodes_with_captures = Vec::new();
201+
// while let Some(match_) = matches.next() {
202+
// for capture in match_.captures {
203+
// let node = capture.node;
204+
// let capture_name = &query.capture_names()[capture.index as usize];
205+
// nodes_with_captures.push((node, capture_name));
206+
// }
207+
// }
208+
//
209+
// nodes_with_captures.sort_by_key(|(node, _)| (node.start_position(), node.end_position()));
210+
//
211+
// for (node, capture_name) in nodes_with_captures {
212+
// let text = &source_code[node.start_byte()..node.end_byte()];
213+
// writeln!(
214+
// writer,
215+
// "({} \"{}\" @{})",
216+
// node.kind(),
217+
// text.replace('"', "\\\""),
218+
// capture_name
219+
// )?;
220+
// //writeln!(writer, "@{}", capture_name)?;
221+
// }
222+
//
223+
// Ok(())
224+
// }

glyph-runtime/src/editor.rs

+15
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ pub fn setup_editor_api(
3131
lua.create_function(move |lua: &Lua, args: Table| editor_write(lua, args, sender.clone()))?,
3232
)?;
3333

34+
let sender = runtime_sender.clone();
35+
core.set(
36+
"editor_open_file",
37+
lua.create_function(move |_: &Lua, filename: mlua::String| editor_open_file(filename, sender.clone()))?,
38+
)?;
39+
3440
Ok(())
3541
}
3642

@@ -74,3 +80,12 @@ fn editor_write(
7480

7581
Ok(())
7682
}
83+
84+
fn editor_open_file(
85+
filename: mlua::String,
86+
runtime_sender: UnboundedSender<RuntimeMessage<'static>>,
87+
) -> mlua::Result<()> {
88+
let filename = filename.to_string_lossy();
89+
runtime_sender.send(RuntimeMessage::OpenFile(filename)).ok();
90+
Ok(())
91+
}

glyph-runtime/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ pub enum RuntimeMessage<'msg> {
4040
Error(String),
4141
Quit(QuitOptions),
4242
Write(WriteOptions),
43+
OpenFile(String),
4344
}
4445

4546
pub fn setup_lua_runtime(

glyph-term/src/layers/editor_layer.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -333,10 +333,14 @@ impl EditorLayer {
333333
Mode::Command => match key_event.code {
334334
KeyCode::Char(ch) => editor.command.push(ch),
335335
KeyCode::Enter => {
336-
if let Some(command) = config.user_commands.get(&editor.command) {
337-
let window = editor.focused_tab().tree.focus();
338-
let document = editor.focused_tab().tree.window(window).document;
339-
command.call::<()>(usize::from(document) as i64).ok();
336+
if editor.command.is_empty() {
337+
return Ok(None);
338+
}
339+
340+
let pieces = editor.command.split_whitespace().collect::<Vec<_>>();
341+
342+
if let Some(command) = config.user_commands.get(pieces[0]) {
343+
command.call::<()>(&pieces[1..]).unwrap();
340344
editor.command.clear();
341345
editor.set_mode(Mode::Normal);
342346
}

glyph-term/src/ui/line_number.rs

+12-3
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,16 @@ impl LineNumberDrawer for RelativeLineDrawer {
106106
let diff = cursor.y().abs_diff(line);
107107
let style = if diff == 0 { current_line_style } else { style };
108108

109-
write!(&mut line_str, "{:>width$}", diff, width = line_size).unwrap();
109+
write!(&mut line_str, "{:>width$} ", diff, width = line_size).unwrap();
110+
buffer.set_string(x, area.y + row as u16, &line_str, *style);
111+
}
112+
113+
let remaining = area.height as usize - (end - start);
114+
for line in 0..remaining {
115+
line_str.clear();
116+
use std::fmt::Write;
117+
let row = end - start + line;
118+
write!(&mut line_str, "{diff:>width$} ", diff = "~", width = line_size).unwrap();
110119
buffer.set_string(x, area.y + row as u16, &line_str, *style);
111120
}
112121
}
@@ -141,7 +150,7 @@ impl LineNumberDrawer for RelativeNumberedLineDrawer {
141150
let style = if diff == 0 { current_line_style } else { style };
142151
let diff = if diff == 0 { cursor.y() + 1 } else { diff };
143152

144-
write!(&mut line_str, "{:>width$}", diff, width = line_size).unwrap();
153+
write!(&mut line_str, "{:>width$} ", diff, width = line_size).unwrap();
145154
buffer.set_string(x, area.y + row as u16, &line_str, *style);
146155
}
147156

@@ -150,7 +159,7 @@ impl LineNumberDrawer for RelativeNumberedLineDrawer {
150159
line_str.clear();
151160
use std::fmt::Write;
152161
let row = end - start + line;
153-
write!(&mut line_str, "{diff:>width$}", diff = "~", width = 6).unwrap();
162+
write!(&mut line_str, "{diff:>width$} ", diff = "~", width = line_size).unwrap();
154163
buffer.set_string(x, area.y + row as u16, &line_str, *style);
155164
}
156165
}

glyph/src/glyph.rs

+27-11
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,10 @@ where
3636
runtime_receiver: ReceiverStream<RuntimeMessage<'static>>,
3737
}
3838

39+
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, PartialOrd, Ord)]
3940
pub enum ControlFlow {
4041
Break,
42+
Continue,
4143
}
4244

4345
#[derive(Debug)]
@@ -145,14 +147,13 @@ where
145147
Some(event) = input_stream.next() => {
146148
self.handle_event(event?)?;
147149
self.draw_frame()?;
148-
None
150+
ControlFlow::Continue
149151
}
150-
Some(message) = self.runtime_receiver.next() => self.handle_runtime_message(message),
152+
Some(message) = self.runtime_receiver.next() => self.handle_runtime_message(message)?,
151153
};
152154

153-
match control_flow {
154-
Some(ControlFlow::Break) => break Ok(()),
155-
None => {}
155+
if control_flow == ControlFlow::Break {
156+
break Ok(());
156157
}
157158
}
158159
}
@@ -167,20 +168,19 @@ where
167168
self.renderer.handle_event(&event, &mut context, &self.config)
168169
}
169170

170-
fn handle_runtime_message(&mut self, message: RuntimeMessage) -> Option<ControlFlow> {
171+
fn handle_runtime_message(&mut self, message: RuntimeMessage) -> Result<ControlFlow, io::Error> {
171172
match message {
172173
RuntimeMessage::UpdateHighlightGroup(_, _) => todo!(),
173174
RuntimeMessage::SetKeymap(_) => todo!(),
174175
RuntimeMessage::UserCommandCreate(_, _) => todo!(),
175176
RuntimeMessage::Error(_) => todo!(),
176177
RuntimeMessage::Quit(options) => match (options.force, options.all) {
177-
(true, true) => return Some(ControlFlow::Break),
178+
(true, true) => return Ok(ControlFlow::Break),
178179
(true, false) => todo!(),
179180
(false, true) => {}
180181
(false, false) => {
181-
let should_quit = self.editor.write().close_active_window();
182-
if should_quit {
183-
return Some(ControlFlow::Break);
182+
if self.editor.write().close_active_window() {
183+
return Ok(ControlFlow::Break);
184184
}
185185
}
186186
},
@@ -195,11 +195,27 @@ where
195195
let window = tab.tree.window(window);
196196
let document = window.document;
197197
editor.write_document(document);
198+
drop(editor);
199+
self.draw_frame()?;
198200
}
199201
},
202+
RuntimeMessage::OpenFile(filename) => {
203+
let mut editor = self.editor.write();
204+
if filename.is_empty() {
205+
editor.new_file(OpenAction::Replace);
206+
return Ok(ControlFlow::Continue);
207+
}
208+
let text = std::fs::read_to_string(&filename).expect("TODO: handle this error");
209+
let (_, document) = editor.new_file_with_document(filename, text, OpenAction::Replace);
210+
let document = editor.document(document);
211+
self.highlighter.add_document(document);
212+
213+
drop(editor);
214+
self.draw_frame()?;
215+
}
200216
};
201217

202-
None
218+
Ok(ControlFlow::Continue)
203219
}
204220

205221
fn draw_frame(&mut self) -> Result<(), std::io::Error> {

0 commit comments

Comments
 (0)