diff --git a/Cargo.lock b/Cargo.lock index adce7c95e1..b3c7fdb20e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1670,7 +1670,7 @@ checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" [[package]] name = "floem" version = "0.1.1" -source = "git+https://github.com/lapce/floem?rev=d2a05e8d6f78da4733bf61666d8c94deaa5da6c6#d2a05e8d6f78da4733bf61666d8c94deaa5da6c6" +source = "git+https://github.com/lapce/floem?rev=720e360500582704303c812c1ed78c98048b5428#720e360500582704303c812c1ed78c98048b5428" dependencies = [ "bitflags 2.6.0", "copypasta", @@ -1733,7 +1733,7 @@ dependencies = [ [[package]] name = "floem-editor-core" version = "0.1.1" -source = "git+https://github.com/lapce/floem?rev=d2a05e8d6f78da4733bf61666d8c94deaa5da6c6#d2a05e8d6f78da4733bf61666d8c94deaa5da6c6" +source = "git+https://github.com/lapce/floem?rev=720e360500582704303c812c1ed78c98048b5428#720e360500582704303c812c1ed78c98048b5428" dependencies = [ "bitflags 2.6.0", "itertools 0.12.1", @@ -1811,7 +1811,7 @@ dependencies = [ [[package]] name = "floem_reactive" version = "0.1.1" -source = "git+https://github.com/lapce/floem?rev=d2a05e8d6f78da4733bf61666d8c94deaa5da6c6#d2a05e8d6f78da4733bf61666d8c94deaa5da6c6" +source = "git+https://github.com/lapce/floem?rev=720e360500582704303c812c1ed78c98048b5428#720e360500582704303c812c1ed78c98048b5428" dependencies = [ "smallvec", ] @@ -1819,7 +1819,7 @@ dependencies = [ [[package]] name = "floem_renderer" version = "0.1.1" -source = "git+https://github.com/lapce/floem?rev=d2a05e8d6f78da4733bf61666d8c94deaa5da6c6#d2a05e8d6f78da4733bf61666d8c94deaa5da6c6" +source = "git+https://github.com/lapce/floem?rev=720e360500582704303c812c1ed78c98048b5428#720e360500582704303c812c1ed78c98048b5428" dependencies = [ "floem-cosmic-text", "image", @@ -1830,7 +1830,7 @@ dependencies = [ [[package]] name = "floem_tiny_skia_renderer" version = "0.1.1" -source = "git+https://github.com/lapce/floem?rev=d2a05e8d6f78da4733bf61666d8c94deaa5da6c6#d2a05e8d6f78da4733bf61666d8c94deaa5da6c6" +source = "git+https://github.com/lapce/floem?rev=720e360500582704303c812c1ed78c98048b5428#720e360500582704303c812c1ed78c98048b5428" dependencies = [ "anyhow", "bytemuck", @@ -1847,7 +1847,7 @@ dependencies = [ [[package]] name = "floem_vger_renderer" version = "0.1.1" -source = "git+https://github.com/lapce/floem?rev=d2a05e8d6f78da4733bf61666d8c94deaa5da6c6#d2a05e8d6f78da4733bf61666d8c94deaa5da6c6" +source = "git+https://github.com/lapce/floem?rev=720e360500582704303c812c1ed78c98048b5428#720e360500582704303c812c1ed78c98048b5428" dependencies = [ "anyhow", "floem-vger", diff --git a/Cargo.toml b/Cargo.toml index 3ddcda7d58..ea541d7e97 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -75,9 +75,9 @@ lapce-core = { path = "./lapce-core" } lapce-rpc = { path = "./lapce-rpc" } lapce-proxy = { path = "./lapce-proxy" } -floem = { git = "https://github.com/lapce/floem", rev = "d2a05e8d6f78da4733bf61666d8c94deaa5da6c6", features = ["editor", "serde", "default-image-formats", "rfd-async-std"] } +floem = { git = "https://github.com/lapce/floem", rev = "720e360500582704303c812c1ed78c98048b5428", features = ["editor", "serde", "default-image-formats", "rfd-async-std"] } # floem = { path = "../floem", features = ["editor", "serde", "default-image-formats", "rfd-async-std"] } -floem-editor-core = { git = "https://github.com/lapce/floem", rev = "d2a05e8d6f78da4733bf61666d8c94deaa5da6c6", features = ["serde"] } +floem-editor-core = { git = "https://github.com/lapce/floem", rev = "720e360500582704303c812c1ed78c98048b5428", features = ["serde"] } # floem-editor-core = { path = "../floem/editor-core/", features = ["serde"] } [patch.crates-io] diff --git a/lapce-app/src/app/logging.rs b/lapce-app/src/app/logging.rs index 3ba9d8f328..4a033ac218 100644 --- a/lapce-app/src/app/logging.rs +++ b/lapce-app/src/app/logging.rs @@ -46,7 +46,12 @@ pub(super) fn logging() -> (Handle, Option) { .with_filter(log_file_filter); registry .with(file_layer) - .with(fmt::Subscriber::default().with_filter(console_filter_targets)) + .with( + fmt::Subscriber::default() + .with_line_number(true) + .with_target(true) + .with_filter(console_filter_targets), + ) .init(); } else { registry diff --git a/lapce-app/src/editor.rs b/lapce-app/src/editor.rs index aa1316a3fc..cd0cb3ac77 100644 --- a/lapce-app/src/editor.rs +++ b/lapce-app/src/editor.rs @@ -26,6 +26,7 @@ use floem::{ Editor, }, }; +use itertools::Itertools; use lapce_core::{ buffer::{ diff::DiffLines, @@ -46,7 +47,8 @@ use lapce_rpc::{buffer::BufferId, plugin::PluginId, proxy::ProxyResponse}; use lapce_xi_rope::{Rope, RopeDelta, Transformer}; use lsp_types::{ CompletionItem, CompletionTextEdit, GotoDefinitionResponse, HoverContents, - InlineCompletionTriggerKind, Location, MarkedString, MarkupKind, TextEdit, + InlayHint, InlayHintLabel, InlineCompletionTriggerKind, Location, MarkedString, + MarkupKind, TextEdit, }; use serde::{Deserialize, Serialize}; @@ -2389,20 +2391,41 @@ impl EditorData { self.active().set(true); self.left_click(pointer_event); - if cfg!(target_os = "macos") && pointer_event.modifiers.meta() { - self.common.lapce_command.send(LapceCommand { - kind: CommandKind::Focus(FocusCommand::GotoDefinition), - data: None, - }) - } - - if cfg!(not(target_os = "macos")) - && pointer_event.modifiers.control() + if (cfg!(target_os = "macos") && pointer_event.modifiers.meta()) + || (cfg!(not(target_os = "macos")) + && pointer_event.modifiers.control()) { - self.common.lapce_command.send(LapceCommand { - kind: CommandKind::Focus(FocusCommand::GotoDefinition), - data: None, - }) + let rs = self.find_hint(pointer_event.pos); + match rs { + FindHintRs::NoMatchBreak + | FindHintRs::NoMatchContinue { .. } => { + self.common.lapce_command.send(LapceCommand { + kind: CommandKind::Focus( + FocusCommand::GotoDefinition, + ), + data: None, + }) + } + FindHintRs::MatchWithoutLocation => {} + FindHintRs::Match(location) => { + let Ok(path) = location.uri.to_file_path() else { + return; + }; + self.common.internal_command.send( + InternalCommand::GoToLocation { + location: EditorLocation { + path, + position: Some(EditorPosition::Position( + location.range.start, + )), + scroll_offset: None, + ignore_unconfirmed: true, + same_editor_tab: false, + }, + }, + ); + } + } } } PointerButton::Secondary => { @@ -2412,6 +2435,40 @@ impl EditorData { } } + fn find_hint(&self, pos: Point) -> FindHintRs { + let rs = self.editor.line_col_of_point_with_phantom(pos); + let line = rs.0 as u32; + let index = rs.1 as u32; + self.doc().inlay_hints.with_untracked(|x| { + if let Some(hints) = x { + let mut pre_len = 0; + for hint in hints + .iter() + .filter_map(|(_, hint)| { + if hint.position.line == line { + Some(hint) + } else { + None + } + }) + .sorted_by(|pre, next| { + pre.position.character.cmp(&next.position.character) + }) + { + match find_hint(pre_len, index, hint) { + FindHintRs::NoMatchContinue { pre_hint_len } => { + pre_len = pre_hint_len; + } + rs => return rs, + } + } + FindHintRs::NoMatchBreak + } else { + FindHintRs::NoMatchBreak + } + }) + } + #[instrument] fn left_click(&self, pointer_event: &PointerInputEvent) { match pointer_event.count { @@ -3402,3 +3459,47 @@ fn parse_hover_resp( }, } } + +#[derive(Debug)] +enum FindHintRs { + NoMatchBreak, + NoMatchContinue { pre_hint_len: u32 }, + MatchWithoutLocation, + Match(Location), +} + +fn find_hint(mut pre_hint_len: u32, index: u32, hint: &InlayHint) -> FindHintRs { + use FindHintRs::*; + match &hint.label { + InlayHintLabel::String(text) => { + let actual_col = pre_hint_len + hint.position.character; + let actual_col_end = actual_col + (text.len() as u32); + if actual_col > index { + NoMatchBreak + } else if actual_col <= index && index < actual_col_end { + MatchWithoutLocation + } else { + pre_hint_len += text.len() as u32; + NoMatchContinue { pre_hint_len } + } + } + InlayHintLabel::LabelParts(parts) => { + for part in parts { + let actual_col = pre_hint_len + hint.position.character; + let actual_col_end = actual_col + part.value.len() as u32; + if index < actual_col { + return NoMatchBreak; + } else if actual_col <= index && index < actual_col_end { + if let Some(location) = &part.location { + return Match(location.clone()); + } else { + return MatchWithoutLocation; + } + } else { + pre_hint_len += part.value.len() as u32; + } + } + NoMatchContinue { pre_hint_len } + } + } +}