A simple CPU rendered GUI IDE experience.
-rw-r--r--src/act.rs15
-rw-r--r--src/bar.rs4
-rw-r--r--src/com.rs9
-rw-r--r--src/edi.rs65
-rw-r--r--src/hov.rs11
-rw-r--r--src/lsp.rs12
-rw-r--r--src/main.rs55
-rw-r--r--src/sig.rs2
-rw-r--r--src/sym.rs10
-rw-r--r--src/text.rs24
10 files changed, 149 insertions, 58 deletions
diff --git a/src/act.rs b/src/act.rs
index 248baeb..4b102d6 100644
--- a/src/act.rs
+++ b/src/act.rs
@@ -154,7 +154,7 @@ impl CodeActions {
let mut to = vec![
Cell {
- style: Style { bg, color: FG, flags: 0 },
+ style: Style::new(FG, bg),
..Default::default()
};
c
@@ -171,13 +171,8 @@ impl CodeActions {
}
fn write(x: &CodeAction, c: usize, selected: bool, to: &mut Vec<Cell>) {
let bg = if selected { col!("#262d3b") } else { col!("#1c212b") };
- let mut into = vec![
- Cell {
- style: Style { bg, color: FG, flags: 0 },
- ..Default::default()
- };
- c
- ];
+ let mut into =
+ vec![Cell { style: Style::new(FG, bg), ..Default::default() }; c];
let t = match &x.kind {
Some(x) if x == &CodeActionKind::QUICKFIX => '󰁨',
@@ -190,8 +185,8 @@ fn write(x: &CodeAction, c: usize, selected: bool, to: &mut Vec<Cell>) {
Some(x) if x == &CodeActionKind::SOURCE => '󱇧',
_ => '', /* 󱢇☭ */
};
- into[0].style.color = col!("#E5C07B");
- into[0].style.bg = set_a(into[0].style.color, 0.5);
+ into[0].style.fg = col!("#E5C07B");
+ into[0].style.bg = set_a(into[0].style.fg, 0.5);
into[0].letter = Some(t);
into.iter_mut()
.skip(1)
diff --git a/src/bar.rs b/src/bar.rs
index 3b843eb..ef5d735 100644
--- a/src/bar.rs
+++ b/src/bar.rs
@@ -7,7 +7,7 @@ use lsp_types::WorkDoneProgress;
use crate::lsp::{Client, Rq};
use crate::sym::Symbols;
use crate::text::TextArea;
-
+#[derive(Default)]
pub struct Bar {
pub last_action: String,
}
@@ -26,7 +26,7 @@ impl Bar {
) {
let row = &mut into[oy * w..oy * w + w];
row.fill(Cell {
- style: Style { color, bg, flags: Style::ITALIC },
+ style: Style::new(color, bg) | Style::ITALIC,
letter: None,
});
fn s(s: &str) -> impl Iterator<Item = (char, u8)> {
diff --git a/src/com.rs b/src/com.rs
index 5ee4174..711591a 100644
--- a/src/com.rs
+++ b/src/com.rs
@@ -205,7 +205,7 @@ fn r(
) {
let bg = if selected { col!("#262d3b") } else { col!("#1c212b") };
- let ds: Style = Style { bg: bg, color: FG, flags: 0 };
+ let ds = Style::new(FG, bg);
let d: Cell = Cell { letter: None, style: ds };
let mut b = vec![d; c];
const MAP: [([u8; 3], [u8; 3], &str); 26] = {
@@ -237,7 +237,7 @@ fn r(
let (bgt, col, ty) =
MAP[x.kind.unwrap_or(CompletionItemKind(50)).0 as usize];
b.iter_mut().zip(ty.chars()).for_each(|(x, c)| {
- *x = Style { bg: bgt, color: col, flags: Style::BOLD }.basic(c)
+ *x = (Style::new(col, bgt) | Style::BOLD).basic(c)
});
let i = &mut b[2..];
@@ -267,8 +267,7 @@ fn r(
i.iter_mut()
.rev()
.zip(details.map(|x| {
- Style { bg, color: color_("#979794"), ..default() }
- .basic(x)
+ Style { bg, fg: color_("#979794"), ..default() }.basic(x)
}))
.for_each(|(a, b)| *a = b);
}
@@ -277,7 +276,7 @@ fn r(
x.label.chars().map(|x| ds.basic(x)).zip(0..).chain(
label_details
.map(|x| {
- Style { bg, color: color_("#858685"), ..default() }
+ Style { bg, fg: color_("#858685"), ..default() }
.basic(x)
})
.zip(repeat(u32::MAX)),
diff --git a/src/edi.rs b/src/edi.rs
new file mode 100644
index 0000000..d825409
--- /dev/null
+++ b/src/edi.rs
@@ -0,0 +1,65 @@
+use std::path::PathBuf;
+use std::sync::Arc;
+use std::thread::JoinHandle;
+
+use lsp_types::request::*;
+use lsp_types::*;
+use tokio::sync::oneshot::Sender;
+
+use crate::bar::Bar;
+use crate::hov::Hovr;
+use crate::lsp::{Client, RequestError, Rq, RqS};
+use crate::text::TextArea;
+use crate::{ClickHistory, CompletionState, Hist, State};
+#[derive(Default)]
+pub struct Editor {
+ text: TextArea,
+ origin: Option<PathBuf>,
+ state: State,
+ bar: Bar,
+ workspace: Option<PathBuf>,
+ lsp: Option<(
+ &'static Client,
+ JoinHandle<()>,
+ Sender<Arc<winit::window::Window>>,
+ )>,
+ tree: Option<Vec<PathBuf>>,
+ hovering: Rq<Hovr, Option<Hovr>, (usize, usize), anyhow::Error>,
+ document_highlights: Rq<
+ Vec<DocumentHighlight>,
+ Vec<DocumentHighlight>,
+ (),
+ RequestError<DocumentHighlightRequest>,
+ >,
+ complete: CompletionState,
+ sig_help: Rq<
+ (SignatureHelp, usize, Option<usize>),
+ Option<SignatureHelp>,
+ (),
+ RequestError<SignatureHelpRequest>,
+ >, // vo, lines
+ semantic_tokens: Rq<
+ Box<[SemanticToken]>,
+ Box<[SemanticToken]>,
+ (),
+ RequestError<SemanticTokensFullRequest>,
+ >,
+ diag: Rq<String, Option<String>, (), anyhow::Error>,
+ inlay: Rq<
+ Vec<InlayHint>,
+ Vec<InlayHint>,
+ (),
+ RequestError<lsp_request!("textDocument/inlayHint")>,
+ >,
+ def: Rq<
+ LocationLink,
+ Option<GotoDefinitionResponse>,
+ (usize, usize),
+ RequestError<lsp_request!("textDocument/definition")>,
+ >,
+ chist: ClickHistory,
+ hist: Hist,
+ mtime: Option<std::time::SystemTime>,
+}
+
+impl Editor {}
diff --git a/src/hov.rs b/src/hov.rs
index fca6dac..ce9c510 100644
--- a/src/hov.rs
+++ b/src/hov.rs
@@ -8,8 +8,7 @@ use dsb::cell::Style;
use itertools::Itertools;
use markdown::mdast::{self, Node};
use ropey::Rope;
-const D: Cell =
- Cell { letter: None, style: Style { bg: BG, color: FG, flags: 0 } };
+const D: Cell = Cell { letter: None, style: Style::new(FG, BG) };
use crate::{FG, text};
struct Builder {
@@ -117,17 +116,17 @@ impl Builder {
}
Node::Link(_) => {
inherit.flags |= Style::UNDERLINE;
- inherit.color = [244, 196, 98];
+ inherit.fg = [244, 196, 98];
self.extend(node, inherit)
}
Node::LinkReference(_) => {
inherit.flags |= Style::UNDERLINE;
- inherit.color = [244, 196, 98];
+ inherit.fg = [244, 196, 98];
self.extend(node, inherit)
}
Node::Heading(_) => {
inherit.flags |= Style::BOLD;
- inherit.color = [255, 255, 255];
+ inherit.fg = [255, 255, 255];
self.extend_(node, [Action::Finish], inherit)
}
@@ -229,7 +228,7 @@ pub fn l(node: &Node) -> Vec<usize> {
pub fn markdown2(c: usize, x: &Node) -> Vec<Cell> {
let mut r = Builder { c, to: vec![], scratch: vec![] };
for (is_put, act) in r
- .run(&x, Style { bg: BG, color: FG, flags: 0 })
+ .run(&x, Style::new(FG, BG))
.into_iter()
.chunk_by(|x| matches!(x, Action::Put(_)))
.into_iter()
diff --git a/src/lsp.rs b/src/lsp.rs
index cbfae52..2e09a6d 100644
--- a/src/lsp.rs
+++ b/src/lsp.rs
@@ -355,13 +355,15 @@ impl Client {
}
}
}
- pub fn document_highlights(&'static self, f: &Path, cursor: Position) {
- self.request::<lsp_request!("textDocument/documentHighlight")>(&DocumentHighlightParams {
+ pub fn document_highlights<'me>(&'me self, f: &Path, cursor: Position) -> impl Future<Output = Result<Vec<DocumentHighlight>, RequestError<DocumentHighlightRequest>>> + use<'me> {
+ let p = DocumentHighlightParams {
text_document_position_params: TextDocumentPositionParams { text_document: f.tid(), position: cursor },
-
work_done_progress_params: default(),
partial_result_params: default(),
- }).unwrap();
+ };
+ self.request::<lsp_request!("textDocument/documentHighlight")>(&p).unwrap().0.map(|x| {
+ x.map(|x| x.unwrap_or_default())
+ })
}
pub fn symbols(
&'static self,
@@ -955,7 +957,7 @@ fn x33() {
let y = serde_json::from_str::<SemanticTokensParams>(&y).unwrap();
}
#[pin_project::pin_project]
-struct Map<T, U, F: FnMut(T) -> U, Fu: Future<Output = T>>(#[pin] Fu, F);
+pub struct Map<T, U, F: FnMut(T) -> U, Fu: Future<Output = T>>(#[pin] Fu, F);
impl<T, F: FnMut(T) -> U, U, Fu: Future<Output = T>> Future
for Map<T, U, F, Fu>
{
diff --git a/src/main.rs b/src/main.rs
index 64f8eed..8acf0bd 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -39,6 +39,7 @@ use std::iter::once;
mod act;
mod sym;
mod trm;
+mod edi;
use std::num::NonZeroU32;
use std::os::fd::AsFd;
use std::path::{Path, PathBuf};
@@ -105,6 +106,15 @@ struct Hist {
pub last: TextArea,
pub last_edit: std::time::Instant,
pub changed: bool,
+}impl Default for Hist{
+ fn default() -> Self {
+ Self{
+ history: vec![],
+ redo_history: vec![],
+ last: TextArea::default(),
+ last_edit: Instant::now(),
+ changed: false,
+ } }
}
#[derive(Debug, Default)]
struct ClickHistory {
@@ -199,7 +209,7 @@ impl Hist {
static mut MODIFIERS: ModifiersState = ModifiersState::empty();
static mut CLICKING: bool = false;
-const BG: [u8; 3] = [31, 36, 48];
+const BG: [u8; 3] = col!("#1f2430");
const FG: [u8; 3] = [204, 202, 194];
const BORDER: [u8; 3] = col!("#ffffff");
#[implicit_fn::implicit_fn]
@@ -310,6 +320,7 @@ pub(crate) fn entry(event_loop: EventLoop<()>) {
}
let mut hovering =
Rq::<Hovr, Option<Hovr>, (usize, usize), anyhow::Error>::default();
+ let mut document_highlights: Rq<Vec<DocumentHighlight>, _, _, _> = Rq::default();
let mut complete = CompletionState::None;
let mut sig_help = // vo, lines
RqS::<(SignatureHelp, usize, Option<usize>), SignatureHelpRequest, ()>::default();
@@ -449,15 +460,19 @@ pub(crate) fn entry(event_loop: EventLoop<()>) {
rq =>
log::debug!("discarding request {rq:?}"),
}
- }
+ }
+ let r = &l.runtime;
inlay.poll(|x, p| x.ok().or(p.1).inspect(|x| {
text.set_inlay(x);
- }), &l.runtime);
- diag.poll(|x, _|x.ok().flatten(), &l.runtime);
+ }), r);
+ document_highlights.poll(|x, _| {
+ x.ok()
+ }, r);
+ diag.poll(|x, _|x.ok().flatten(), r);
if let CompletionState::Complete(rq)= &mut complete {
rq.poll(|f, (c,_)| {
f.ok().flatten().map(|x| {Complete {r:x,start:c,selection:0,vo:0,}})
- }, &l.runtime);
+ }, r);
};
if let State::Symbols(x) = &mut state {
@@ -529,7 +544,8 @@ pub(crate) fn entry(event_loop: EventLoop<()>) {
cells = vec![
Cell {
style: Style {
- color: BG,
+ fg: BG,
+ secondary_color: BG,
bg: BG,
flags: 0
},
@@ -572,7 +588,7 @@ pub(crate) fn entry(event_loop: EventLoop<()>) {
return;
}
cells.fill(Cell {
- style: Style { color: BG, bg: BG, flags: 0 },
+ style: Style { fg: BG, secondary_color: BG, bg: BG, flags: 0 },
letter: None,
});
let x = match &state {
@@ -609,6 +625,20 @@ pub(crate) fn entry(event_loop: EventLoop<()>) {
(t_ox, 0),
x,
|(_c, _r), text, mut x| {
+ if let Some(hl) = &document_highlights.result {
+ for DocumentHighlight { range: r, .. } in hl {
+ // let s = match kind {
+ // Some(DocumentHighlightKind::READ) => Style::UNDERLINE,
+ // Some(DocumentHighlightKind::WRITE) => Style::UNDERLINE,
+ // _ => Style::UNDERCURL,
+ // };
+ let (x1, y1) = text.map_to_visual((r.start.character as _, r.start.line as _));
+ let (x2, y2) = text.map_to_visual((r.end.character as _, r.end.line as _));
+ x.get_simple((x1, y1), (x2, y2)).coerce().for_each(|x| {
+ x.style.bg = col!("#3a4358");
+ });
+ }
+ }
if let Some(LocationLink {
origin_selection_range: Some(r), ..
}) = def.result { _ = try {
@@ -616,7 +646,7 @@ pub(crate) fn entry(event_loop: EventLoop<()>) {
let (x2, y2) = text.map_to_visual((r.end.character as _, r.end.line as _));
x.get_simple((x1, y1), (x2, y2))?.iter_mut().for_each(|x| {
x.style.flags |= Style::UNDERLINE;
- x.style.color = col!("#FFD173");
+ x.style.fg = col!("#FFD173");
});
} }
if let Some((lsp, p)) = lsp!() && let uri = Url::from_file_path(p).unwrap() && let Some(diag) = lsp.diagnostics.get(&uri, &lsp.diagnostics.guard()) {
@@ -677,7 +707,7 @@ pub(crate) fn entry(event_loop: EventLoop<()>) {
_ => return
};
x.style.bg.blend(bg);
- x.style.color = fg;
+ x.style.fg = fg;
x.letter = Some(ch);
})
});
@@ -1139,6 +1169,7 @@ hovering.request = (DropH::new(handle), cursor_position).into();
text.cursor = text.mapped_index_at(cursor_position);
if let Some((lsp, path)) = lsp!() {
sig_help.request(lsp.runtime.spawn(window.redraw_after(lsp.request_sig_help(path, text.cursor()))));
+ document_highlights.request(lsp.runtime.spawn(window.redraw_after(lsp.document_highlights(path, text.to_l_position(text.cursor).unwrap()))));
}
hist.last.cursor = text.cursor;
chist.push(text.cursor());
@@ -1735,7 +1766,11 @@ impl State {
}
use std::ops::Range;
-
+impl Default for State {
+ fn default() -> Self {
+ Self::Default
+ }
+}
rust_fsm::state_machine! {
#[derive(Debug)]
pub(crate) State => Action => Do
diff --git a/src/sig.rs b/src/sig.rs
index a70d014..852773b 100644
--- a/src/sig.rs
+++ b/src/sig.rs
@@ -26,7 +26,7 @@ pub fn sig(
c: usize,
) -> Vec<Cell> {
let bg = color_("#1c212b");
- let ds: Style = Style { bg: bg, color: FG, flags: 0 };
+ let ds = Style::new(FG, bg);
let d: Cell = Cell { letter: None, style: ds };
let sig = y.label.chars().zip(0..).map(|(x, i)| {
let mut a = ds.basic(x);
diff --git a/src/sym.rs b/src/sym.rs
index 5882491..bbd0651 100644
--- a/src/sym.rs
+++ b/src/sym.rs
@@ -124,7 +124,7 @@ fn r(
) {
let bg = if selected { col!("#262d3b") } else { col!("#1c212b") };
- let ds: Style = Style { bg: bg, color: FG, flags: 0 };
+ let ds: Style = Style::new(FG, bg);
let d: Cell = Cell { letter: None, style: ds };
let mut b = vec![d; c];
const MAP: [([u8; 3], [u8; 3], &str); 70] = {
@@ -158,7 +158,7 @@ fn r(
};
let (bgt, col, ty) = MAP[x.kind.0 as usize];
b.iter_mut().zip(ty.chars()).for_each(|(x, c)| {
- *x = Style { bg: bgt, color: col, flags: Style::BOLD }.basic(c)
+ *x = (Style::new(col, bgt) | Style::BOLD).basic(c)
});
let i = &mut b[2..];
let qualifier = x
@@ -189,14 +189,14 @@ fn r(
i.iter_mut()
.rev()
.zip(q.map(|x| {
- Style { bg, color: color_("#979794"), ..default() }.basic(x)
+ Style { bg, fg: color_("#979794"), ..default() }.basic(x)
}))
.for_each(|(a, b)| *a = b);
// i.iter_mut()
// .rev()
// .zip(loc.map(|x| {
- // Style { bg, color: color_("#979794"), ..default() }
+ // Style { bg, fg: color_("#979794"), ..default() }
// .basic(x)
// }))
// .for_each(|(a, b)| *a = b);
@@ -212,7 +212,7 @@ fn r(
.map(|x| {
Style {
bg,
- color: color_("#858685"),
+ fg: color_("#858685"),
..default()
}
.basic(x)
diff --git a/src/text.rs b/src/text.rs
index 91c9a61..c5e7b5b 100644
--- a/src/text.rs
+++ b/src/text.rs
@@ -1012,17 +1012,13 @@ impl TextArea {
cells.get((x + self.ho, y)).unwrap().letter =
Some(e.c());
cells.get((x + self.ho, y)).unwrap().style = match e {
- Mapping::Char(..) => Style {
- color: crate::FG,
- bg: crate::BG,
- flags: 0,
- },
+ Mapping::Char(..) =>
+ Style::new(crate::FG, crate::BG),
Mapping::Fake(Mark { ty: INLAY, .. }, ..) =>
- Style {
- color: const { color_("#536172") },
- bg: crate::BG,
- flags: 0,
- },
+ Style::new(
+ const { color_("#536172") },
+ crate::BG,
+ ),
_ => unreachable!(),
};
}
@@ -1118,7 +1114,7 @@ impl TextArea {
)
})
.for_each(|(x, _)| {
- x.style.color = semantic::COLORS[f];
+ x.style.fg = semantic::COLORS[f];
x.style.flags |= semantic::STYLES[f];
});
}
@@ -1153,7 +1149,7 @@ impl TextArea {
)
})
.for_each(|(x, _)| {
- x.style.color = MCOLORS[i];
+ x.style.fg = MCOLORS[i];
x.style.flags |= MSTYLE[i];
});
});
@@ -1194,7 +1190,7 @@ impl TextArea {
.for_each(|(x, _)| {
if x.letter == Some(' ') {
x.letter = Some('·'); // tabs? what are those
- x.style.color = [0x4e, 0x62, 0x79];
+ x.style.fg = [0x4e, 0x62, 0x79];
}
x.style.bg = [0x27, 0x43, 0x64];
// 0x23, 0x34, 0x4B
@@ -1249,7 +1245,7 @@ impl TextArea {
.zip(into[(y + oy) * w..].iter_mut().skip(ox))
.for_each(|(a, b)| {
*b = Cell {
- style: Style { color, bg, flags: 0 },
+ style: Style::new(color, bg),
letter: Some(a),
}
});