A simple CPU rendered GUI IDE experience.
Diffstat (limited to 'src/edi.rs')
| -rw-r--r-- | src/edi.rs | 229 |
1 files changed, 67 insertions, 162 deletions
@@ -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::*; |