Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Engine and DocSet, use FocusTarget, bump ppp. #91

Merged
merged 2 commits into from
Apr 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@ bit-set = "0.5"
typed-arena = "2.0"
generational-arena = "0.2"
crossterm = "0.27.0"
serde = { version = "1.0", features = ["derive"] }
ron = "0.8.1"
[dependencies.partial-pretty-printer]
git = "https://github.com/justinpombrio/partial-pretty-printer"
version = "0.4.0"
version = "0.5.1"
features = ["serialization"]
[dependencies.no-nonsense-flamegraphs]
version = "0.2.*"
git = "https://github.com/justinpombrio/no-nonsense-flamegraphs"
Expand Down
17 changes: 15 additions & 2 deletions src/engine/doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use super::doc_command::{
TextNavCommand, TreeEdCommand, TreeNavCommand,
};
use crate::language::Storage;
use crate::pretty_doc::DocRef;
use crate::tree::{Bookmark, Location, Mode, Node};
use crate::util::{bug_assert, SynlessBug};
use std::collections::HashMap;
Expand Down Expand Up @@ -42,6 +43,7 @@ pub enum DocError {
EmptyClipboard,
}

#[derive(Debug)]
pub struct Doc {
cursor: Location,
recent: Option<UndoGroup>,
Expand All @@ -61,6 +63,18 @@ impl Doc {
}
}

pub fn doc_ref_source<'d>(&self, s: &'d Storage) -> DocRef<'d> {
DocRef::new_source(s, self.cursor, self.cursor.root_node(s))
}

pub fn doc_ref_display<'d>(&self, s: &'d Storage) -> DocRef<'d> {
DocRef::new_display(s, self.cursor, self.cursor.root_node(s))
}

pub fn cursor(&self) -> Location {
self.cursor
}

pub fn mode(&self) -> Mode {
self.cursor.mode()
}
Expand All @@ -78,7 +92,7 @@ impl Doc {
DocCommand::Ed(cmd) => execute_ed(s, cmd, &mut self.cursor)?,
DocCommand::Clipboard(cmd) => execute_clipboard(s, cmd, &mut self.cursor, clipboard)?,
DocCommand::Nav(cmd) => {
execute_nav(s, cmd, &mut self.cursor, &mut self.bookmarks, clipboard)?;
execute_nav(s, cmd, &mut self.cursor, &mut self.bookmarks)?;
Vec::new()
}
};
Expand Down Expand Up @@ -191,7 +205,6 @@ fn execute_nav(
cmd: NavCommand,
cursor: &mut Location,
bookmarks: &mut HashMap<char, Bookmark>,
clipboard: &mut Vec<Node>,
) -> Result<(), DocError> {
match cmd {
NavCommand::Tree(cmd) => execute_tree_nav(s, cmd, cursor),
Expand Down
148 changes: 148 additions & 0 deletions src/engine/doc_set.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
use super::doc::Doc;
use super::Settings;
use crate::language::Storage;
use crate::pretty_doc::DocRef;
use crate::util::SynlessBug;
use partial_pretty_printer as ppp;
use partial_pretty_printer::pane;
use std::collections::HashMap;
use std::path::{Path, PathBuf};

type DocIndex = usize;

/// Label for documents that might be displayed on the screen.
///
/// Sample PaneNotation, and its corresponding DocLabels:
///
/// ```text
/// +----------------------------+
/// | doc1 |*doc2*| doc3 | |
/// +----------------------------+
/// | |
/// | This is the visible doc. |
/// | |
/// +----------------------------+
/// | doc2.rs 27,1 |
/// +----------------------------+
/// |i->insert h->left |
/// |s->save l->right |
/// +----------------------------+
///
/// +----------------------------+
/// | Aux(tab_bar) |
/// +----------------------------+
/// | |
/// | Visible |
/// | |
/// +----------------------------+
/// | Meta(name) Meta(linecol) |
/// +----------------------------+
/// | |
/// | Aux(key_hints) |
/// +----------------------------+
/// ```
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum DocLabel {
/// The "real" document that the user is viewing and editing.
Visible,
/// An auto-generated doc containing info about the `Visible` doc, for use in a status bar.
Metadata(String),
/// An auto-generated doc used to implement UI elements like menus.
Auxilliary(String),
}

#[derive(Debug)]
pub struct DocSet {
file_path_to_doc: HashMap<PathBuf, DocIndex>,
/// INVARIANT: DocLabel::Visible is always present.
label_to_doc: HashMap<DocLabel, DocIndex>,
/// DocIndex -> Doc
docs: Vec<Doc>,
}

impl DocSet {
pub fn new(starting_doc: Doc) -> DocSet {
let mut doc_set = DocSet {
file_path_to_doc: HashMap::new(),
label_to_doc: HashMap::new(),
docs: Vec::new(),
};
let starting_doc_index = doc_set.insert_doc(starting_doc);
doc_set
.label_to_doc
.insert(DocLabel::Visible, starting_doc_index);
doc_set
}

pub fn visible_doc(&self) -> &Doc {
let doc_index = *self
.label_to_doc
.get(&DocLabel::Visible)
.bug_msg("VisibleDoc not found");
self.docs.get(doc_index).bug()
}

pub fn metadata_doc(&self, name: &str) -> Option<&Doc> {
let doc_index = *self
.label_to_doc
.get(&DocLabel::Metadata(name.to_owned()))?;
Some(self.docs.get(doc_index).bug())
}

pub fn auxilliary_doc(&self, name: &str) -> Option<&Doc> {
let doc_index = *self
.label_to_doc
.get(&DocLabel::Auxilliary(name.to_owned()))?;
Some(self.docs.get(doc_index).bug())
}

pub fn file_doc(&self, file_path: &Path) -> Option<&Doc> {
let doc_index = *self.file_path_to_doc.get(file_path)?;
Some(self.docs.get(doc_index).bug())
}

pub fn get_content<'s>(
&self,
s: &'s Storage,
label: DocLabel,
settings: &Settings,
) -> Option<(DocRef<'s>, pane::PrintingOptions)> {
let meta_and_aux_options = pane::PrintingOptions {
focus_path: vec![],
focus_target: ppp::FocusTarget::Start,
focus_height: 0.0,
width_strategy: pane::WidthStrategy::Full,
set_focus: false,
};

let (doc, opts) = match label {
DocLabel::Visible => {
let doc = self.visible_doc();
let (focus_path, focus_target) = doc.cursor().path_from_root(s);
let options = pane::PrintingOptions {
focus_path,
focus_target,
focus_height: settings.focus_height,
width_strategy: pane::WidthStrategy::NoMoreThan(settings.max_display_width),
set_focus: true,
};
(doc, options)
}
DocLabel::Metadata(name) => {
let doc = self.metadata_doc(&name)?;
(doc, meta_and_aux_options)
}
DocLabel::Auxilliary(name) => {
let doc = self.auxilliary_doc(&name)?;
(doc, meta_and_aux_options)
}
};
Some((doc.doc_ref_display(s), opts))
}

fn insert_doc(&mut self, doc: Doc) -> usize {
let doc_index = self.docs.len();
self.docs.push(doc);
doc_index
}
}
110 changes: 110 additions & 0 deletions src/engine/engine.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
#![allow(clippy::module_inception)]

use super::doc::Doc;
use super::doc_set::{DocLabel, DocSet};
use super::Settings;
use crate::language::{Language, LanguageError, LanguageSpec, NotationSetSpec, Storage};
use crate::pretty_doc::{DocRef, PrettyDocError};
use crate::style::Style;
use crate::tree::{Bookmark, Node};
use crate::util::SynlessBug;
use partial_pretty_printer as ppp;
use partial_pretty_printer::pane;
use std::path::Path;

// TODO: think about error types
#[derive(thiserror::Error, Debug)]
pub enum EngineError {
#[error("Did not find doc named '{0}'")]
DocNotFound(String),
#[error("{0}")]
PrintingError(#[from] ppp::PrintingError<PrettyDocError>),
#[error("{0}")]
LanguageError(#[from] LanguageError),
}

#[derive(Debug)]
pub struct Engine {
storage: Storage,
doc_set: DocSet,
clipboard: Vec<Node>,
settings: Settings,
}

impl Engine {
pub fn new(settings: Settings) -> Engine {
todo!()
}

/*************
* Languages *
*************/

pub fn add_language(&mut self, language_spec: LanguageSpec) -> Result<(), EngineError> {
self.storage.add_language(language_spec)?;
Ok(())
}

pub fn add_notation(
&mut self,
language_name: &str,
notation: NotationSetSpec,
) -> Result<(), EngineError> {
let lang = self.storage.language(language_name)?;
lang.add_notation(&mut self.storage, notation)?;
Ok(())
}

pub fn set_display_notation(
&mut self,
language_name: &str,
notation_name: &str,
) -> Result<(), EngineError> {
let lang = self.storage.language(language_name)?;
lang.set_display_notation(&mut self.storage, notation_name)?;
Ok(())
}

pub fn set_source_notation(
&mut self,
language_name: &str,
notation_name: &str,
) -> Result<(), EngineError> {
let lang = self.storage.language(language_name)?;
lang.set_source_notation(&mut self.storage, notation_name)?;
Ok(())
}

pub fn unset_source_notation(&mut self, language_name: &str) -> Result<(), EngineError> {
let lang = self.storage.language(language_name)?;
lang.unset_source_notation(&mut self.storage)?;
Ok(())
}

/******************
* Doc Management *
******************/

pub fn make_empty_doc(&mut self, doc_name: &str, language: Language) {
todo!()
}

/************
* Printing *
************/

fn print_source(&self, doc_path: &Path) -> Result<String, EngineError> {
let doc = self
.doc_set
.file_doc(doc_path)
.ok_or_else(|| EngineError::DocNotFound(doc_path.to_string_lossy().into_owned()))?;
let doc_ref = doc.doc_ref_source(&self.storage);
let source = ppp::pretty_print_to_string(doc_ref, self.settings.max_source_width)?;
Ok(source)
}

fn get_content(&self, label: DocLabel) -> Option<(DocRef, pane::PrintingOptions)> {
self.doc_set
.get_content(&self.storage, label, &self.settings)
}
}
21 changes: 21 additions & 0 deletions src/engine/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,23 @@
mod doc;
mod doc_command;
mod doc_set;
mod engine;

use partial_pretty_printer as ppp;

#[derive(Debug, Clone)]
pub struct Settings {
max_source_width: ppp::Width,
max_display_width: ppp::Width,
focus_height: f32,
}

impl Settings {
fn default() -> Settings {
Settings {
max_source_width: 100,
max_display_width: 120,
focus_height: 0.5,
}
}
}
Loading
Loading