A simple CPU rendered GUI IDE experience.
Diffstat (limited to 'src/edi.rs')
-rw-r--r--src/edi.rs229
1 files changed, 67 insertions, 162 deletions
diff --git a/src/edi.rs b/src/edi.rs
index d840540..31ac71a 100644
--- a/src/edi.rs
+++ b/src/edi.rs
@@ -1,6 +1,5 @@
use std::borrow::Cow;
use std::collections::HashMap;
-use std::fs::OpenOptions;
use std::mem::take;
use std::ops::ControlFlow;
use std::path::{Path, PathBuf};
@@ -8,14 +7,12 @@ use std::sync::Arc;
use std::time::SystemTime;
use Default::default;
-use anyhow::anyhow;
use implicit_fn::implicit_fn;
use lsp_server::{Connection, Request as LRq, ResponseError};
use lsp_types::request::*;
use lsp_types::*;
use regex::Regex;
use ropey::Rope;
-use rust_analyzer::lsp::ext::OnTypeFormatting;
use rust_fsm::StateMachine;
use serde_derive::{Deserialize, Serialize};
use tokio::sync::oneshot::Sender;
@@ -29,7 +26,7 @@ pub mod st;
use st::*;
use crate::bar::Bar;
-use crate::complete::Complete;
+use crate::com::Complete;
use crate::hov::{self, Hovr};
use crate::lsp::{
self, Anonymize, Client, Map_, PathURI, RedrawAfter, RequestError, Rq,
@@ -38,7 +35,9 @@ use crate::meta::META;
use crate::sym::{Symbols, SymbolsList, SymbolsType};
use crate::text::cursor::{Ronge, ceach};
use crate::text::hist::{ClickHistory, Hist};
-use crate::text::{self, Mapping, RopeExt, SortTedits, TextArea};
+use crate::text::{
+ self, CoerceOption, Mapping, RopeExt, SortTedits, TextArea,
+};
use crate::{
BoolRequest, CDo, CompletionAction, CompletionState, act, alt, ctrl,
filter, hash, shift, sig, sym, trm,
@@ -178,11 +177,6 @@ macro_rules! change {
($self:ident, $w:expr) => {
change!(@$self, Some($w))
};
- (just $self:ident) => {
- lsp!($self + p).map(|(x, origin)| {
- x.edit(&origin, $self.text.rope.to_string()).unwrap();
- })
- };
(@$self:ident, $w:expr) => {
lsp!($self + p).map(|(x, origin)| {
x.edit(&origin, $self.text.rope.to_string()).unwrap();
@@ -217,7 +211,6 @@ macro_rules! change {
});
};
}
-
fn rooter(x: &Path) -> Option<PathBuf> {
for f in std::fs::read_dir(&x).unwrap().filter_map(Result::ok) {
if f.file_name() == "Cargo.toml" {
@@ -267,6 +260,7 @@ impl Editor {
.map(|x| x.path().to_owned())
.collect::<Vec<_>>()
});
+ assert!(me.tree.is_some());
let l = me.workspace.as_ref().map(|workspace| {
let dh = std::panic::take_hook();
let main = std::thread::current_id();
@@ -388,10 +382,8 @@ impl Editor {
self.bar.last_action = "saved".into();
lsp!(self + p).map(|(l, o)| {
let v = l.runtime.block_on(l.format(o)).unwrap();
- if let Some(v) = v {
- if let Err(()) =
- self.text.apply_tedits_adjusting(&mut { v })
- {
+ for v in v.coerce() {
+ if let Err(()) = self.text.apply_adjusting(&v) {
eprintln!("unhappy fmt")
}
}
@@ -453,7 +445,7 @@ impl Editor {
|x, (_, p)| {
let Some(p) = p else { unreachable!() };
x.ok().flatten().map(|r| sym::Symbols {
- data: (r, p.data.1, p.data.2),
+ r,
selection: 0,
vo: 0,
..p
@@ -728,8 +720,6 @@ impl Editor {
vo: 0,
cells: cells.into(),
},
- range: x.range,
- // range: x.range.and_then(|x| text.l_range(x)),
}
.into(),
))
@@ -809,8 +799,23 @@ impl Editor {
self.hist.lc = text.cursor.clone();
}
Some(Do::GoToDefinition) => {
- if let Some(x) = self.requests.def.result.clone() {
- self.open_loclink(&x, w.clone());
+ if let Some(LocationLink {
+ ref target_uri,
+ target_range,
+ ..
+ }) = self.requests.def.result
+ {
+ self.open(
+ &target_uri.to_file_path().unwrap(),
+ w.clone(),
+ )
+ .unwrap();
+
+ self.text.cursor.just(
+ self.text.l_position(target_range.start).unwrap(),
+ &self.text.rope,
+ );
+ self.text.scroll_to_cursor();
}
}
Some(Do::InsertCursorAtMouse) => {
@@ -826,7 +831,6 @@ impl Editor {
_ => unreachable!(),
}
}
-
pub fn nav_back(&mut self) {
self.chist.back().map(|x| {
self.text.cursor.just(
@@ -941,9 +945,9 @@ impl Editor {
else {
unreachable!()
};
- x.data.2 = sym::SymbolsType::Document;
+ x.ty = sym::SymbolsType::Document;
let p = p.to_owned();
- take(&mut x.data.0);
+ take(&mut x.r);
*request = Some((
DropH::new(lsp.runtime.spawn(
window.redraw_after(async move {
@@ -956,12 +960,6 @@ impl Editor {
(),
));
},
- Some(Do::ProcessCommand(x)) => {
- let z = x.sel();
- if let Err(e) = self.handle_command(z, window.clone()) {
- self.bar.last_action = format!("{e}");
- }
- }
Some(Do::SymbolsHandleKey) => {
if let Some(lsp) = lsp!(self) {
let State::Symbols(Rq { result: Some(x), request }) =
@@ -978,7 +976,7 @@ impl Editor {
.is_some()
|| ptedit != x.tedit.rope
{
- if x.data.2 == SymbolsType::Workspace {
+ if x.ty == SymbolsType::Workspace {
*request = Some((
DropH::new(
lsp.runtime.spawn(
@@ -1007,13 +1005,6 @@ impl Editor {
unreachable!()
};
x.next();
- match x.sel().at {
- sym::GoTo::R(x) => {
- let x = self.text.l_range(x).unwrap();
- self.text.vo = self.text.char_to_line(x.start);
- }
- _ => {}
- }
}
Some(Do::SymbolsSelectPrev) => {
let State::Symbols(Rq { result: Some(x), .. }) =
@@ -1022,13 +1013,18 @@ impl Editor {
unreachable!()
};
x.back();
- match x.sel().at {
- sym::GoTo::R(x) => {
- let x = self.text.l_range(x).unwrap();
- self.text.vo = self.text.char_to_line(x.start);
- }
- _ => {}
- }
+ }
+ Some(Do::CommandNext) => {
+ let State::Command(x) = &mut self.state else {
+ unreachable!()
+ };
+ x.next();
+ }
+ Some(Do::CommandPrev) => {
+ let State::Command(x) = &mut self.state else {
+ unreachable!()
+ };
+ x.back();
}
Some(Do::SymbolsSelect) => {
let State::Symbols(Rq { result: Some(x), .. }) =
@@ -1044,7 +1040,7 @@ impl Editor {
let f = x
.uri
.to_file_path()
- .map_err(|()| anyhow!("dammit"))?
+ .map_err(|()| anyhow::anyhow!("dammit"))?
.canonicalize()?;
self.state = State::Default;
self.requests.complete = CompletionState::None;
@@ -1058,7 +1054,7 @@ impl Editor {
let p = self
.text
.l_position(r.start)
- .ok_or(anyhow!("rah"))?;
+ .ok_or(anyhow::anyhow!("rah"))?;
if p != 0 {
self.text.cursor.just(p, &self.text.rope);
}
@@ -1236,58 +1232,14 @@ impl Editor {
self.requests.complete
{
} else {
- if let Some(x) = handle2(
- &event.logical_key,
- &mut self.text,
- lsp!(self + p),
- ) && let Some((l, p)) = lsp!(self + p)
- && let Some(
- InitializeResult {
- capabilities:
- ServerCapabilities {
- document_on_type_formatting_provider:
- Some(DocumentOnTypeFormattingOptions {
- first_trigger_character,
- more_trigger_character: Some(t),
- }),
- ..
- },
- ..
- },
- ..,
- ) = &l.initialized
- && (first_trigger_character == first_trigger_character
- || t.iter().any(|y| y == x))
- && self.text.cursor.inner.len() == 1
- && change!(just self).is_some()
- && let Ok(Some(mut x)) = l
- .request_immediate::<OnTypeFormatting>(
- &DocumentOnTypeFormattingParams {
- text_document_position:
- TextDocumentPositionParams {
- text_document: p.tid(),
- position: self
- .text
- .to_l_position(
- *self.text.cursor.first(),
- )
- .unwrap(),
- },
- ch: x.into(),
- options: FormattingOptions {
- tab_size: 4,
- ..default()
- },
- },
- )
- {
- x.sort_tedits();
- for x in x {
- self.text.apply_snippet_tedit(&x).unwrap();
- }
+ handle2(
+ &event.logical_key,
+ &mut self.text,
+ lsp!(self + p),
+ );
}
- };
self.text.scroll_to_cursor();
+ inlay!(self);
if cb4 != self.text.cursor.first()
&& let CompletionState::Complete(Rq {
result: Some(c),
@@ -1703,38 +1655,33 @@ impl Editor {
let position = self.text.line_to_char(y);
self.text.cursor.add(position + x, &self.text.rope);
}
+ Some(Do::ProcessCommand(text)) => match text.sel() {
+ "w" => self.save(),
+ "q" => return ControlFlow::Break(()),
+ "exit-vim-mode" => {
+ self.state = State::Default;
+ }
+ _ => {}
+ },
None => {}
}
ControlFlow::Continue(())
}
pub fn apply_wsedit(&mut self, x: WorkspaceEdit, f: &Path) {
+ let mut f_ = |edits: &mut [SnippetTextEdit]| {
+ edits.sort_tedits();
+ // let mut first = false;
+ for edit in edits {
+ self.text.apply_snippet_tedit(edit).unwrap();
+ }
+ };
let mut f2 =
- |TextDocumentEdit { mut edits, text_document, .. }| {
- edits.sort_tedits();
+ |TextDocumentEdit { edits, text_document, .. }| {
if text_document.uri != f.tid().uri {
- let f = OpenOptions::new()
- .read(true)
- .create(true)
- .write(true)
- .open(text_document.uri.path())
- .unwrap();
- let mut r = Rope::from_reader(f).unwrap();
- for edit in &edits {
- TextArea::apply_snippet_tedit_raw(edit, &mut r);
- }
- r.write_to(
- OpenOptions::new()
- .write(true)
- .truncate(true)
- .open(text_document.uri.path())
- .unwrap(),
- )
- .unwrap();
- } else {
- for edit in &edits {
- self.text.apply_snippet_tedit(edit).unwrap();
- }
+ log::error!("didnt apply to {}", text_document.uri);
+ return;
}
+ f_(&mut { edits });
};
match x {
WorkspaceEdit {
@@ -1859,23 +1806,8 @@ impl Editor {
.unwrap();
});
}
- self.set_title(w);
Ok(())
}
- pub fn set_title(&self, w: Option<Arc<Window>>) {
- if let Some(x) = w
- && let Some(t) = self.title()
- {
- x.set_title(&t);
- }
- }
- pub fn title(&self) -> Option<String> {
- [self.workspace.as_deref(), self.origin.as_deref()]
- .try_map(|x| {
- x.and_then(Path::file_name).and_then(|x| x.to_str())
- })
- .map(|[wo, or]| format!("gracilaria - {wo} - {or}"))
- }
pub fn store(&mut self) -> anyhow::Result<()> {
let ws = self.workspace.clone();
@@ -1905,33 +1837,6 @@ impl Editor {
}
Ok(())
}
- /// this is so dumb
- pub fn open_loc(
- &mut self,
- Location { uri, range }: &Location,
- w: Arc<Window>,
- ) {
- self.open(&uri.to_file_path().unwrap(), w.clone()).unwrap();
-
- self.text.cursor.just(
- self.text.l_position(range.start).unwrap(),
- &self.text.rope,
- );
- self.text.scroll_to_cursor();
- }
- pub fn open_loclink(
- &mut self,
- LocationLink { target_uri, target_range, .. }: &LocationLink,
- w: Arc<Window>,
- ) {
- self.open(&target_uri.to_file_path().unwrap(), w.clone()).unwrap();
-
- self.text.cursor.just(
- self.text.l_position(target_range.start).unwrap(),
- &self.text.rope,
- );
- self.text.scroll_to_cursor();
- }
}
use NamedKey::*;