From a8eea4e7f73fc9c282716fa5b1731b6337ec4684 Mon Sep 17 00:00:00 2001 From: Justin Date: Mon, 3 Jun 2024 23:09:23 -0400 Subject: [PATCH] feat: add a status bar --- scripts/init.rhai | 4 +- src/engine/doc_set.rs | 2 +- src/engine/engine.rs | 9 +++- src/lib.rs | 4 +- src/runtime.rs | 122 +++++++++++++++++++++++++++++++++--------- src/tree/location.rs | 9 ++++ 6 files changed, 120 insertions(+), 30 deletions(-) diff --git a/scripts/init.rhai b/scripts/init.rhai index c10e28c..fa4bb2b 100644 --- a/scripts/init.rhai +++ b/scripts/init.rhai @@ -100,13 +100,13 @@ tree_keymap.bind_key("p", "Paste", || s::paste()); tree_keymap.bind_key("P", "PasteSwap", || s::paste_swap()); tree_keymap.bind_key("I", "Insert", || { - s::open_menu("candidate_node_selection"); + s::open_menu("candidate_node_selection", "Select node to insert"); let construct = s::block(); s::insert_node(construct); }); tree_keymap.bind_key("i", "QuickInsert", || { - s::open_menu("char_node_selection"); + s::open_menu("char_node_selection", "Select node to insert"); let construct = s::block(); s::insert_node(construct); }); diff --git a/src/engine/doc_set.rs b/src/engine/doc_set.rs index 18008d6..6fb138d 100644 --- a/src/engine/doc_set.rs +++ b/src/engine/doc_set.rs @@ -63,7 +63,7 @@ impl fmt::Display for DocName { use DocName::*; match self { - File(path) => write!(f, "file:{}", path.to_string_lossy()), + File(path) => write!(f, "{}", path.to_string_lossy()), Metadata(name) => write!(f, "metadata:{}", name), Auxilliary(name) => write!(f, "auxilliary:{}", name), } diff --git a/src/engine/engine.rs b/src/engine/engine.rs index 8b3eb0a..aacefc8 100644 --- a/src/engine/engine.rs +++ b/src/engine/engine.rs @@ -7,7 +7,7 @@ use super::Settings; use crate::language::{Language, LanguageSpec, NotationSetSpec, Storage}; use crate::parsing::{Parse, ParseError}; use crate::pretty_doc::DocRef; -use crate::tree::Node; +use crate::tree::{Mode, Node}; use crate::util::{error, SynlessBug, SynlessError}; use partial_pretty_printer as ppp; use partial_pretty_printer::pane; @@ -198,6 +198,13 @@ impl Engine { self.doc_set.get_doc_mut(doc_name) } + pub fn mode(&self) -> Mode { + self.doc_set + .visible_doc() + .map(|doc| doc.mode()) + .unwrap_or(Mode::Tree) + } + /**************************** * Doc Loading and Printing * ****************************/ diff --git a/src/lib.rs b/src/lib.rs index 11f15e6..f5f485a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,8 +17,8 @@ pub use engine::{DocName, Engine, Settings}; pub use frontends::Terminal; pub use keymap::{KeyProg, Keymap, Layer}; pub use language::{ - AritySpec, Construct, ConstructSpec, GrammarSpec, LanguageSpec, NotationSetSpec, SortSpec, - Storage, + AritySpec, Construct, ConstructSpec, GrammarSpec, Language, LanguageSpec, NotationSetSpec, + SortSpec, Storage, }; pub use pretty_doc::DocRef; pub use runtime::Runtime; diff --git a/src/runtime.rs b/src/runtime.rs index a545cbd..345f50a 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -21,12 +21,14 @@ const MENU_NAME_LABEL: &str = "menu_name"; const MODE_LABEL: &str = "mode"; const FILENAME_LABEL: &str = "filename"; const SIBLING_INDEX_LABEL: &str = "sibling_index"; +const ERROR_LABEL: &str = "error"; const KEYHINTS_PANE_WIDTH: usize = 15; pub struct Runtime> { engine: Engine, - pane_notation: pane::PaneNotation, + default_pane_notation: pane::PaneNotation, + menu_pane_notation: pane::PaneNotation, frontend: F, layers: LayerManager, } @@ -40,7 +42,8 @@ impl + 'static> Runtime { Runtime { engine, - pane_notation: make_pane_notation(false), + default_pane_notation: make_pane_notation(false), + menu_pane_notation: make_pane_notation(true), frontend, layers: LayerManager::new(), } @@ -144,12 +147,12 @@ impl + 'static> Runtime { .map_err(|err| error!(Frontend, "{}", err))?; let get_content = |doc_label| self.engine.get_content(doc_label); - pane::display_pane( - &mut self.frontend, - &self.pane_notation, - &Style::default(), - &get_content, - )?; + let note = if self.layers.has_open_menu() { + &self.menu_pane_notation + } else { + &self.default_pane_notation + }; + pane::display_pane(&mut self.frontend, note, &Style::default(), &get_content)?; self.frontend .end_frame() @@ -161,6 +164,9 @@ impl + 'static> Runtime { self.make_keyhint_doc(), self.make_candidate_selection_doc(), self.make_menu_name_doc(), + self.make_mode_doc(), + self.make_filename_doc(), + self.make_sibling_index_doc(), ] { let _ = self.engine.delete_doc(&name); if let Some(node) = node { @@ -180,11 +186,7 @@ impl + 'static> Runtime { fn make_keyhint_doc(&mut self) -> (DocName, Option) { let visible_doc_name = self.engine.visible_doc_name().cloned(); - let mode = if let Some(doc) = self.engine.visible_doc() { - doc.mode() - } else { - Mode::Tree - }; + let mode = self.engine.mode(); let storage = self.engine.raw_storage_mut(); let node = self .layers @@ -200,6 +202,43 @@ impl + 'static> Runtime { (DocName::Auxilliary(MENU_NAME_LABEL.to_owned()), opt_node) } + fn make_mode_doc(&mut self) -> (DocName, Option) { + let mode = match self.engine.mode() { + Mode::Tree => "TREE".to_owned(), + Mode::Text => "TEXT".to_owned(), + }; + let node = self.engine.make_string_doc(mode); + (DocName::Auxilliary(MODE_LABEL.to_owned()), Some(node)) + } + + fn make_filename_doc(&mut self) -> (DocName, Option) { + let opt_doc_name = self.engine.visible_doc_name(); + let opt_label = opt_doc_name.map(|doc_name| match doc_name { + DocName::File(path) => { + let os_str = path.file_name().unwrap_or_else(|| path.as_os_str()); + os_str.to_string_lossy().into_owned() + } + DocName::Metadata(label) => format!("metadata:{}", label), + DocName::Auxilliary(label) => format!("auxilliary:{}", label), + }); + let opt_node = opt_label.map(|label| self.engine.make_string_doc(label)); + (DocName::Auxilliary(FILENAME_LABEL.to_owned()), opt_node) + } + + fn make_sibling_index_doc(&mut self) -> (DocName, Option) { + let opt_label = self.engine.visible_doc().map(|doc| { + let cursor = doc.cursor(); + let s = self.engine.raw_storage(); + let (numerator, denominator) = cursor.sibling_index_info(s); + format!("sibling {}/{}", numerator, denominator) + }); + let opt_node = opt_label.map(|label| self.engine.make_string_doc(label)); + ( + DocName::Auxilliary(SIBLING_INDEX_LABEL.to_owned()), + opt_node, + ) + } + /****************** * Doc Management * ******************/ @@ -382,7 +421,7 @@ impl + 'static> Runtime { * Pane Notations * ******************/ -fn make_pane_notation(_include_menu: bool) -> pane::PaneNotation { +fn make_pane_notation(include_menu: bool) -> pane::PaneNotation { use crate::style::{Base16Color, Priority}; use pane::{PaneNotation, PaneSize}; @@ -390,6 +429,11 @@ fn make_pane_notation(_include_menu: bool) -> pane::PaneNotation pane::PaneNotation (usize, usize) { + match self.0 { + InText(node, _) | AtNode(node) => (node.sibling_index(s) + 1, node.num_siblings(s)), + BelowNode(node) => (0, node.num_children(s).bug()), + } + } + /************** * Navigation * **************/