-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #91 from justinpombrio/engine
Add Engine and DocSet, use FocusTarget, bump ppp.
- Loading branch information
Showing
16 changed files
with
476 additions
and
147 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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, | ||
} | ||
} | ||
} |
Oops, something went wrong.