use duat_core::{
Ns, cmd,
form::{self, Form},
mode,
text::{Text, txt},
};
use regex_syntax::ast::Ast;
use crate::{modes::Pager, widgets::LogBook};
mod buffer_parser;
pub mod modes;
pub mod state;
pub mod widgets;
#[derive(Default)]
pub struct DuatBase {
pub default_opts_parser: bool,
}
impl DuatBase {
#[doc(hidden)]
#[inline(never)]
pub fn _plug(self) {
widgets::add_info_hooks();
widgets::add_logbook_hooks();
widgets::add_notifications_hook();
widgets::add_promptline_hooks();
widgets::add_whichkey_hooks();
widgets::setup_completions();
modes::add_prompt_hook();
if self.default_opts_parser {
buffer_parser::enable_parser();
}
form::set_weak("linenum.main", Form::new().yellow());
form::set_weak("linenum.wrapped", Form::new().cyan().italic());
form::set_weak("buffer", Form::new().yellow().italic());
form::set_weak("selections", Form::new().dark_blue());
form::set_weak("coord", Form::mimic("contant"));
form::set_weak("separator", Form::mimic("punctuation.delimiter"));
form::set_weak("mode", Form::new().green());
form::set_weak("default.StatusLine", Form::new().on_dark_grey());
form::set_weak("default.LogBook", Form::new().on_dark_grey());
form::set_weak("log_book.error", Form::mimic("default.error"));
form::set_weak("log_book.warn", Form::mimic("default.warninging"));
form::set_weak("log_book.info", Form::mimic("default.info"));
form::set_weak("log_book.debug", Form::mimic("default.debug"));
form::set_weak("log_book.colon", Form::mimic("prompt.colon"));
form::set_weak("log_book.bracket", Form::mimic("punctuation.bracket"));
form::set_weak("log_book.target", Form::mimic("module"));
form::set_weak("prompt.preview", Form::mimic("comment"));
form::set_weak("default.Completions", Form::new().on_dark_grey());
form::set_weak("selected.Completions", Form::new().black().on_grey());
form::set_weak("key", Form::mimic("const"));
form::set_weak("key.mod", Form::mimic("punctuation.bracket"));
form::set_weak("key.angle", Form::mimic("punctuation.bracket"));
form::set_weak("key.special", Form::new().yellow());
form::set_weak("remap", Form::new().italic());
cmd::add("logs", |pa: &mut _| {
mode::set(pa, Pager::<LogBook>::new());
Ok(None)
})
.doc(
txt!("Open the [a]Logs[] and enter [mode]Pager[] mode"),
None,
);
}
}
pub mod hooks {
use duat_core::{data::Pass, hook::Hookable};
pub struct SearchUpdated(pub(crate) (String, String));
impl Hookable for SearchUpdated {
type Input<'h> = (&'h str, &'h str);
fn get_input<'h>(&'h mut self, _: &mut Pass) -> Self::Input<'h> {
(&self.0.0, &self.0.1)
}
}
pub struct SearchPerformed(pub(crate) String);
impl Hookable for SearchPerformed {
type Input<'h> = &'h str;
fn get_input<'h>(&'h mut self, _: &mut Pass) -> Self::Input<'h> {
&self.0
}
}
}
fn tag_from_ast(ns: Ns, text: &mut Text, ast: &Ast) {
use duat_core::form::FormId;
use regex_syntax::ast::{Ast::*, Span};
let mut insert_form = |id: FormId, span: Span| {
text.insert_tag(ns, span.start.offset..span.end.offset, id.to_tag(0));
};
match ast {
Empty(_) => {}
Flags(set_flags) => {
let id = form::id_of!("regex.operator.flags");
insert_form(id, set_flags.span);
}
Literal(literal) => {
let id = form::id_of!("regex.literal");
insert_form(id, literal.span);
}
Dot(span) => {
let id = form::id_of!("regex.operator.dot");
insert_form(id, **span);
}
Assertion(assertion) => {
let id = form::id_of!("regex.operator.assertion");
insert_form(id, assertion.span);
}
ClassUnicode(class) => {
let id = form::id_of!("regex.class.unicode");
insert_form(id, class.span);
}
ClassPerl(class) => {
let id = form::id_of!("regex.class.perl");
insert_form(id, class.span);
}
ClassBracketed(class) => {
let class_id = form::id_of!("regex.class.bracketed");
let bracket_id = form::id_of!("regex.bracket.class");
insert_form(class_id, *class.kind.span());
let range = class.span.start.offset..class.span.start.offset + 1;
text.insert_tag(ns, range, bracket_id.to_tag(0));
let range = class.span.end.offset - 1..class.span.end.offset;
text.insert_tag(ns, range, bracket_id.to_tag(0));
}
Repetition(repetition) => {
let id = form::id_of!("regex.operator.repetition");
insert_form(id, repetition.op.span);
}
Group(group) => {
let group_id = form::id_of!("regex.group");
let bracket_id = form::id_of!("regex.bracket.group");
insert_form(group_id, *group.ast.span());
let range = group.span.start.offset..group.span.start.offset + 1;
text.insert_tag(ns, range, bracket_id.to_tag(0));
let range = group.span.end.offset - 1..group.span.end.offset;
text.insert_tag(ns, range, bracket_id.to_tag(0));
tag_from_ast(ns, text, &group.ast);
}
Alternation(alternation) => {
let id = form::id_of!("regex.operator.alternation");
let mut prev_end = None;
for ast in alternation.asts.iter() {
tag_from_ast(ns, text, ast);
if let Some(end) = prev_end {
let range = end..ast.span().start.offset;
text.insert_tag(ns, range, id.to_tag(0));
}
prev_end = Some(ast.span().end.offset);
}
}
Concat(concat) => {
for ast in concat.asts.iter() {
tag_from_ast(ns, text, ast);
}
}
}
}
#[doc(hidden)]
pub mod private_exports {
pub use duat_core::{context::Handle, data::Pass, form, text::Builder, ui::PushSpecs};
pub use format_like::format_like;
}