From cab5ddeac8239f3c59bbc8859d942e92f909967f Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Wed, 7 Aug 2024 23:07:24 +0100 Subject: [PATCH 01/69] relase 0.4.1 --- CHANGELOG.md | 6 ++++++ Cargo.lock | 12 ++++++------ Cargo.toml | 2 +- extra/linux/dev.lapce.lapce.metainfo.xml | 2 +- extra/macos/Lapce.app/Contents/Info.plist | 2 +- extra/windows/wix/lapce.wxs | 2 +- lapce.spec | 2 +- 7 files changed, 17 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e31fa27cad..dbfcb80544 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ ## Unreleased +### Features/Changes + +### Bug Fixes + +## 0.4.1 + ### Features/Changes - Add fedora builds - Finish tree sitter dynamic libary support by downloading from https://github.com/lapce/tree-sitter-grammars diff --git a/Cargo.lock b/Cargo.lock index f08869645e..8627ad1830 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2906,7 +2906,7 @@ dependencies = [ [[package]] name = "lapce" -version = "0.4.0" +version = "0.4.1" dependencies = [ "lapce-app", "lapce-proxy", @@ -2914,7 +2914,7 @@ dependencies = [ [[package]] name = "lapce-app" -version = "0.4.0" +version = "0.4.1" dependencies = [ "Inflector", "alacritty_terminal", @@ -2971,14 +2971,14 @@ dependencies = [ "tracing-subscriber", "unicode-width", "url", - "windows-sys 0.52.0", + "windows-sys 0.36.1", "zip", "zstd", ] [[package]] name = "lapce-core" -version = "0.4.0" +version = "0.4.1" dependencies = [ "ahash", "anyhow", @@ -3006,7 +3006,7 @@ dependencies = [ [[package]] name = "lapce-proxy" -version = "0.4.0" +version = "0.4.1" dependencies = [ "alacritty_terminal", "anyhow", @@ -3055,7 +3055,7 @@ dependencies = [ [[package]] name = "lapce-rpc" -version = "0.4.0" +version = "0.4.1" dependencies = [ "anyhow", "crossbeam-channel", diff --git a/Cargo.toml b/Cargo.toml index 658c97f93d..9e04e14786 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ path = "lapce-proxy/src/bin/lapce-proxy.rs" members = ["lapce-app", "lapce-proxy", "lapce-rpc", "lapce-core"] [workspace.package] -version = "0.4.0" +version = "0.4.1" edition = "2021" rust-version = "1.77.0" license = "Apache-2.0" diff --git a/extra/linux/dev.lapce.lapce.metainfo.xml b/extra/linux/dev.lapce.lapce.metainfo.xml index 99d322aff3..3c6ad2db59 100644 --- a/extra/linux/dev.lapce.lapce.metainfo.xml +++ b/extra/linux/dev.lapce.lapce.metainfo.xml @@ -30,6 +30,6 @@ - + diff --git a/extra/macos/Lapce.app/Contents/Info.plist b/extra/macos/Lapce.app/Contents/Info.plist index 2f6f78e208..5896e12833 100644 --- a/extra/macos/Lapce.app/Contents/Info.plist +++ b/extra/macos/Lapce.app/Contents/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.4.0 + 0.4.1 CFBundleSupportedPlatforms MacOSX diff --git a/extra/windows/wix/lapce.wxs b/extra/windows/wix/lapce.wxs index b2d0e4c600..305f835e22 100644 --- a/extra/windows/wix/lapce.wxs +++ b/extra/windows/wix/lapce.wxs @@ -1,6 +1,6 @@ - + diff --git a/lapce.spec b/lapce.spec index 0a6761d063..9996f3b8ca 100644 --- a/lapce.spec +++ b/lapce.spec @@ -1,5 +1,5 @@ Name: lapce-git -Version: 0.4.0.{{{ git_dir_version }}} +Version: 0.4.1.{{{ git_dir_version }}} Release: 1 Summary: Lightning-fast and Powerful Code Editor written in Rust License: Apache-2.0 From 36bebb6d159c6a12ba99df3c3d3682d83972ec52 Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Thu, 8 Aug 2024 19:02:28 +0100 Subject: [PATCH 02/69] add markup syntax color for markdown --- CHANGELOG.md | 1 + defaults/dark-theme.toml | 8 ++++++++ defaults/light-theme.toml | 8 ++++++++ lapce-core/src/language.rs | 4 ++-- lapce-core/src/style.rs | 8 ++++++++ 5 files changed, 27 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dbfcb80544..07da85bef1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Features/Changes ### Bug Fixes +- Fix markdown syntax highlighting ## 0.4.1 diff --git a/defaults/dark-theme.toml b/defaults/dark-theme.toml index 478d501a64..8d3c6ce0c4 100644 --- a/defaults/dark-theme.toml +++ b/defaults/dark-theme.toml @@ -68,6 +68,14 @@ dim-text = "#5C6370" "variable.other.member" = "$red" "tag" = "$blue" +"markup.heading" = "$red" +"markup.bold" = "$orange" +"markup.italic" = "$orange" +"markup.list" = "$orange" +"markup.link.url" = "$blue" +"markup.link.label" = "$purple" +"markup.link.text" = "$purple" + "bracket.color.1" = "$blue" "bracket.color.2" = "$yellow" "bracket.color.3" = "$purple" diff --git a/defaults/light-theme.toml b/defaults/light-theme.toml index 5cef4861b2..570e6f75b2 100644 --- a/defaults/light-theme.toml +++ b/defaults/light-theme.toml @@ -74,6 +74,14 @@ dim-text = "#A0A1A7" "variable.other.member" = "$red" "tag" = "$blue" +"markup.heading" = "$red" +"markup.bold" = "$orange" +"markup.italic" = "$orange" +"markup.list" = "$orange" +"markup.link.url" = "$blue" +"markup.link.label" = "$purple" +"markup.link.text" = "$purple" + "bracket.color.1" = "$blue" "bracket.color.2" = "$yellow" "bracket.color.3" = "$purple" diff --git a/lapce-core/src/language.rs b/lapce-core/src/language.rs index 53c9ae4991..15c1535a7c 100644 --- a/lapce-core/src/language.rs +++ b/lapce-core/src/language.rs @@ -1169,8 +1169,8 @@ const LANGUAGES: &[SyntaxProperties] = &[ extensions: &[], comment: comment_properties!(), tree_sitter: TreeSitterProperties { - grammar: Some("markdown"), - grammar_fn: None, + grammar: Some("markdown_inline"), + grammar_fn: Some("markdown_inline"), query: Some("markdown.inline"), code_glance: (DEFAULT_CODE_GLANCE_LIST, DEFAULT_CODE_GLANCE_IGNORE_LIST), sticky_headers: &[], diff --git a/lapce-core/src/style.rs b/lapce-core/src/style.rs index fed6642423..9f6a5cd211 100644 --- a/lapce-core/src/style.rs +++ b/lapce-core/src/style.rs @@ -33,6 +33,14 @@ pub const SCOPES: &[&str] = &[ "conceal", "none", "tag", + "markup.bold", + "markup.italic", + "markup.list", + "markup.quote", + "markup.heading", + "markup.link.url", + "markup.link.label", + "markup.link.text", ]; pub fn line_styles( From 7c3405c147f18a29f944f51ae00ed9b24b5c1859 Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Thu, 8 Aug 2024 19:22:09 +0100 Subject: [PATCH 03/69] just language configurations --- lapce-core/src/language.rs | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/lapce-core/src/language.rs b/lapce-core/src/language.rs index 15c1535a7c..292f66d9ee 100644 --- a/lapce-core/src/language.rs +++ b/lapce-core/src/language.rs @@ -713,7 +713,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ SyntaxProperties { id: LapceLanguage::Dockerfile, indent: Indent::space(2), - files: &["dockerfile", "containerfile"], + files: &["Dockerfile", "Containerfile"], extensions: &["containerfile", "dockerfile"], comment: comment_properties!("#"), tree_sitter: TreeSitterProperties::DEFAULT, @@ -1069,8 +1069,8 @@ const LANGUAGES: &[SyntaxProperties] = &[ SyntaxProperties { id: LapceLanguage::Just, indent: Indent::tab(), - files: &[], - extensions: &[], + files: &["justfile", "Justfile", ".justfile", ".Justfile"], + extensions: &["just"], comment: comment_properties!(), tree_sitter: TreeSitterProperties::DEFAULT, }, @@ -1567,7 +1567,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ SyntaxProperties { id: LapceLanguage::Toml, indent: Indent::space(2), - files: &[], + files: &["Cargo.lock"], extensions: &["toml"], comment: comment_properties!("#"), tree_sitter: TreeSitterProperties::DEFAULT, @@ -1683,20 +1683,14 @@ impl LapceLanguage { } pub fn from_path_raw(path: &Path) -> Option { - let filename = path - .file_stem() - .and_then(|s| s.to_str().map(|s| s.to_lowercase())); + let filename = path.file_name().and_then(|s| s.to_str()); let extension = path .extension() .and_then(|s| s.to_str().map(|s| s.to_lowercase())); // NOTE: This is a linear search. It is assumed that this function // isn't called in any tight loop. for properties in LANGUAGES { - if properties - .files - .iter() - .any(|f| Some(*f) == filename.as_deref()) - { + if properties.files.iter().any(|f| Some(*f) == filename) { return Some(properties.id); } if properties From e45e292bf007c67684e389483e6e139a35f8cdf4 Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Fri, 9 Aug 2024 21:58:41 +0800 Subject: [PATCH 04/69] Avoid overflow. (#3420) --- lapce-app/src/editor.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lapce-app/src/editor.rs b/lapce-app/src/editor.rs index bf7655523e..499f4b893a 100644 --- a/lapce-app/src/editor.rs +++ b/lapce-app/src/editor.rs @@ -3292,7 +3292,7 @@ pub(crate) fn compute_screen_lines( let is_right = diff_info.is_right; let line_y = |info: VLineInfo<()>, vline_y: usize| -> usize { - vline_y - info.rvline.line_index * line_height + vline_y.saturating_sub(info.rvline.line_index * line_height) }; while let Some(change) = changes.next() { From 08222a7d6f16466135aa57d89f1d0c590efe0a3b Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Fri, 9 Aug 2024 23:25:25 +0800 Subject: [PATCH 05/69] Implement feature "Run in Terminal" (#3419) * Implement feature "Run in Terminal" * call other method to get select text --- lapce-app/src/command.rs | 4 ++++ lapce-app/src/editor.rs | 1 + lapce-app/src/window_tab.rs | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/lapce-app/src/command.rs b/lapce-app/src/command.rs index 1ea715861c..014e5d7e15 100644 --- a/lapce-app/src/command.rs +++ b/lapce-app/src/command.rs @@ -191,6 +191,10 @@ pub enum LapceWorkbenchCommand { #[strum(message = "Reveal in File Tree")] RevealInFileTree, + #[strum(serialize = "run_in_terminal")] + #[strum(message = "Run in Terminal")] + RunInTerminal, + #[strum(serialize = "reveal_active_file_in_file_explorer")] #[strum(message = "Reveal Active File in File Explorer")] RevealActiveFileInFileExplorer, diff --git a/lapce-app/src/editor.rs b/lapce-app/src/editor.rs index 499f4b893a..7739f82420 100644 --- a/lapce-app/src/editor.rs +++ b/lapce-app/src/editor.rs @@ -2660,6 +2660,7 @@ impl EditorData { Some(CommandKind::Workbench( LapceWorkbenchCommand::PaletteCommand, )), + Some(CommandKind::Workbench(LapceWorkbenchCommand::RunInTerminal)), ] } else { vec![ diff --git a/lapce-app/src/window_tab.rs b/lapce-app/src/window_tab.rs index ed487a9542..61de7ac45e 100644 --- a/lapce-app/src/window_tab.rs +++ b/lapce-app/src/window_tab.rs @@ -1394,6 +1394,38 @@ impl WindowTabData { editor_data.call_hierarchy(self.clone()); } } + RunInTerminal => { + if let Some(editor_data) = + self.main_split.active_editor.get_untracked() + { + let name = editor_data.word_at_cursor(); + if !name.is_empty() { + let mut args_str = name.split(" "); + let program = args_str.next().map(|x| x.to_string()).unwrap(); + let args: Vec = args_str.into_iter().map(|x| x.to_string()).collect(); + let args = if args.is_empty() { + None + } else { + Some(args) + }; + + let config = RunDebugConfig { + ty: None, + name, + program, + args, + cwd: None, + env: None, + prelaunch: None, + debug_command: None, + dap_id: Default::default(), + }; + self.common + .internal_command + .send(InternalCommand::RunAndDebug { mode: RunDebugMode::Run, config }); + } + } + } } } From 48d09de95834b702359004af8a305866c9bc3074 Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Fri, 9 Aug 2024 20:12:32 +0100 Subject: [PATCH 06/69] Fix pointer down on window message --- lapce-app/src/app.rs | 12 +++++++++--- lapce-app/src/editor.rs | 8 ++++---- lapce-app/src/markdown.rs | 4 ++-- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/lapce-app/src/app.rs b/lapce-app/src/app.rs index 36a04eb11d..4008fed604 100644 --- a/lapce-app/src/app.rs +++ b/lapce-app/src/app.rs @@ -2795,10 +2795,10 @@ fn window_message_view( }), stack(( text(title.clone()).style(|s| { - s.min_width(0.0).line_height(1.6).font_weight(Weight::BOLD) + s.min_width(0.0).line_height(1.8).font_weight(Weight::BOLD) }), text(message.message.clone()).style(|s| { - s.min_width(0.0).line_height(1.6).margin_top(5.0) + s.min_width(0.0).line_height(1.8).margin_top(5.0) }), )) .style(move |s| { @@ -2818,6 +2818,7 @@ fn window_message_view( ) .style(|s| s.margin_left(6.0)), )) + .on_event_stop(EventListener::PointerDown, |_| {}) .style(move |s| { let config = config.get(); s.width_full() @@ -2846,7 +2847,11 @@ fn window_message_view( .style(|s| s.flex_col().width_full()), ) .style(|s| { - s.absolute().width_full().min_height(0.0).max_height_full() + s.absolute() + .width_full() + .min_height(0.0) + .max_height_full() + .set(PropagatePointerWheel, false) }), ) .style(|s| s.size_full()), @@ -2930,6 +2935,7 @@ fn hover(window_tab_data: Rc) -> impl View { layout_rect.set(rect); }) .on_event_stop(EventListener::PointerMove, |_| {}) + .on_event_stop(EventListener::PointerDown, |_| {}) .style(move |s| { let active = window_tab_data.common.hover.active.get(); if !active { diff --git a/lapce-app/src/editor.rs b/lapce-app/src/editor.rs index 7739f82420..a4826d491d 100644 --- a/lapce-app/src/editor.rs +++ b/lapce-app/src/editor.rs @@ -3502,10 +3502,10 @@ fn parse_hover_resp( ) -> Vec { match hover.contents { HoverContents::Scalar(text) => match text { - MarkedString::String(text) => parse_markdown(&text, 1.5, config), + MarkedString::String(text) => parse_markdown(&text, 1.8, config), MarkedString::LanguageString(code) => parse_markdown( &format!("```{}\n{}\n```", code.language, code.value), - 1.5, + 1.8, config, ), }, @@ -3520,8 +3520,8 @@ fn parse_hover_resp( }) .unwrap_or_default(), HoverContents::Markup(content) => match content.kind { - MarkupKind::PlainText => from_plaintext(&content.value, 1.5, config), - MarkupKind::Markdown => parse_markdown(&content.value, 1.5, config), + MarkupKind::PlainText => from_plaintext(&content.value, 1.8, config), + MarkupKind::Markdown => parse_markdown(&content.value, 1.8, config), }, } } diff --git a/lapce-app/src/markdown.rs b/lapce-app/src/markdown.rs index f9e384365a..623c310464 100644 --- a/lapce-app/src/markdown.rs +++ b/lapce-app/src/markdown.rs @@ -310,14 +310,14 @@ pub fn from_marked_string( config: &LapceConfig, ) -> Vec { match text { - MarkedString::String(text) => parse_markdown(&text, 1.5, config), + MarkedString::String(text) => parse_markdown(&text, 1.8, config), // This is a short version of a code block MarkedString::LanguageString(code) => { // TODO: We could simply construct the MarkdownText directly // Simply construct the string as if it was written directly parse_markdown( &format!("```{}\n{}\n```", code.language, code.value), - 1.5, + 1.8, config, ) } From be4b2686cb5ed1f77e1a1e765c1c961885bc9c9c Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Fri, 9 Aug 2024 20:13:18 +0100 Subject: [PATCH 07/69] update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 07da85bef1..a55d3a7e1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,9 +3,11 @@ ## Unreleased ### Features/Changes +- Implement "Run in terminal" ### Bug Fixes - Fix markdown syntax highlighting +- Fix click issue on window error message ## 0.4.1 From 8d63ee769bb13f0404aaf05638c91a8e94e481ef Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Fri, 9 Aug 2024 21:49:49 +0100 Subject: [PATCH 08/69] implement on screen find --- Cargo.lock | 12 +-- Cargo.toml | 4 +- lapce-app/src/editor.rs | 99 ++++++++++++++++++ lapce-app/src/editor/view.rs | 153 +++++++++++++++++----------- lapce-app/src/keypress/condition.rs | 2 + lapce-app/src/palette.rs | 8 +- lapce-app/src/window_tab.rs | 2 +- 7 files changed, 207 insertions(+), 73 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8627ad1830..7bdabad25a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1684,7 +1684,7 @@ checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" [[package]] name = "floem" version = "0.1.1" -source = "git+https://github.com/lapce/floem?rev=54f0d1bcf0e1a91d82492ee7300a526adb60eb5c#54f0d1bcf0e1a91d82492ee7300a526adb60eb5c" +source = "git+https://github.com/lapce/floem?rev=a207ef4bd463d41be1d06daeae3be7936b0dbb60#a207ef4bd463d41be1d06daeae3be7936b0dbb60" dependencies = [ "bitflags 2.6.0", "copypasta", @@ -1722,7 +1722,7 @@ dependencies = [ [[package]] name = "floem-editor-core" version = "0.1.1" -source = "git+https://github.com/lapce/floem?rev=54f0d1bcf0e1a91d82492ee7300a526adb60eb5c#54f0d1bcf0e1a91d82492ee7300a526adb60eb5c" +source = "git+https://github.com/lapce/floem?rev=a207ef4bd463d41be1d06daeae3be7936b0dbb60#a207ef4bd463d41be1d06daeae3be7936b0dbb60" dependencies = [ "bitflags 2.6.0", "itertools 0.12.1", @@ -1800,7 +1800,7 @@ dependencies = [ [[package]] name = "floem_reactive" version = "0.1.1" -source = "git+https://github.com/lapce/floem?rev=54f0d1bcf0e1a91d82492ee7300a526adb60eb5c#54f0d1bcf0e1a91d82492ee7300a526adb60eb5c" +source = "git+https://github.com/lapce/floem?rev=a207ef4bd463d41be1d06daeae3be7936b0dbb60#a207ef4bd463d41be1d06daeae3be7936b0dbb60" dependencies = [ "smallvec", ] @@ -1808,7 +1808,7 @@ dependencies = [ [[package]] name = "floem_renderer" version = "0.1.1" -source = "git+https://github.com/lapce/floem?rev=54f0d1bcf0e1a91d82492ee7300a526adb60eb5c#54f0d1bcf0e1a91d82492ee7300a526adb60eb5c" +source = "git+https://github.com/lapce/floem?rev=a207ef4bd463d41be1d06daeae3be7936b0dbb60#a207ef4bd463d41be1d06daeae3be7936b0dbb60" dependencies = [ "cosmic-text", "image", @@ -1821,7 +1821,7 @@ dependencies = [ [[package]] name = "floem_tiny_skia_renderer" version = "0.1.1" -source = "git+https://github.com/lapce/floem?rev=54f0d1bcf0e1a91d82492ee7300a526adb60eb5c#54f0d1bcf0e1a91d82492ee7300a526adb60eb5c" +source = "git+https://github.com/lapce/floem?rev=a207ef4bd463d41be1d06daeae3be7936b0dbb60#a207ef4bd463d41be1d06daeae3be7936b0dbb60" dependencies = [ "anyhow", "bytemuck", @@ -1838,7 +1838,7 @@ dependencies = [ [[package]] name = "floem_vger_renderer" version = "0.1.1" -source = "git+https://github.com/lapce/floem?rev=54f0d1bcf0e1a91d82492ee7300a526adb60eb5c#54f0d1bcf0e1a91d82492ee7300a526adb60eb5c" +source = "git+https://github.com/lapce/floem?rev=a207ef4bd463d41be1d06daeae3be7936b0dbb60#a207ef4bd463d41be1d06daeae3be7936b0dbb60" dependencies = [ "anyhow", "floem-vger", diff --git a/Cargo.toml b/Cargo.toml index 9e04e14786..694595a460 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -76,9 +76,9 @@ lapce-core = { path = "./lapce-core" } lapce-rpc = { path = "./lapce-rpc" } lapce-proxy = { path = "./lapce-proxy" } -floem = { git = "https://github.com/lapce/floem", rev = "54f0d1bcf0e1a91d82492ee7300a526adb60eb5c", features = ["editor", "serde", "default-image-formats", "rfd-async-std"] } +floem = { git = "https://github.com/lapce/floem", rev = "a207ef4bd463d41be1d06daeae3be7936b0dbb60", 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 = "54f0d1bcf0e1a91d82492ee7300a526adb60eb5c", features = ["serde"] } +floem-editor-core = { git = "https://github.com/lapce/floem", rev = "a207ef4bd463d41be1d06daeae3be7936b0dbb60", features = ["serde"] } # floem-editor-core = { path = "../floem/editor-core/", features = ["serde"] } [patch.crates-io] diff --git a/lapce-app/src/editor.rs b/lapce-app/src/editor.rs index a4826d491d..012c0aa5c3 100644 --- a/lapce-app/src/editor.rs +++ b/lapce-app/src/editor.rs @@ -51,6 +51,7 @@ use lsp_types::{ HoverContents, InlayHint, InlayHintLabel, InlineCompletionTriggerKind, Location, MarkedString, MarkupKind, Range, TextEdit, }; +use nucleo::Utf32Str; use serde::{Deserialize, Serialize}; use self::{ @@ -187,6 +188,13 @@ impl EditorViewKind { } } +#[derive(Clone)] +pub struct OnScreenFind { + pub active: bool, + pub pattern: String, + pub regions: Vec, +} + pub type SnippetIndex = Vec<(usize, (usize, usize))>; /// Shares data between cloned instances as long as the signals aren't swapped out. @@ -198,6 +206,7 @@ pub struct EditorData { pub confirmed: RwSignal, pub snippet: RwSignal>, pub inline_find: RwSignal>, + pub on_screen_find: RwSignal, pub last_inline_find: RwSignal>, pub find_focus: RwSignal, pub editor: Rc, @@ -231,6 +240,11 @@ impl EditorData { confirmed, snippet: cx.create_rw_signal(None), inline_find: cx.create_rw_signal(None), + on_screen_find: cx.create_rw_signal(OnScreenFind { + active: false, + pattern: "".to_string(), + regions: Vec::new(), + }), last_inline_find: cx.create_rw_signal(None), find_focus: cx.create_rw_signal(false), editor: Rc::new(editor), @@ -435,6 +449,7 @@ impl EditorData { // Cancel so that there's no flickering self.cancel_inline_completion(); self.update_inline_completion(InlineCompletionTriggerKind::Automatic); + self.quit_on_screen_find(); } else if show_inline_completion(cmd) { self.update_inline_completion(InlineCompletionTriggerKind::Automatic); } else { @@ -444,6 +459,7 @@ impl EditorData { self.apply_deltas(&deltas); if let EditCommand::NormalMode = cmd { self.snippet.set(None); + self.quit_on_screen_find(); } CommandExecuted::Yes @@ -1028,6 +1044,13 @@ impl EditorData { FocusCommand::InlineFindRight => { self.inline_find.set(Some(InlineFindDirection::Right)); } + FocusCommand::OnScreenFind => { + self.on_screen_find.update(|find| { + find.active = true; + find.pattern.clear(); + find.regions.clear(); + }); + } FocusCommand::RepeatLastInlineFind => { if let Some((direction, c)) = self.last_inline_find.get_untracked() { self.inline_find(direction, &c); @@ -1130,6 +1153,72 @@ impl EditorData { } } + fn quit_on_screen_find(&self) { + if self.on_screen_find.with_untracked(|s| s.active) { + self.on_screen_find.update(|f| { + f.active = false; + f.pattern.clear(); + f.regions.clear(); + }) + } + } + + fn on_screen_find(&self, pattern: &str) -> Vec { + let screen_lines = self.screen_lines().get_untracked(); + let lines: HashSet = + screen_lines.lines.iter().map(|l| l.line).collect(); + + let mut matcher = nucleo::Matcher::new(nucleo::Config::DEFAULT); + let pattern = nucleo::pattern::Pattern::parse( + pattern, + nucleo::pattern::CaseMatching::Ignore, + nucleo::pattern::Normalization::Smart, + ); + let mut indices = Vec::new(); + let mut filter_text_buf = Vec::new(); + let mut items = Vec::new(); + + let buffer = self.doc().buffer; + + for line in lines { + filter_text_buf.clear(); + indices.clear(); + + buffer.with_untracked(|buffer| { + let start = buffer.offset_of_line(line); + let end = buffer.offset_of_line(line + 1); + let text = buffer.text().slice_to_cow(start..end); + let filter_text = Utf32Str::new(&text, &mut filter_text_buf); + + if let Some(score) = + pattern.indices(filter_text, &mut matcher, &mut indices) + { + indices.sort(); + let left = + start + indices.first().copied().unwrap_or(0) as usize; + let right = + start + indices.last().copied().unwrap_or(0) as usize + 1; + let right = if right == left { left + 1 } else { right }; + items.push((score, left, right)); + } + }); + } + + items.sort_by_key(|(score, _, _)| -(*score as i64)); + if let Some((_, offset, _)) = items.first().copied() { + self.run_move_command( + &lapce_core::movement::Movement::Offset(offset), + None, + Modifiers::empty(), + ); + } + + items + .into_iter() + .map(|(_, start, end)| SelRegion::new(start, end, None)) + .collect() + } + fn go_to_definition(&self) { let doc = self.doc(); let path = match if doc.loaded() { @@ -2947,6 +3036,9 @@ impl KeyPressFocus for EditorData { Condition::ListFocus => self.has_completions(), Condition::CompletionFocus => self.has_completions(), Condition::InlineCompletionVisible => self.has_inline_completions(), + Condition::OnScreenFindActive => { + self.on_screen_find.with_untracked(|f| f.active) + } Condition::InSnippet => self.snippet.with_untracked(|s| s.is_some()), Condition::EditorFocus => self .doc() @@ -3053,6 +3145,7 @@ impl KeyPressFocus for EditorData { false } else { self.inline_find.with_untracked(|f| f.is_some()) + || self.on_screen_find.with_untracked(|f| f.active) } } @@ -3098,6 +3191,12 @@ impl KeyPressFocus for EditorData { self.inline_find(direction.clone(), c); self.last_inline_find.set(Some((direction, c.to_string()))); self.inline_find.set(None); + } else if self.on_screen_find.with_untracked(|f| f.active) { + self.on_screen_find.update(|find| { + let pattern = format!("{}{c}", find.pattern); + find.regions = self.on_screen_find(&pattern); + find.pattern = pattern; + }); } } } diff --git a/lapce-app/src/editor/view.rs b/lapce-app/src/editor/view.rs index df80fc1478..0f249822a2 100644 --- a/lapce-app/src/editor/view.rs +++ b/lapce-app/src/editor/view.rs @@ -39,6 +39,7 @@ use itertools::Itertools; use lapce_core::{ buffer::{diff::DiffLines, rope_text::RopeText, Buffer}, cursor::{CursorAffinity, CursorMode}, + selection::SelRegion, }; use lapce_rpc::{ dap_types::{DapId, SourceBreakpoint}, @@ -477,8 +478,8 @@ impl EditorView { } fn paint_find(&self, cx: &mut PaintCx, screen_lines: &ScreenLines) { - let visual = self.editor.common.find.visual; - if !visual.get_untracked() { + let find_visual = self.editor.common.find.visual.get_untracked(); + if !find_visual && self.editor.on_screen_find.with_untracked(|f| !f.active) { return; } if screen_lines.lines.is_empty() { @@ -499,78 +500,108 @@ impl EditorView { let config = config.get_untracked(); let line_height = config.editor.line_height() as f64; + let color = config.color(LapceColor::EDITOR_FOREGROUND); - doc.update_find(); let start = ed.offset_of_line(min_line); let end = ed.offset_of_line(max_line + 1); // TODO: The selection rect creation logic for find is quite similar to the version // within insert cursor. It would be good to deduplicate it. - let mut rects = Vec::new(); - for region in occurrences.with_untracked(|selection| { - selection.regions_in_range(start, end).to_vec() - }) { - let start = region.min(); - let end = region.max(); - - // TODO(minor): the proper affinity here should probably be tracked by selregion - let (start_rvline, start_col) = - ed.rvline_col_of_offset(start, CursorAffinity::Forward); - let (end_rvline, end_col) = - ed.rvline_col_of_offset(end, CursorAffinity::Backward); - - for line_info in screen_lines.iter_line_info() { - let rvline_info = line_info.vline_info; - let rvline = rvline_info.rvline; - let line = rvline.line; - - if rvline < start_rvline { - continue; - } + if find_visual { + doc.update_find(); + for region in occurrences.with_untracked(|selection| { + selection.regions_in_range(start, end).to_vec() + }) { + self.paint_find_region( + cx, + ed, + ®ion, + color, + screen_lines, + line_height, + ); + } + } - if rvline > end_rvline { - break; + self.editor.on_screen_find.with_untracked(|find| { + if find.active { + for region in &find.regions { + self.paint_find_region( + cx, + ed, + region, + color, + screen_lines, + line_height, + ); } + } + }); + } - let left_col = if rvline == start_rvline { start_col } else { 0 }; - let (right_col, _vline_end) = if rvline == end_rvline { - let max_col = ed.last_col(rvline_info, true); - (end_col.min(max_col), false) - } else { - (ed.last_col(rvline_info, true), true) - }; + fn paint_find_region( + &self, + cx: &mut PaintCx, + ed: &Editor, + region: &SelRegion, + color: Color, + screen_lines: &ScreenLines, + line_height: f64, + ) { + let start = region.min(); + let end = region.max(); - // TODO(minor): sel region should have the affinity of the start/end - let x0 = ed - .line_point_of_line_col( - line, - left_col, - CursorAffinity::Forward, - true, - ) - .x; - let x1 = ed - .line_point_of_line_col( - line, - right_col, - CursorAffinity::Backward, - true, - ) - .x; + // TODO(minor): the proper affinity here should probably be tracked by selregion + let (start_rvline, start_col) = + ed.rvline_col_of_offset(start, CursorAffinity::Forward); + let (end_rvline, end_col) = + ed.rvline_col_of_offset(end, CursorAffinity::Backward); - if !rvline_info.is_empty() && start != end && left_col != right_col { - rects.push( - Size::new(x1 - x0, line_height) - .to_rect() - .with_origin(Point::new(x0, line_info.vline_y)), - ); - } + for line_info in screen_lines.iter_line_info() { + let rvline_info = line_info.vline_info; + let rvline = rvline_info.rvline; + let line = rvline.line; + + if rvline < start_rvline { + continue; } - } - let color = config.color(LapceColor::EDITOR_FOREGROUND); - for rect in rects { - cx.stroke(&rect, color, 1.0); + if rvline > end_rvline { + break; + } + + let left_col = if rvline == start_rvline { start_col } else { 0 }; + let (right_col, _vline_end) = if rvline == end_rvline { + let max_col = ed.last_col(rvline_info, true); + (end_col.min(max_col), false) + } else { + (ed.last_col(rvline_info, true), true) + }; + + // TODO(minor): sel region should have the affinity of the start/end + let x0 = ed + .line_point_of_line_col( + line, + left_col, + CursorAffinity::Forward, + true, + ) + .x; + let x1 = ed + .line_point_of_line_col( + line, + right_col, + CursorAffinity::Backward, + true, + ) + .x; + + if !rvline_info.is_empty() && start != end && left_col != right_col { + let rect = Size::new(x1 - x0, line_height) + .to_rect() + .with_origin(Point::new(x0, line_info.vline_y)); + cx.stroke(&rect, color, 1.0); + } } } diff --git a/lapce-app/src/keypress/condition.rs b/lapce-app/src/keypress/condition.rs index 3d6e61c56c..cb2d23cf74 100644 --- a/lapce-app/src/keypress/condition.rs +++ b/lapce-app/src/keypress/condition.rs @@ -65,6 +65,8 @@ pub enum Condition { RenameFocus, #[strum(serialize = "search_active")] SearchActive, + #[strum(serialize = "on_screen_find_active")] + OnScreenFindActive, #[strum(serialize = "search_focus")] SearchFocus, #[strum(serialize = "replace_focus")] diff --git a/lapce-app/src/palette.rs b/lapce-app/src/palette.rs index 8c97c677be..4b84eeef5c 100644 --- a/lapce-app/src/palette.rs +++ b/lapce-app/src/palette.rs @@ -1506,6 +1506,8 @@ impl PaletteData { // NOTE: We collect into a Vec to sort as we are hitting a worst-case behavior in // `im::Vector` that can lead to a stack overflow! let mut filtered_items = Vec::new(); + let mut indices = Vec::new(); + let mut filter_text_buf = Vec::new(); for i in &items { // If the run id has ever changed, then we'll just bail out of this filtering to avoid // wasting effort. This would happen, for example, on the user continuing to type. @@ -1513,14 +1515,14 @@ impl PaletteData { return None; } - let mut indices = Vec::new(); - let mut filter_text_buf = Vec::new(); + indices.clear(); + filter_text_buf.clear(); let filter_text = Utf32Str::new(&i.filter_text, &mut filter_text_buf); if let Some(score) = pattern.indices(filter_text, matcher, &mut indices) { let mut item = i.clone(); item.score = score; - item.indices = indices.into_iter().map(|i| i as usize).collect(); + item.indices = indices.iter().map(|i| *i as usize).collect(); filtered_items.push(item); } } diff --git a/lapce-app/src/window_tab.rs b/lapce-app/src/window_tab.rs index 61de7ac45e..716e16c3b6 100644 --- a/lapce-app/src/window_tab.rs +++ b/lapce-app/src/window_tab.rs @@ -1402,7 +1402,7 @@ impl WindowTabData { if !name.is_empty() { let mut args_str = name.split(" "); let program = args_str.next().map(|x| x.to_string()).unwrap(); - let args: Vec = args_str.into_iter().map(|x| x.to_string()).collect(); + let args: Vec = args_str.map(|x| x.to_string()).collect(); let args = if args.is_empty() { None } else { From 082f63ec82242e202d9738f6c946f72e8985a8ce Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Tue, 13 Aug 2024 04:43:51 +0800 Subject: [PATCH 09/69] Filter out code-len without commands. (#3427) --- lapce-app/src/doc.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lapce-app/src/doc.rs b/lapce-app/src/doc.rs index cd64958b1c..2beaa19987 100644 --- a/lapce-app/src/doc.rs +++ b/lapce-app/src/doc.rs @@ -880,6 +880,9 @@ impl Doc { }; doc.code_lens.update(|code_lens| { for codelens in codelens { + if codelens.command.is_none() { + continue; + } let entry = code_lens .entry(codelens.range.start.line as usize) .or_insert_with(|| { From bb3709dfabe05739c4a4a6db094564a3d7fa4441 Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Tue, 13 Aug 2024 04:45:20 +0800 Subject: [PATCH 10/69] Implement 'Go To Location' functionality in the Diff editor. (#3426) --- lapce-app/src/command.rs | 4 ++++ lapce-app/src/editor.rs | 7 ++++++- lapce-app/src/window_tab.rs | 27 +++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/lapce-app/src/command.rs b/lapce-app/src/command.rs index 014e5d7e15..aad6553df2 100644 --- a/lapce-app/src/command.rs +++ b/lapce-app/src/command.rs @@ -566,6 +566,10 @@ pub enum LapceWorkbenchCommand { #[strum(serialize = "quit")] #[strum(message = "Quit Editor")] Quit, + + #[strum(serialize = "go_to_location")] + #[strum(message = "Go to Location")] + GoToLocation, } #[derive(Clone, Debug)] diff --git a/lapce-app/src/editor.rs b/lapce-app/src/editor.rs index 012c0aa5c3..9dedc66b32 100644 --- a/lapce-app/src/editor.rs +++ b/lapce-app/src/editor.rs @@ -2729,7 +2729,7 @@ impl EditorData { let is_file = doc.content.with_untracked(|content| content.is_file()); let mut menu = Menu::new(""); - let cmds = if is_file { + let mut cmds = if is_file { vec![ Some(CommandKind::Focus(FocusCommand::GotoDefinition)), Some(CommandKind::Focus(FocusCommand::GotoTypeDefinition)), @@ -2762,6 +2762,11 @@ impl EditorData { )), ] }; + if self.diff_editor_id.get_untracked().is_some() && is_file { + cmds.push(Some(CommandKind::Workbench( + LapceWorkbenchCommand::GoToLocation, + ))); + } let lapce_command = self.common.lapce_command; for cmd in cmds { if let Some(cmd) = cmd { diff --git a/lapce-app/src/window_tab.rs b/lapce-app/src/window_tab.rs index 716e16c3b6..c5542ebbdf 100644 --- a/lapce-app/src/window_tab.rs +++ b/lapce-app/src/window_tab.rs @@ -1426,6 +1426,33 @@ impl WindowTabData { } } } + GoToLocation => { + if let Some(editor_data) = + self.main_split.active_editor.get_untracked() + { + let doc = editor_data.doc(); + let path = match if doc.loaded() { + doc.content.with_untracked(|c| c.path().cloned()) + } else { + None + } { + Some(path) => path, + None => return, + }; + let offset = editor_data.cursor().with_untracked(|c| c.offset()); + let internal_command = self.common.internal_command; + + internal_command.send(InternalCommand::MakeConfirmed); + internal_command.send(InternalCommand::GoToLocation { location: EditorLocation { + path, + position: Some(EditorPosition::Offset(offset)), + scroll_offset: None, + ignore_unconfirmed: false, + same_editor_tab: false, + } }); + } + } + } } From 0bbb901a3bf09dfdb36a7c6f849339cad8019883 Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Tue, 13 Aug 2024 04:48:12 +0800 Subject: [PATCH 11/69] implement document symbol (#3425) --- lapce-app/src/doc.rs | 58 +++- lapce-app/src/main_split.rs | 15 ++ lapce-app/src/panel/call_hierarchy_view.rs | 3 +- lapce-app/src/panel/data.rs | 4 + lapce-app/src/panel/document_symbol.rs | 299 +++++++++++++++++++++ lapce-app/src/panel/kind.rs | 2 + lapce-app/src/panel/mod.rs | 1 + lapce-app/src/panel/view.rs | 8 +- lapce-app/src/window_tab.rs | 6 +- lapce-proxy/src/plugin/mod.rs | 12 +- lapce-proxy/src/terminal.rs | 2 +- 11 files changed, 397 insertions(+), 13 deletions(-) create mode 100644 lapce-app/src/panel/document_symbol.rs diff --git a/lapce-app/src/doc.rs b/lapce-app/src/doc.rs index 2beaa19987..50e1195add 100644 --- a/lapce-app/src/doc.rs +++ b/lapce-app/src/doc.rs @@ -64,8 +64,8 @@ use lapce_xi_rope::{ Interval, Rope, RopeDelta, Transformer, }; use lsp_types::{ - CodeActionOrCommand, CodeLens, Diagnostic, DiagnosticSeverity, InlayHint, - InlayHintLabel, + CodeActionOrCommand, CodeLens, Diagnostic, DiagnosticSeverity, + DocumentSymbolResponse, InlayHint, InlayHintLabel, }; use serde::{Deserialize, Serialize}; use smallvec::SmallVec; @@ -78,7 +78,10 @@ use crate::{ history::DocumentHistory, keypress::KeyPressFocus, main_split::Editors, - panel::kind::PanelKind, + panel::{ + document_symbol::{SymbolData, SymbolInformationItemData}, + kind::PanelKind, + }, window_tab::{CommonData, Focus}, workspace::LapceWorkspace, }; @@ -205,6 +208,8 @@ pub struct Doc { editors: Editors, pub common: Rc, + + pub document_symbol_data: RwSignal>, } impl Doc { pub fn new( @@ -249,6 +254,7 @@ impl Doc { editors, common, code_lens: cx.create_rw_signal(im::HashMap::new()), + document_symbol_data: cx.create_rw_signal(None), } } @@ -298,6 +304,7 @@ impl Doc { editors, common, code_lens: cx.create_rw_signal(im::HashMap::new()), + document_symbol_data: cx.create_rw_signal(None), } } @@ -347,6 +354,7 @@ impl Doc { editors, common, code_lens: cx.create_rw_signal(im::HashMap::new()), + document_symbol_data: cx.create_rw_signal(None), } } @@ -640,6 +648,7 @@ impl Doc { self.clear_code_actions(); self.clear_style_cache(); self.get_code_lens(); + self.get_document_symbol(); }); } @@ -907,6 +916,49 @@ impl Doc { } } + pub fn get_document_symbol(&self) { + let cx = self.scope; + let doc = self.clone(); + self.document_symbol_data.update(|symbol| { + symbol.take(); + }); + let rev = self.rev(); + if let DocContent::File { path, .. } = doc.content.get_untracked() { + let send = create_ext_action(cx, { + let path = path.clone(); + move |result| { + if rev != doc.rev() { + return; + } + if let Ok(ProxyResponse::GetDocumentSymbols { resp }) = result { + let items: Vec> = + match resp { + DocumentSymbolResponse::Flat(_symbols) => { + Vec::with_capacity(0) + } + DocumentSymbolResponse::Nested(symbols) => symbols + .into_iter() + .map(|x| { + cx.create_rw_signal( + SymbolInformationItemData::from((x, cx)), + ) + }) + .collect(), + }; + let symbol_new = Some(SymbolData { items, path }); + doc.document_symbol_data.update(|symbol| { + *symbol = symbol_new; + }); + } + } + }); + + self.common.proxy.get_document_symbols(path, move |result| { + send(result); + }); + } + } + /// Request inlay hints for the buffer from the LSP through the proxy. fn get_inlay_hints(&self) { if !self.loaded() { diff --git a/lapce-app/src/main_split.rs b/lapce-app/src/main_split.rs index 01f696bc11..11c8e79a7b 100644 --- a/lapce-app/src/main_split.rs +++ b/lapce-app/src/main_split.rs @@ -640,6 +640,7 @@ impl MainSplitData { }); } doc.get_code_lens(); + doc.get_document_symbol(); (doc, true) } } @@ -2914,6 +2915,20 @@ impl MainSplitData { } } } + + pub fn get_active_editor(&self) -> Option { + let active_editor_tab = self.active_editor_tab.get()?; + let editor_tabs = self.editor_tabs; + let editor_tab = editor_tabs + .with(|editor_tabs| editor_tabs.get(&active_editor_tab).copied())?; + let (_, _, child) = editor_tab.with(|editor_tab| { + editor_tab.children.get(editor_tab.active).cloned() + })?; + match child { + EditorTabChild::Editor(editor_id) => self.editors.editor(editor_id), + _ => None, + } + } } fn workspace_edits(edit: &WorkspaceEdit) -> Option>> { diff --git a/lapce-app/src/panel/call_hierarchy_view.rs b/lapce-app/src/panel/call_hierarchy_view.rs index 6e76bbf4c4..1cb2881031 100644 --- a/lapce-app/src/panel/call_hierarchy_view.rs +++ b/lapce-app/src/panel/call_hierarchy_view.rs @@ -17,8 +17,7 @@ use crate::{ command::InternalCommand, config::{color::LapceColor, icon::LapceIcons}, editor::location::EditorLocation, - window_tab::CommonData, - window_tab::WindowTabData, + window_tab::{CommonData, WindowTabData}, }; #[derive(Clone, Debug)] diff --git a/lapce-app/src/panel/data.rs b/lapce-app/src/panel/data.rs index edc270678e..4aba1d9440 100644 --- a/lapce-app/src/panel/data.rs +++ b/lapce-app/src/panel/data.rs @@ -38,6 +38,10 @@ pub fn default_panel_order() -> PanelOrder { PanelKind::CallHierarchy ], ); + order.insert( + PanelPosition::RightTop, + im::vector![PanelKind::DocumentSymbol,], + ); order } diff --git a/lapce-app/src/panel/document_symbol.rs b/lapce-app/src/panel/document_symbol.rs new file mode 100644 index 0000000000..baa3ba5a79 --- /dev/null +++ b/lapce-app/src/panel/document_symbol.rs @@ -0,0 +1,299 @@ +use std::{ops::AddAssign, path::PathBuf, rc::Rc}; + +use floem::{ + event::EventPropagation, + peniko::Color, + reactive::{RwSignal, Scope}, + style::{AlignItems, CursorStyle}, + views::{ + editor::id::Id, label, scroll, stack, svg, virtual_stack, Decorators, + VirtualDirection, VirtualItemSize, VirtualVector, + }, + View, +}; +use lsp_types::DocumentSymbol; + +use super::position::PanelPosition; +use crate::{ + command::InternalCommand, + config::{color::LapceColor, icon::LapceIcons}, + editor::location::EditorLocation, + window_tab::WindowTabData, +}; + +#[derive(Clone, Debug)] +pub struct SymbolData { + pub items: Vec>, + pub path: PathBuf, +} + +impl SymbolData { + fn get_children( + &self, + min: usize, + max: usize, + ) -> Vec<( + usize, + usize, + Rc, + RwSignal, + )> { + let mut children = Vec::new(); + let path = Rc::new(self.path.clone()); + let level: usize = 0; + let mut next = 0; + for item in &self.items { + if next >= max { + return children; + } + let child_children = + get_children(*item, &mut next, min, max, level, path.clone()); + children.extend(child_children); + } + children + } +} + +#[derive(Debug, Clone)] +pub struct SymbolInformationItemData { + pub id: Id, + pub name: String, + pub item: DocumentSymbol, + pub open: RwSignal, + pub children: Vec>, +} + +impl From<(DocumentSymbol, Scope)> for SymbolInformationItemData { + fn from((mut item, cx): (DocumentSymbol, Scope)) -> Self { + let children = if let Some(children) = item.children.take() { + children + .into_iter() + .map(|x| cx.create_rw_signal(Self::from((x, cx)))) + .collect() + } else { + Vec::with_capacity(0) + }; + let name = if let Some(detail) = &item.detail { + format!("{} {}", item.name, detail) + } else { + item.name.clone() + }; + Self { + id: Id::next(), + name, + item, + open: cx.create_rw_signal(false), + children, + } + } +} + +impl SymbolInformationItemData { + pub fn child_count(&self) -> usize { + let mut count = 1; + if self.open.get() { + for child in &self.children { + count += child.with(|x| x.child_count()) + } + } + count + } +} + +fn get_children( + data: RwSignal, + next: &mut usize, + min: usize, + max: usize, + level: usize, + path: Rc, +) -> Vec<( + usize, + usize, + Rc, + RwSignal, +)> { + let mut children = Vec::new(); + if *next >= min && *next < max { + children.push((*next, level, path.clone(), data)); + } else if *next >= max { + return children; + } + next.add_assign(1); + if data.get_untracked().open.get() { + for child in data.get().children { + let child_children = + get_children(child, next, min, max, level + 1, path.clone()); + children.extend(child_children); + if *next > max { + break; + } + } + } + children +} + +pub struct VirtualList { + root: Option>>, +} + +impl VirtualList { + pub fn new(root: Option>>) -> Self { + Self { root } + } +} + +impl + VirtualVector<( + usize, + usize, + Rc, + RwSignal, + )> for VirtualList +{ + fn total_len(&self) -> usize { + if let Some(root) = self.root.as_ref().and_then(|x| x.get()) { + let len = root.items.iter().fold(0, |mut x, item| { + x += item.get_untracked().child_count(); + x + }); + len + } else { + 0 + } + } + + fn slice( + &mut self, + range: std::ops::Range, + ) -> impl Iterator< + Item = ( + usize, + usize, + Rc, + RwSignal, + ), + > { + if let Some(root) = self.root.as_ref().and_then(|x| x.get()) { + let min = range.start; + let max = range.end; + let children = root.get_children(min, max); + children.into_iter() + } else { + Vec::new().into_iter() + } + } +} +pub fn symbol_panel( + window_tab_data: Rc, + _position: PanelPosition, +) -> impl View { + let config = window_tab_data.common.config; + let ui_line_height = window_tab_data.common.ui_line_height; + scroll( + virtual_stack( + VirtualDirection::Vertical, + VirtualItemSize::Fixed(Box::new(move || ui_line_height.get())), + { + let window_tab_data = window_tab_data.clone(); + move || { + let editor = window_tab_data.main_split.get_active_editor(); + VirtualList::new(editor.map(|x| x.doc().document_symbol_data)) + } + }, + move |(_, _, _, item)| item.get_untracked().id, + move |(_, level, path, rw_data)| { + let data = rw_data.get_untracked(); + let open = data.open; + let has_child = !data.children.is_empty(); + let kind = data.item.kind; + stack(( + svg(move || { + let config = config.get(); + let svg_str = match open.get() { + true => LapceIcons::ITEM_OPENED, + false => LapceIcons::ITEM_CLOSED, + }; + config.ui_svg(svg_str) + }) + .style(move |s| { + let config = config.get(); + let color = if has_child { + config.color(LapceColor::LAPCE_ICON_ACTIVE) + } else { + Color::TRANSPARENT + }; + let size = config.ui.icon_size() as f32; + s.size(size, size) + .flex_shrink(0.0) + .margin_left(10.0) + .margin_right(6.0).color(color) + }).on_click_stop({ + move |_x| { + if has_child { + open.update(|x| { + *x = !*x; + }); + } + } + }), + svg(move || { + let config = config.get(); + config + .symbol_svg(&kind) + .unwrap_or_else(|| config.ui_svg(LapceIcons::FILE)) + }).style(move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + s.min_width(size) + .size(size, size) + .margin_right(5.0) + .color(config.color(LapceColor::LAPCE_ICON_ACTIVE)) + }), + label(move || { + data.name.clone() + }) + .style(move |s| { + s.flex_grow(1.0) + .height(ui_line_height.get()) + .selectable(false) + .align_items(AlignItems::Center) + }), + )) + .style(move |s| { + s.padding_right(5.0) + .padding_left((level * 10) as f32) + .align_items(AlignItems::Center) + .hover(|s| { + s.background( + config + .get() + .color(LapceColor::PANEL_HOVERED_BACKGROUND), + ) + .cursor(CursorStyle::Pointer) + }) + }) + .on_double_click({ + let window_tab_data = window_tab_data.clone(); + let data = rw_data; + move |_| { + let data = data.get_untracked(); + window_tab_data + .common + .internal_command + .send(InternalCommand::GoToLocation { location: EditorLocation { + path: path.to_path_buf(), + position: Some(crate::editor::location::EditorPosition::Position(data.item.range.start)), + scroll_offset: None, + ignore_unconfirmed: false, + same_editor_tab: false, + } }); + EventPropagation::Stop + } + }) + }, + ) + .style(|s| s.flex_col().align_items(AlignItems::Stretch).size_full()), + ) + .style(|s| s.size_full()) +} diff --git a/lapce-app/src/panel/kind.rs b/lapce-app/src/panel/kind.rs index 671571ebbf..030efb5838 100644 --- a/lapce-app/src/panel/kind.rs +++ b/lapce-app/src/panel/kind.rs @@ -16,6 +16,7 @@ pub enum PanelKind { Problem, Debug, CallHierarchy, + DocumentSymbol, } impl PanelKind { @@ -29,6 +30,7 @@ impl PanelKind { PanelKind::Problem => LapceIcons::PROBLEM, PanelKind::Debug => LapceIcons::DEBUG, PanelKind::CallHierarchy => LapceIcons::LINK, + PanelKind::DocumentSymbol => LapceIcons::SEARCH, } } diff --git a/lapce-app/src/panel/mod.rs b/lapce-app/src/panel/mod.rs index a539e9f9f3..2398e4f5bb 100644 --- a/lapce-app/src/panel/mod.rs +++ b/lapce-app/src/panel/mod.rs @@ -1,6 +1,7 @@ pub mod call_hierarchy_view; pub mod data; pub mod debug_view; +pub mod document_symbol; pub mod global_search_view; pub mod kind; pub mod plugin_view; diff --git a/lapce-app/src/panel/view.rs b/lapce-app/src/panel/view.rs index 1fdc4c40b5..ce4c173820 100644 --- a/lapce-app/src/panel/view.rs +++ b/lapce-app/src/panel/view.rs @@ -28,7 +28,9 @@ use crate::{ app::{clickable_icon, clickable_icon_base}, config::{color::LapceColor, icon::LapceIcons, LapceConfig}, file_explorer::view::file_explorer_panel, - panel::call_hierarchy_view::show_hierarchy_panel, + panel::{ + call_hierarchy_view::show_hierarchy_panel, document_symbol::symbol_panel, + }, window_tab::{DragContent, WindowTabData}, }; @@ -489,6 +491,9 @@ fn panel_view( show_hierarchy_panel(window_tab_data.clone(), position) .into_any() } + PanelKind::DocumentSymbol => { + symbol_panel(window_tab_data.clone(), position).into_any() + } }; view.style(|s| s.size_pct(100.0, 100.0)) }, @@ -544,6 +549,7 @@ fn panel_picker( PanelKind::Problem => (LapceIcons::PROBLEM, "Problems"), PanelKind::Debug => (LapceIcons::DEBUG_ALT, "Debug"), PanelKind::CallHierarchy => (LapceIcons::LINK, "Call Hierarchy"), + PanelKind::DocumentSymbol => (LapceIcons::SEARCH, "Document Symbol"), }; let is_active = { let window_tab_data = window_tab_data.clone(); diff --git a/lapce-app/src/window_tab.rs b/lapce-app/src/window_tab.rs index c5542ebbdf..0fb5c577cd 100644 --- a/lapce-app/src/window_tab.rs +++ b/lapce-app/src/window_tab.rs @@ -1,4 +1,3 @@ -use alacritty_terminal::vte::ansi::Handler; use std::{ collections::{BTreeMap, HashSet}, env, @@ -8,6 +7,7 @@ use std::{ time::Instant, }; +use alacritty_terminal::vte::ansi::Handler; use crossbeam_channel::Sender; use floem::{ action::{open_file, remove_overlay, TimerToken}, @@ -2007,6 +2007,7 @@ impl WindowTabData { self.main_split.docs.with_untracked(|x| { for doc in x.values() { doc.get_code_lens(); + doc.get_document_symbol(); doc.get_semantic_styles(); } }); @@ -2471,7 +2472,8 @@ impl WindowTabData { | PanelKind::Plugin | PanelKind::Problem | PanelKind::Debug - | PanelKind::CallHierarchy => { + | PanelKind::CallHierarchy + | PanelKind::DocumentSymbol => { // Some panels don't accept focus (yet). Fall back to visibility check // in those cases. self.panel.is_panel_visible(&kind) diff --git a/lapce-proxy/src/plugin/mod.rs b/lapce-proxy/src/plugin/mod.rs index 009a899047..8b09527ccc 100644 --- a/lapce-proxy/src/plugin/mod.rs +++ b/lapce-proxy/src/plugin/mod.rs @@ -49,10 +49,10 @@ use lsp_types::{ CodeActionResponse, CodeLens, CodeLensParams, CompletionClientCapabilities, CompletionItem, CompletionItemCapability, CompletionItemCapabilityResolveSupport, CompletionParams, CompletionResponse, - Diagnostic, DocumentFormattingParams, DocumentSymbolParams, - DocumentSymbolResponse, FormattingOptions, GotoCapability, GotoDefinitionParams, - GotoDefinitionResponse, Hover, HoverClientCapabilities, HoverParams, InlayHint, - InlayHintClientCapabilities, InlayHintParams, + Diagnostic, DocumentFormattingParams, DocumentSymbolClientCapabilities, + DocumentSymbolParams, DocumentSymbolResponse, FormattingOptions, GotoCapability, + GotoDefinitionParams, GotoDefinitionResponse, Hover, HoverClientCapabilities, + HoverParams, InlayHint, InlayHintClientCapabilities, InlayHintParams, InlineCompletionClientCapabilities, InlineCompletionParams, InlineCompletionResponse, InlineCompletionTriggerKind, Location, MarkupKind, MessageActionItemCapabilities, ParameterInformationSettings, @@ -1623,6 +1623,10 @@ fn client_capabilities() -> ClientCapabilities { call_hierarchy: Some(CallHierarchyClientCapabilities { dynamic_registration: Some(true), }), + document_symbol: Some(DocumentSymbolClientCapabilities { + hierarchical_document_symbol_support: Some(true), + ..Default::default() + }), ..Default::default() }), window: Some(WindowClientCapabilities { diff --git a/lapce-proxy/src/terminal.rs b/lapce-proxy/src/terminal.rs index e7c996964c..76a89e6cdf 100644 --- a/lapce-proxy/src/terminal.rs +++ b/lapce-proxy/src/terminal.rs @@ -1,4 +1,3 @@ -use std::time::Duration; use std::{ borrow::Cow, collections::VecDeque, @@ -6,6 +5,7 @@ use std::{ num::NonZeroUsize, path::PathBuf, sync::Arc, + time::Duration, }; use alacritty_terminal::{ From 8efe4bbdeffba50ef3484e4fb205503b438a2628 Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Mon, 12 Aug 2024 22:22:15 +0100 Subject: [PATCH 12/69] change some panel icons --- defaults/icon-theme.toml | 2 ++ icons/codicons/type-hierarchy.svg | 1 + lapce-app/src/config/icon.rs | 2 ++ lapce-app/src/panel/kind.rs | 4 ++-- lapce-app/src/panel/view.rs | 23 +++++++++++------------ 5 files changed, 18 insertions(+), 14 deletions(-) create mode 100644 icons/codicons/type-hierarchy.svg diff --git a/defaults/icon-theme.toml b/defaults/icon-theme.toml index 8bda5b1de8..4a818c9bee 100644 --- a/defaults/icon-theme.toml +++ b/defaults/icon-theme.toml @@ -36,6 +36,7 @@ name = "Lapce Codicons" "keyboard" = "keyboard.svg" "breadcrumb_separator" = "chevron-right.svg" "symbol_color" = "symbol-color.svg" +"type_hierarchy" = "type-hierarchy.svg" "window.close" = "chrome-close.svg" "window.restore" = "chrome-restore.svg" @@ -103,6 +104,7 @@ name = "Lapce Codicons" "search.replace" = "replace.svg" "search.replace_all" = "replace-all.svg" +"document_symbol" = "symbol-class.svg" "symbol_kind.array" = "symbol-array.svg" "symbol_kind.boolean" = "symbol-boolean.svg" "symbol_kind.class" = "symbol-class.svg" diff --git a/icons/codicons/type-hierarchy.svg b/icons/codicons/type-hierarchy.svg new file mode 100644 index 0000000000..bcbc902e40 --- /dev/null +++ b/icons/codicons/type-hierarchy.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/lapce-app/src/config/icon.rs b/lapce-app/src/config/icon.rs index a53812e88b..61a17bd421 100644 --- a/lapce-app/src/config/icon.rs +++ b/lapce-app/src/config/icon.rs @@ -38,6 +38,7 @@ impl LapceIcons { pub const KEYBOARD: &'static str = "keyboard"; pub const BREADCRUMB_SEPARATOR: &'static str = "breadcrumb_separator"; pub const SYMBOL_COLOR: &'static str = "symbol_color"; + pub const TYPE_HIERARCHY: &'static str = "type_hierarchy"; pub const FILE: &'static str = "file"; pub const FILE_EXPLORER: &'static str = "file_explorer"; @@ -108,6 +109,7 @@ impl LapceIcons { pub const FILE_TYPE_SYMLINK_FILE: &'static str = "file-symlink-file"; pub const FILE_TYPE_SYMLINK_DIRECTORY: &'static str = "file-symlink-directory"; + pub const DOCUMENT_SYMBOL: &'static str = "document_symbol"; pub const SYMBOL_KIND_ARRAY: &'static str = "symbol_kind.array"; pub const SYMBOL_KIND_BOOLEAN: &'static str = "symbol_kind.boolean"; pub const SYMBOL_KIND_CLASS: &'static str = "symbol_kind.class"; diff --git a/lapce-app/src/panel/kind.rs b/lapce-app/src/panel/kind.rs index 030efb5838..0f29f5c241 100644 --- a/lapce-app/src/panel/kind.rs +++ b/lapce-app/src/panel/kind.rs @@ -29,8 +29,8 @@ impl PanelKind { PanelKind::Search => LapceIcons::SEARCH, PanelKind::Problem => LapceIcons::PROBLEM, PanelKind::Debug => LapceIcons::DEBUG, - PanelKind::CallHierarchy => LapceIcons::LINK, - PanelKind::DocumentSymbol => LapceIcons::SEARCH, + PanelKind::CallHierarchy => LapceIcons::TYPE_HIERARCHY, + PanelKind::DocumentSymbol => LapceIcons::DOCUMENT_SYMBOL, } } diff --git a/lapce-app/src/panel/view.rs b/lapce-app/src/panel/view.rs index ce4c173820..4e7d370b31 100644 --- a/lapce-app/src/panel/view.rs +++ b/lapce-app/src/panel/view.rs @@ -538,19 +538,18 @@ fn panel_picker( |p| *p, move |p| { let window_tab_data = window_tab_data.clone(); - let (icon, tooltip) = match p { - PanelKind::Terminal => (LapceIcons::TERMINAL, "Terminal"), - PanelKind::FileExplorer => { - (LapceIcons::FILE_EXPLORER, "File Explorer") - } - PanelKind::SourceControl => (LapceIcons::SCM, "Source Control"), - PanelKind::Plugin => (LapceIcons::EXTENSIONS, "Plugins"), - PanelKind::Search => (LapceIcons::SEARCH, "Search"), - PanelKind::Problem => (LapceIcons::PROBLEM, "Problems"), - PanelKind::Debug => (LapceIcons::DEBUG_ALT, "Debug"), - PanelKind::CallHierarchy => (LapceIcons::LINK, "Call Hierarchy"), - PanelKind::DocumentSymbol => (LapceIcons::SEARCH, "Document Symbol"), + let tooltip = match p { + PanelKind::Terminal => "Terminal", + PanelKind::FileExplorer => "File Explorer", + PanelKind::SourceControl => "Source Control", + PanelKind::Plugin => "Plugins", + PanelKind::Search => "Search", + PanelKind::Problem => "Problems", + PanelKind::Debug => "Debug", + PanelKind::CallHierarchy => "Call Hierarchy", + PanelKind::DocumentSymbol => "Document Symbol", }; + let icon = p.svg_name(); let is_active = { let window_tab_data = window_tab_data.clone(); move || { From 06c5174555c0aa295beafd935dfd3b523fd03e8e Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Mon, 12 Aug 2024 22:24:31 +0100 Subject: [PATCH 13/69] update CHANGELOG --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a55d3a7e1f..0a4a3c8306 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ ### Features/Changes - Implement "Run in terminal" +- Implement document symbols in a panel +- Implement 'Go To Location' functionality in the Diff editor. +- implement on screen find which is similar to `f` in vim but for the whole screen. ### Bug Fixes - Fix markdown syntax highlighting From b9062c01a7cd08526a0aed62ddae9b2c39e1069a Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Mon, 12 Aug 2024 22:57:44 +0100 Subject: [PATCH 14/69] make file explorer horizontal scrollable --- lapce-app/src/file_explorer/node.rs | 2 +- lapce-app/src/file_explorer/view.rs | 23 +++++++++------------- lapce-app/src/panel/call_hierarchy_view.rs | 2 +- 3 files changed, 11 insertions(+), 16 deletions(-) diff --git a/lapce-app/src/file_explorer/node.rs b/lapce-app/src/file_explorer/node.rs index 633b65962a..278c9215cc 100644 --- a/lapce-app/src/file_explorer/node.rs +++ b/lapce-app/src/file_explorer/node.rs @@ -17,7 +17,7 @@ impl FileNodeVirtualList { impl VirtualVector for FileNodeVirtualList { fn total_len(&self) -> usize { - self.file_node_item.children_open_count + self.file_node_item.children_open_count + 1 } fn slice( diff --git a/lapce-app/src/file_explorer/view.rs b/lapce-app/src/file_explorer/view.rs index 752497699d..52c8032347 100644 --- a/lapce-app/src/file_explorer/view.rs +++ b/lapce-app/src/file_explorer/view.rs @@ -86,10 +86,8 @@ pub fn file_explorer_panel( ) .add( "File Explorer", - container( - new_file_node_view(data, source_control).style(|s| s.absolute()), - ) - .style(|s| s.size_full().line_height(1.8)), + container(file_explorer_view(data, source_control)) + .style(|s| s.size_full()), window_tab_data .panel .section_open(PanelSection::FileExplorer), @@ -173,7 +171,7 @@ fn file_node_text_view( let config = data.common.config; let ui_line_height = data.common.ui_line_height; - let view = match node.kind.clone() { + match node.kind.clone() { FileNodeViewKind::Path(path) => container( label(move || { path.file_name() @@ -181,8 +179,7 @@ fn file_node_text_view( .unwrap_or_default() }) .style(move |s| { - s.flex_grow(1.0) - .height(ui_line_height.get()) + s.height(ui_line_height.get()) .color(file_node_text_color( config, node.clone(), @@ -212,9 +209,7 @@ fn file_node_text_view( file_node_input_view(data, err.clone()) } - }; - - view.style(|s| s.flex_grow(1.0).padding(0.0).margin(0.0)) + } } /// Input used for naming a file/directory @@ -282,7 +277,7 @@ fn file_node_input_view(data: FileExplorerData, err: Option) -> Containe } } -fn new_file_node_view( +fn file_explorer_view( data: FileExplorerData, source_control: SourceControlData, ) -> impl View { @@ -376,7 +371,7 @@ fn new_file_node_view( file_node_text_view(data, node, source_control.clone()), )) .style(move |s| { - s.padding_right(5.0) + s.padding_right(15.0) .padding_left((level * 10) as f32) .align_items(AlignItems::Center) .hover(|s| { @@ -419,9 +414,9 @@ fn new_file_node_view( } }, ) - .style(|s| s.flex_col().align_items(AlignItems::Stretch).width_full()), + .style(|s| s.absolute().flex_col().min_width_full()), ) - .style(|s| s.size_full()) + .style(|s| s.absolute().size_full().line_height(1.8)) .on_secondary_click_stop(move |_| { if let Naming::None = naming.get_untracked() { if let Some(path) = &secondary_click_data.common.workspace.path { diff --git a/lapce-app/src/panel/call_hierarchy_view.rs b/lapce-app/src/panel/call_hierarchy_view.rs index 1cb2881031..d142edfb1e 100644 --- a/lapce-app/src/panel/call_hierarchy_view.rs +++ b/lapce-app/src/panel/call_hierarchy_view.rs @@ -229,7 +229,7 @@ pub fn show_hierarchy_panel( ) .style(|s| s.flex_col().align_items(AlignItems::Stretch).width_full()), ) - .style(|s| s.size_full()) + .style(|s| s.absolute().size_full()) .scroll_to(move || { if let Some(line) = scroll_to_line.get() { let line_height = ui_line_height.get(); From 3dd37e703b937d28258ed9171106871c02fa835f Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Mon, 12 Aug 2024 23:03:48 +0100 Subject: [PATCH 15/69] scroll style fix --- lapce-app/src/panel/call_hierarchy_view.rs | 2 +- lapce-app/src/panel/document_symbol.rs | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lapce-app/src/panel/call_hierarchy_view.rs b/lapce-app/src/panel/call_hierarchy_view.rs index d142edfb1e..c0f797b3fb 100644 --- a/lapce-app/src/panel/call_hierarchy_view.rs +++ b/lapce-app/src/panel/call_hierarchy_view.rs @@ -227,7 +227,7 @@ pub fn show_hierarchy_panel( }) }, ) - .style(|s| s.flex_col().align_items(AlignItems::Stretch).width_full()), + .style(|s| s.flex_col().absolute().min_width_full()), ) .style(|s| s.absolute().size_full()) .scroll_to(move || { diff --git a/lapce-app/src/panel/document_symbol.rs b/lapce-app/src/panel/document_symbol.rs index baa3ba5a79..18484c4a53 100644 --- a/lapce-app/src/panel/document_symbol.rs +++ b/lapce-app/src/panel/document_symbol.rs @@ -184,6 +184,7 @@ impl } } } + pub fn symbol_panel( window_tab_data: Rc, _position: PanelPosition, @@ -293,7 +294,7 @@ pub fn symbol_panel( }) }, ) - .style(|s| s.flex_col().align_items(AlignItems::Stretch).size_full()), + .style(|s| s.flex_col().absolute().min_width_full()), ) - .style(|s| s.size_full()) + .style(|s| s.absolute().size_full()) } From e95283f51a09febf105bc570882c21b571e8eb3b Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Tue, 13 Aug 2024 19:40:04 +0100 Subject: [PATCH 16/69] A few style tweaks --- Cargo.lock | 14 ++-- Cargo.toml | 4 +- lapce-app/src/app.rs | 9 +- lapce-app/src/config.rs | 30 +++++++ lapce-app/src/doc.rs | 3 - lapce-app/src/file_explorer/node.rs | 2 +- lapce-app/src/file_explorer/view.rs | 1 + lapce-app/src/palette.rs | 97 +++++++++++++--------- lapce-app/src/panel/call_hierarchy_view.rs | 96 +++++++++++---------- lapce-app/src/panel/document_symbol.rs | 89 ++++++++++---------- lapce-app/src/proxy/remote.rs | 17 ++-- lapce-core/src/meta.rs | 2 +- 12 files changed, 217 insertions(+), 147 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7bdabad25a..22a6965a81 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1684,7 +1684,7 @@ checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" [[package]] name = "floem" version = "0.1.1" -source = "git+https://github.com/lapce/floem?rev=a207ef4bd463d41be1d06daeae3be7936b0dbb60#a207ef4bd463d41be1d06daeae3be7936b0dbb60" +source = "git+https://github.com/lapce/floem?rev=3a974c9bbc0c1dfefc17affb976ea8e9ae31369b#3a974c9bbc0c1dfefc17affb976ea8e9ae31369b" dependencies = [ "bitflags 2.6.0", "copypasta", @@ -1702,7 +1702,6 @@ dependencies = [ "image", "indexmap", "lapce-xi-rope", - "once_cell", "parking_lot", "peniko", "raw-window-handle 0.6.0", @@ -1722,13 +1721,12 @@ dependencies = [ [[package]] name = "floem-editor-core" version = "0.1.1" -source = "git+https://github.com/lapce/floem?rev=a207ef4bd463d41be1d06daeae3be7936b0dbb60#a207ef4bd463d41be1d06daeae3be7936b0dbb60" +source = "git+https://github.com/lapce/floem?rev=3a974c9bbc0c1dfefc17affb976ea8e9ae31369b#3a974c9bbc0c1dfefc17affb976ea8e9ae31369b" dependencies = [ "bitflags 2.6.0", "itertools 0.12.1", "lapce-xi-rope", "memchr", - "once_cell", "serde", "strum", "strum_macros", @@ -1800,7 +1798,7 @@ dependencies = [ [[package]] name = "floem_reactive" version = "0.1.1" -source = "git+https://github.com/lapce/floem?rev=a207ef4bd463d41be1d06daeae3be7936b0dbb60#a207ef4bd463d41be1d06daeae3be7936b0dbb60" +source = "git+https://github.com/lapce/floem?rev=3a974c9bbc0c1dfefc17affb976ea8e9ae31369b#3a974c9bbc0c1dfefc17affb976ea8e9ae31369b" dependencies = [ "smallvec", ] @@ -1808,7 +1806,7 @@ dependencies = [ [[package]] name = "floem_renderer" version = "0.1.1" -source = "git+https://github.com/lapce/floem?rev=a207ef4bd463d41be1d06daeae3be7936b0dbb60#a207ef4bd463d41be1d06daeae3be7936b0dbb60" +source = "git+https://github.com/lapce/floem?rev=3a974c9bbc0c1dfefc17affb976ea8e9ae31369b#3a974c9bbc0c1dfefc17affb976ea8e9ae31369b" dependencies = [ "cosmic-text", "image", @@ -1821,7 +1819,7 @@ dependencies = [ [[package]] name = "floem_tiny_skia_renderer" version = "0.1.1" -source = "git+https://github.com/lapce/floem?rev=a207ef4bd463d41be1d06daeae3be7936b0dbb60#a207ef4bd463d41be1d06daeae3be7936b0dbb60" +source = "git+https://github.com/lapce/floem?rev=3a974c9bbc0c1dfefc17affb976ea8e9ae31369b#3a974c9bbc0c1dfefc17affb976ea8e9ae31369b" dependencies = [ "anyhow", "bytemuck", @@ -1838,7 +1836,7 @@ dependencies = [ [[package]] name = "floem_vger_renderer" version = "0.1.1" -source = "git+https://github.com/lapce/floem?rev=a207ef4bd463d41be1d06daeae3be7936b0dbb60#a207ef4bd463d41be1d06daeae3be7936b0dbb60" +source = "git+https://github.com/lapce/floem?rev=3a974c9bbc0c1dfefc17affb976ea8e9ae31369b#3a974c9bbc0c1dfefc17affb976ea8e9ae31369b" dependencies = [ "anyhow", "floem-vger", diff --git a/Cargo.toml b/Cargo.toml index 694595a460..28ddba1ae6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -76,9 +76,9 @@ lapce-core = { path = "./lapce-core" } lapce-rpc = { path = "./lapce-rpc" } lapce-proxy = { path = "./lapce-proxy" } -floem = { git = "https://github.com/lapce/floem", rev = "a207ef4bd463d41be1d06daeae3be7936b0dbb60", features = ["editor", "serde", "default-image-formats", "rfd-async-std"] } +floem = { git = "https://github.com/lapce/floem", rev = "3a974c9bbc0c1dfefc17affb976ea8e9ae31369b", 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 = "a207ef4bd463d41be1d06daeae3be7936b0dbb60", features = ["serde"] } +floem-editor-core = { git = "https://github.com/lapce/floem", rev = "3a974c9bbc0c1dfefc17affb976ea8e9ae31369b", features = ["serde"] } # floem-editor-core = { path = "../floem/editor-core/", features = ["serde"] } [patch.crates-io] diff --git a/lapce-app/src/app.rs b/lapce-app/src/app.rs index 4008fed604..b9e6a2a7d6 100644 --- a/lapce-app/src/app.rs +++ b/lapce-app/src/app.rs @@ -2261,10 +2261,11 @@ fn palette_item( .style(move |s| { let config = config.get(); let size = config.ui.icon_size() as f32; - s.min_width(size) - .size(size, size) - .margin_right(5.0) - .color(config.color(LapceColor::LAPCE_ICON_ACTIVE)) + s.min_width(size).size(size, size).margin_right(5.0).color( + config.symbol_color(&kind).unwrap_or_else(|| { + config.color(LapceColor::LAPCE_ICON_ACTIVE) + }), + ) }), focus_text( move || text.clone(), diff --git a/lapce-app/src/config.rs b/lapce-app/src/config.rs index 4258f636a0..7c70e30340 100644 --- a/lapce-app/src/config.rs +++ b/lapce-app/src/config.rs @@ -655,6 +655,36 @@ impl LapceConfig { Some(self.ui_svg(kind_str)) } + pub fn symbol_color(&self, kind: &SymbolKind) -> Option { + let theme_str = match *kind { + SymbolKind::METHOD => "method", + SymbolKind::FUNCTION => "method", + SymbolKind::ENUM => "enum", + SymbolKind::ENUM_MEMBER => "enum-member", + SymbolKind::CLASS => "class", + SymbolKind::VARIABLE => "field", + SymbolKind::STRUCT => "structure", + SymbolKind::CONSTANT => "constant", + SymbolKind::PROPERTY => "property", + SymbolKind::FIELD => "field", + SymbolKind::INTERFACE => "interface", + SymbolKind::ARRAY => "", + SymbolKind::BOOLEAN => "", + SymbolKind::EVENT => "", + SymbolKind::FILE => "", + SymbolKind::KEY => "", + SymbolKind::OBJECT => "", + SymbolKind::NAMESPACE => "", + SymbolKind::NUMBER => "number", + SymbolKind::OPERATOR => "", + SymbolKind::TYPE_PARAMETER => "", + SymbolKind::STRING => "string", + _ => return None, + }; + + self.style_color(theme_str) + } + pub fn logo_svg(&self) -> String { self.svg_store.read().logo_svg() } diff --git a/lapce-app/src/doc.rs b/lapce-app/src/doc.rs index 50e1195add..b733036af9 100644 --- a/lapce-app/src/doc.rs +++ b/lapce-app/src/doc.rs @@ -919,9 +919,6 @@ impl Doc { pub fn get_document_symbol(&self) { let cx = self.scope; let doc = self.clone(); - self.document_symbol_data.update(|symbol| { - symbol.take(); - }); let rev = self.rev(); if let DocContent::File { path, .. } = doc.content.get_untracked() { let send = create_ext_action(cx, { diff --git a/lapce-app/src/file_explorer/node.rs b/lapce-app/src/file_explorer/node.rs index 278c9215cc..633b65962a 100644 --- a/lapce-app/src/file_explorer/node.rs +++ b/lapce-app/src/file_explorer/node.rs @@ -17,7 +17,7 @@ impl FileNodeVirtualList { impl VirtualVector for FileNodeVirtualList { fn total_len(&self) -> usize { - self.file_node_item.children_open_count + 1 + self.file_node_item.children_open_count } fn slice( diff --git a/lapce-app/src/file_explorer/view.rs b/lapce-app/src/file_explorer/view.rs index 52c8032347..92183a7810 100644 --- a/lapce-app/src/file_explorer/view.rs +++ b/lapce-app/src/file_explorer/view.rs @@ -372,6 +372,7 @@ fn file_explorer_view( )) .style(move |s| { s.padding_right(15.0) + .min_width_full() .padding_left((level * 10) as f32) .align_items(AlignItems::Center) .hover(|s| { diff --git a/lapce-app/src/palette.rs b/lapce-app/src/palette.rs index 4b84eeef5c..1a5e549aed 100644 --- a/lapce-app/src/palette.rs +++ b/lapce-app/src/palette.rs @@ -25,7 +25,7 @@ use lapce_core::{ }; use lapce_rpc::proxy::ProxyResponse; use lapce_xi_rope::Rope; -use lsp_types::DocumentSymbolResponse; +use lsp_types::{DocumentSymbol, DocumentSymbolResponse}; use nucleo::Utf32Str; use strum::{EnumMessage, IntoEnumIterator}; use tracing::error; @@ -646,42 +646,7 @@ impl PaletteData { let set_items = self.items.write_only(); let send = create_ext_action(self.common.scope, move |result| { if let Ok(ProxyResponse::GetDocumentSymbols { resp }) = result { - let items: im::Vector = match resp { - DocumentSymbolResponse::Flat(symbols) => symbols - .iter() - .map(|s| { - let mut filter_text = s.name.clone(); - if let Some(container_name) = s.container_name.as_ref() { - filter_text += container_name; - } - PaletteItem { - content: PaletteItemContent::DocumentSymbol { - kind: s.kind, - name: s.name.clone(), - range: s.location.range, - container_name: s.container_name.clone(), - }, - filter_text, - score: 0, - indices: Vec::new(), - } - }) - .collect(), - DocumentSymbolResponse::Nested(symbols) => symbols - .iter() - .map(|s| PaletteItem { - content: PaletteItemContent::DocumentSymbol { - kind: s.kind, - name: s.name.clone(), - range: s.range, - container_name: None, - }, - filter_text: s.name.clone(), - score: 0, - indices: Vec::new(), - }) - .collect(), - }; + let items = Self::format_document_symbol_resp(resp); set_items.set(items); } else { set_items.update(|items| items.clear()); @@ -693,6 +658,64 @@ impl PaletteData { }); } + fn format_document_symbol_resp( + resp: DocumentSymbolResponse, + ) -> im::Vector { + match resp { + DocumentSymbolResponse::Flat(symbols) => symbols + .iter() + .map(|s| { + let mut filter_text = s.name.clone(); + if let Some(container_name) = s.container_name.as_ref() { + filter_text += container_name; + } + PaletteItem { + content: PaletteItemContent::DocumentSymbol { + kind: s.kind, + name: s.name.replace('\n', "↵"), + range: s.location.range, + container_name: s.container_name.clone(), + }, + filter_text, + score: 0, + indices: Vec::new(), + } + }) + .collect(), + DocumentSymbolResponse::Nested(symbols) => { + let mut items = im::Vector::new(); + for s in symbols { + Self::format_document_symbol(&mut items, None, s) + } + items + } + } + } + + fn format_document_symbol( + items: &mut im::Vector, + parent: Option, + s: DocumentSymbol, + ) { + items.push_back(PaletteItem { + content: PaletteItemContent::DocumentSymbol { + kind: s.kind, + name: s.name.replace('\n', "↵"), + range: s.range, + container_name: parent, + }, + filter_text: s.name.clone(), + score: 0, + indices: Vec::new(), + }); + if let Some(children) = s.children { + let parent = Some(s.name.replace('\n', "↵")); + for child in children { + Self::format_document_symbol(items, parent.clone(), child); + } + } + } + fn get_workspace_symbols(&self) { let input = self.input.get_untracked().input; diff --git a/lapce-app/src/panel/call_hierarchy_view.rs b/lapce-app/src/panel/call_hierarchy_view.rs index c0f797b3fb..47934c38b9 100644 --- a/lapce-app/src/panel/call_hierarchy_view.rs +++ b/lapce-app/src/panel/call_hierarchy_view.rs @@ -1,14 +1,13 @@ use std::{ops::AddAssign, rc::Rc}; use floem::{ - event::EventPropagation, reactive::RwSignal, - style::{AlignItems, CursorStyle}, + style::CursorStyle, views::{ - container, label, scroll, stack, svg, virtual_stack, Decorators, + container, empty, label, scroll, stack, svg, virtual_stack, Decorators, VirtualDirection, VirtualItemSize, VirtualVector, }, - View, ViewId, + IntoView, View, ViewId, }; use lsp_types::{CallHierarchyItem, Range}; @@ -140,24 +139,26 @@ pub fn show_hierarchy_panel( move |(_, level, rw_data)| { let data = rw_data.get_untracked(); let open = data.open; + let kind = data.item.kind; stack(( - svg(move || { - let config = config.get(); - let svg_str = match open.get() { - true => LapceIcons::ITEM_OPENED, - false => LapceIcons::ITEM_CLOSED, - }; - config.ui_svg(svg_str) - }) - .style(move |s| { - let config = config.get(); - let size = config.ui.icon_size() as f32; - s.size(size, size) - .flex_shrink(0.0) - .margin_left(10.0) - .margin_right(6.0) - .color(config.color(LapceColor::LAPCE_ICON_ACTIVE)) - }).on_click_stop({ + container( + svg(move || { + let config = config.get(); + let svg_str = match open.get() { + true => LapceIcons::ITEM_OPENED, + false => LapceIcons::ITEM_CLOSED, + }; + config.ui_svg(svg_str) + }) + .style(move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + s.size(size, size) + .color(config.color(LapceColor::LAPCE_ICON_ACTIVE)) + }) + ) + .style(|s| s.padding(4.0).margin_left(6.0).margin_right(2.0)) + .on_click_stop({ let window_tab_data = window_tab_data.clone(); move |_x| { open.update(|x| { @@ -172,27 +173,37 @@ pub fn show_hierarchy_panel( } } }), - container( - label(move || { - format!( - "{} {} {}", - data.item.name, - data.item.detail.as_deref().unwrap_or(""), data.from_range.start.line - ) - }) - .style(move |s| { - s.flex_grow(1.0) - .height(ui_line_height.get()) - .selectable(false) - .align_items(AlignItems::Center) + svg(move || { + let config = config.get(); + config + .symbol_svg(&kind) + .unwrap_or_else(|| config.ui_svg(LapceIcons::FILE)) + }).style(move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + s.min_width(size) + .size(size, size) + .margin_right(5.0) + .color(config.symbol_color(&kind).unwrap_or_else(|| { + config.color(LapceColor::LAPCE_ICON_ACTIVE) + })) }), - ) - .style(|s| s.flex_grow(1.0).padding(0.0).margin(0.0)), + data.item.name.clone().into_view(), + if data.item.detail.is_some() { + label(move || { + data.item.detail.clone().unwrap_or_default().replace('\n', "↵") + }).style(move |s| s.margin_left(6.0) + .color(config.get().color(LapceColor::EDITOR_DIM)) + ).into_any() + } else { + empty().into_any() + }, )) .style(move |s| { s.padding_right(5.0) + .height(ui_line_height.get()) .padding_left((level * 10) as f32) - .align_items(AlignItems::Center) + .items_center() .hover(|s| { s.background( config @@ -202,13 +213,15 @@ pub fn show_hierarchy_panel( .cursor(CursorStyle::Pointer) }) }) - .on_double_click({ + .on_click_stop({ let window_tab_data = window_tab_data.clone(); let data = rw_data; move |_| { - window_tab_data.common.internal_command.send( - InternalCommand::CallHierarchyIncoming { item_id: rw_data.get_untracked().view_id }, - ); + if !rw_data.get_untracked().init { + window_tab_data.common.internal_command.send( + InternalCommand::CallHierarchyIncoming { item_id: rw_data.get_untracked().view_id }, + ); + } let data = data.get_untracked(); if let Ok(path) = data.item.uri.to_file_path() { window_tab_data @@ -222,7 +235,6 @@ pub fn show_hierarchy_panel( same_editor_tab: false, } }); } - EventPropagation::Stop } }) }, diff --git a/lapce-app/src/panel/document_symbol.rs b/lapce-app/src/panel/document_symbol.rs index 18484c4a53..8c4e8b2f2f 100644 --- a/lapce-app/src/panel/document_symbol.rs +++ b/lapce-app/src/panel/document_symbol.rs @@ -1,13 +1,12 @@ use std::{ops::AddAssign, path::PathBuf, rc::Rc}; use floem::{ - event::EventPropagation, peniko::Color, reactive::{RwSignal, Scope}, - style::{AlignItems, CursorStyle}, + style::CursorStyle, views::{ - editor::id::Id, label, scroll, stack, svg, virtual_stack, Decorators, - VirtualDirection, VirtualItemSize, VirtualVector, + container, editor::id::Id, label, scroll, stack, svg, virtual_stack, + Decorators, VirtualDirection, VirtualItemSize, VirtualVector, }, View, }; @@ -58,6 +57,7 @@ impl SymbolData { pub struct SymbolInformationItemData { pub id: Id, pub name: String, + pub detail: Option, pub item: DocumentSymbol, pub open: RwSignal, pub children: Vec>, @@ -73,16 +73,12 @@ impl From<(DocumentSymbol, Scope)> for SymbolInformationItemData { } else { Vec::with_capacity(0) }; - let name = if let Some(detail) = &item.detail { - format!("{} {}", item.name, detail) - } else { - item.name.clone() - }; Self { id: Id::next(), - name, + name: item.name.clone(), + detail: item.detail.clone(), item, - open: cx.create_rw_signal(false), + open: cx.create_rw_signal(true), children, } } @@ -209,27 +205,28 @@ pub fn symbol_panel( let has_child = !data.children.is_empty(); let kind = data.item.kind; stack(( - svg(move || { - let config = config.get(); - let svg_str = match open.get() { - true => LapceIcons::ITEM_OPENED, - false => LapceIcons::ITEM_CLOSED, - }; - config.ui_svg(svg_str) - }) - .style(move |s| { - let config = config.get(); - let color = if has_child { - config.color(LapceColor::LAPCE_ICON_ACTIVE) - } else { - Color::TRANSPARENT - }; - let size = config.ui.icon_size() as f32; - s.size(size, size) - .flex_shrink(0.0) - .margin_left(10.0) - .margin_right(6.0).color(color) - }).on_click_stop({ + container( + svg(move || { + let config = config.get(); + let svg_str = match open.get() { + true => LapceIcons::ITEM_OPENED, + false => LapceIcons::ITEM_CLOSED, + }; + config.ui_svg(svg_str) + }) + .style(move |s| { + let config = config.get(); + let color = if has_child { + config.color(LapceColor::LAPCE_ICON_ACTIVE) + } else { + Color::TRANSPARENT + }; + let size = config.ui.icon_size() as f32; + s.size(size, size) + .color(color) + }) + ).style(|s| s.padding(4.0).margin_left(6.0).margin_right(2.0)) + .on_click_stop({ move |_x| { if has_child { open.update(|x| { @@ -249,22 +246,31 @@ pub fn symbol_panel( s.min_width(size) .size(size, size) .margin_right(5.0) - .color(config.color(LapceColor::LAPCE_ICON_ACTIVE)) + .color(config.symbol_color(&kind).unwrap_or_else(|| { + config.color(LapceColor::LAPCE_ICON_ACTIVE) + })) }), label(move || { - data.name.clone() + data.name.replace('\n', "↵") }) .style(move |s| { - s.flex_grow(1.0) - .height(ui_line_height.get()) - .selectable(false) - .align_items(AlignItems::Center) + s.selectable(false) }), + label(move || { + data.detail.clone().unwrap_or_default() + }).style(move |s| s.margin_left(6.0) + .color(config.get().color(LapceColor::EDITOR_DIM)) + .selectable(false) + .apply_if( + data.item.detail.clone().is_none(), + |s| s.hide()) + ), )) .style(move |s| { s.padding_right(5.0) .padding_left((level * 10) as f32) - .align_items(AlignItems::Center) + .items_center() + .height(ui_line_height.get()) .hover(|s| { s.background( config @@ -274,7 +280,7 @@ pub fn symbol_panel( .cursor(CursorStyle::Pointer) }) }) - .on_double_click({ + .on_click_stop({ let window_tab_data = window_tab_data.clone(); let data = rw_data; move |_| { @@ -284,12 +290,11 @@ pub fn symbol_panel( .internal_command .send(InternalCommand::GoToLocation { location: EditorLocation { path: path.to_path_buf(), - position: Some(crate::editor::location::EditorPosition::Position(data.item.range.start)), + position: Some(crate::editor::location::EditorPosition::Position(data.item.selection_range.start)), scroll_offset: None, ignore_unconfirmed: false, same_editor_tab: false, } }); - EventPropagation::Stop } }) }, diff --git a/lapce-app/src/proxy/remote.rs b/lapce-app/src/proxy/remote.rs index 73a487451a..919583e3ce 100644 --- a/lapce-app/src/proxy/remote.rs +++ b/lapce-app/src/proxy/remote.rs @@ -6,7 +6,10 @@ use std::{ use anyhow::{anyhow, Result}; use flate2::read::GzDecoder; -use lapce_core::{directory::Directory, meta}; +use lapce_core::{ + directory::Directory, + meta::{self, ReleaseType}, +}; use lapce_rpc::{ core::CoreRpcHandler, proxy::{ProxyRpc, ProxyRpcHandler}, @@ -118,7 +121,7 @@ pub fn start_remote( .args([&remote_proxy_file, "--version"]) .output() .map(|output| { - if meta::VERSION == "debug" { + if meta::RELEASE == ReleaseType::Debug { String::from_utf8_lossy(&output.stdout).starts_with("Lapce-proxy") } else { String::from_utf8_lossy(&output.stdout).trim() @@ -267,10 +270,10 @@ fn download_remote( _ => { let proxy_script = general_purpose::STANDARD.encode(UNIX_PROXY_SCRIPT); - let version = if meta::VERSION == "debug" { - "nightly" - } else { - meta::VERSION + let version = match meta::RELEASE { + ReleaseType::Debug => "nightly".to_string(), + ReleaseType::Nightly => "nightly".to_string(), + ReleaseType::Stable => format!("v{}", meta::VERSION), }; let cmd = remote .command_builder() @@ -283,7 +286,7 @@ fn download_remote( "|", "sh", "/dev/stdin", - version, + &version, remote_proxy_path, ]) .output()?; diff --git a/lapce-core/src/meta.rs b/lapce-core/src/meta.rs index d79ab2f8d2..1add227339 100644 --- a/lapce-core/src/meta.rs +++ b/lapce-core/src/meta.rs @@ -1,4 +1,4 @@ -#[derive(strum_macros::AsRefStr)] +#[derive(strum_macros::AsRefStr, PartialEq, Eq)] pub enum ReleaseType { Debug, Stable, From 74faab555fee8983ee5654ce8144042958e2b94c Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Wed, 14 Aug 2024 02:46:55 +0800 Subject: [PATCH 17/69] Implement a selection visual effect in the File Explorer. (#3434) Co-authored-by: Dongdong Zhou --- lapce-app/src/file_explorer/data.rs | 10 ++++-- lapce-app/src/file_explorer/view.rs | 50 ++++++++++++++++++++--------- 2 files changed, 42 insertions(+), 18 deletions(-) diff --git a/lapce-app/src/file_explorer/data.rs b/lapce-app/src/file_explorer/data.rs index 0ea95b8930..5a3d2bf172 100644 --- a/lapce-app/src/file_explorer/data.rs +++ b/lapce-app/src/file_explorer/data.rs @@ -22,7 +22,10 @@ use lapce_core::{ register::Clipboard, }; use lapce_rpc::{ - file::{Duplicating, FileNodeItem, Naming, NamingState, NewNode, Renaming}, + file::{ + Duplicating, FileNodeItem, FileNodeViewKind, Naming, NamingState, NewNode, + Renaming, + }, proxy::ProxyResponse, }; @@ -51,6 +54,7 @@ pub struct FileExplorerData { pub common: Rc, pub scroll_to_line: RwSignal>, left_diff_path: RwSignal>, + pub select: RwSignal>, } impl KeyPressFocus for FileExplorerData { @@ -131,6 +135,7 @@ impl FileExplorerData { common, scroll_to_line: cx.create_rw_signal(None), left_diff_path: cx.create_rw_signal(None), + select: cx.create_rw_signal(None), }; if data.common.workspace.path.is_some() { // only fill in the child files if there is open folder @@ -448,7 +453,8 @@ impl FileExplorerData { let (found, line) = self.root.with_untracked(|x| x.find_file_at_line(&path)); if found { - self.scroll_to_line.set(Some(line)) + self.scroll_to_line.set(Some(line)); + self.select.set(Some(FileNodeViewKind::Path(path))); } } } diff --git a/lapce-app/src/file_explorer/view.rs b/lapce-app/src/file_explorer/view.rs index 92183a7810..e146e4ba9c 100644 --- a/lapce-app/src/file_explorer/view.rs +++ b/lapce-app/src/file_explorer/view.rs @@ -286,6 +286,7 @@ fn file_explorer_view( let config = data.common.config; let naming = data.naming; let scroll_to_line = data.scroll_to_line; + let select = data.select; let secondary_click_data = data.clone(); scroll( @@ -370,29 +371,46 @@ fn file_explorer_view( }, file_node_text_view(data, node, source_control.clone()), )) - .style(move |s| { - s.padding_right(15.0) - .min_width_full() - .padding_left((level * 10) as f32) - .align_items(AlignItems::Center) - .hover(|s| { - s.background( - config - .get() - .color(LapceColor::PANEL_HOVERED_BACKGROUND), + .style({ + let kind = kind.clone(); + move |s| { + s.padding_right(15.0) + .min_width_full() + .padding_left((level * 10) as f32) + .align_items(AlignItems::Center) + .hover(|s| { + s.background( + config + .get() + .color(LapceColor::PANEL_HOVERED_BACKGROUND), + ) + .cursor(CursorStyle::Pointer) + }) + .apply_if( + select.get().map(|x| x == kind).unwrap_or_default(), + |x| { + x.background( + config.get().color( + LapceColor::PANEL_HOVERED_BACKGROUND, + ), + ) + }, ) - .cursor(CursorStyle::Pointer) - }) + } }); // Only handle click events if we are not naming the file node - if let FileNodeViewKind::Path(path) = kind { + if let FileNodeViewKind::Path(path) = &kind { let click_path = path.clone(); let double_click_path = path.clone(); let secondary_click_path = path.clone(); - let aux_click_path = path; - view.on_click_stop(move |_| { - click_data.click(&click_path); + let aux_click_path = path.clone(); + view.on_click_stop({ + let kind = kind.clone(); + move |_| { + click_data.click(&click_path); + select.update(|x| *x = Some(kind.clone())); + } }) .on_double_click(move |_| { double_click_data.double_click(&double_click_path) From 5f58268c4a5a1cb78f5cfdf4c6344e353a5b4c77 Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Tue, 13 Aug 2024 20:07:52 +0100 Subject: [PATCH 18/69] reveal file in explorer centered --- lapce-app/src/file_explorer/view.rs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/lapce-app/src/file_explorer/view.rs b/lapce-app/src/file_explorer/view.rs index e146e4ba9c..7304705d44 100644 --- a/lapce-app/src/file_explorer/view.rs +++ b/lapce-app/src/file_explorer/view.rs @@ -2,6 +2,7 @@ use std::{path::Path, rc::Rc, sync::Arc}; use floem::{ event::{Event, EventListener}, + kurbo::Rect, peniko::Color, reactive::{create_rw_signal, ReadSignal, RwSignal}, style::{AlignItems, CursorStyle, Position, Style}, @@ -288,6 +289,7 @@ fn file_explorer_view( let scroll_to_line = data.scroll_to_line; let select = data.select; let secondary_click_data = data.clone(); + let scroll_rect = create_rw_signal(Rect::ZERO); scroll( virtual_stack( @@ -391,7 +393,7 @@ fn file_explorer_view( |x| { x.background( config.get().color( - LapceColor::PANEL_HOVERED_BACKGROUND, + LapceColor::PANEL_CURRENT_BACKGROUND, ), ) }, @@ -443,10 +445,19 @@ fn file_explorer_view( } } }) + .on_resize(move |rect| { + scroll_rect.set(rect); + }) .scroll_to(move || { if let Some(line) = scroll_to_line.get() { - let line_height = ui_line_height.get(); - Some((0.0, line * line_height).into()) + let line_height = ui_line_height.get_untracked(); + Some( + ( + 0.0, + line * line_height - scroll_rect.get_untracked().height() / 2.0, + ) + .into(), + ) } else { None } From 81f38382492a26e57ecc01ac20cea9553704e2b8 Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Thu, 15 Aug 2024 00:35:52 +0800 Subject: [PATCH 19/69] By default, open the parent directory. (#3439) --- lapce-app/src/window_tab.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lapce-app/src/window_tab.rs b/lapce-app/src/window_tab.rs index 0fb5c577cd..d5fc93b1e6 100644 --- a/lapce-app/src/window_tab.rs +++ b/lapce-app/src/window_tab.rs @@ -684,7 +684,12 @@ impl WindowTabData { OpenFolder => { if !self.workspace.kind.is_remote() { let window_command = self.common.window_common.window_command; - let options = FileDialogOptions::new().select_directories(); + let mut options = FileDialogOptions::new().select_directories(); + options = if let Some(parent) = self.workspace.path.as_ref().and_then(|x| x.parent()) { + options.force_starting_directory(parent) + } else { + options + }; open_file(options, move |file| { if let Some(mut file) = file { let workspace = LapceWorkspace { From 1f22a05026a170626f8641d1c49cef664d7cb021 Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Thu, 15 Aug 2024 03:17:33 +0800 Subject: [PATCH 20/69] add "Reveal in File Explorer" to right_click of editor (#3437) --- lapce-app/src/command.rs | 4 ++++ lapce-app/src/editor.rs | 3 +++ lapce-app/src/window_tab.rs | 18 ++++++++++++++++++ 3 files changed, 25 insertions(+) diff --git a/lapce-app/src/command.rs b/lapce-app/src/command.rs index aad6553df2..f3303c6c65 100644 --- a/lapce-app/src/command.rs +++ b/lapce-app/src/command.rs @@ -191,6 +191,10 @@ pub enum LapceWorkbenchCommand { #[strum(message = "Reveal in File Tree")] RevealInFileTree, + #[strum(serialize = "reveal_in_file_explorer")] + #[strum(message = "Reveal in File Explorer")] + RevealInFileExplorer, + #[strum(serialize = "run_in_terminal")] #[strum(message = "Run in Terminal")] RunInTerminal, diff --git a/lapce-app/src/editor.rs b/lapce-app/src/editor.rs index 9dedc66b32..4029973269 100644 --- a/lapce-app/src/editor.rs +++ b/lapce-app/src/editor.rs @@ -2746,6 +2746,9 @@ impl EditorData { Some(CommandKind::Workbench( LapceWorkbenchCommand::RevealInFileTree, )), + Some(CommandKind::Workbench( + LapceWorkbenchCommand::RevealInFileExplorer, + )), Some(CommandKind::Workbench( LapceWorkbenchCommand::PaletteCommand, )), diff --git a/lapce-app/src/window_tab.rs b/lapce-app/src/window_tab.rs index d5fc93b1e6..70798c265c 100644 --- a/lapce-app/src/window_tab.rs +++ b/lapce-app/src/window_tab.rs @@ -1392,6 +1392,24 @@ impl WindowTabData { } } } + RevealInFileExplorer => { + if let Some(editor_data) = + self.main_split.active_editor.get_untracked() + { + if let DocContent::File {path, ..} = editor_data.doc().content.get_untracked() { + let path = path.parent().unwrap_or(&path); + if !path.exists() { + return; + } + if let Err(err) = open::that(path) { + error!( + "Failed to reveal file in system file explorer: {}", + err + ); + } + } + } + } ShowCallHierarchy => { if let Some(editor_data) = self.main_split.active_editor.get_untracked() From 9ca4a99a9e7c226d026628a755f6a67309cefe17 Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Wed, 14 Aug 2024 20:30:46 +0100 Subject: [PATCH 21/69] some style changes --- lapce-app/src/command.rs | 14 ++++++++++---- lapce-app/src/editor.rs | 14 ++++++-------- lapce-app/src/file_explorer/data.rs | 30 +++++++++++++++-------------- lapce-app/src/window_tab.rs | 2 +- 4 files changed, 33 insertions(+), 27 deletions(-) diff --git a/lapce-app/src/command.rs b/lapce-app/src/command.rs index f3303c6c65..b4bafd768c 100644 --- a/lapce-app/src/command.rs +++ b/lapce-app/src/command.rs @@ -187,12 +187,18 @@ pub enum LapceWorkbenchCommand { #[strum(message = "Show Call Hierarchy")] ShowCallHierarchy, - #[strum(serialize = "reveal_in_file_tree")] - #[strum(message = "Reveal in File Tree")] - RevealInFileTree, + #[strum(serialize = "reveal_in_panel")] + #[strum(message = "Reveal in Panel")] + RevealInPanel, + #[cfg(not(target_os = "macos"))] #[strum(serialize = "reveal_in_file_explorer")] - #[strum(message = "Reveal in File Explorer")] + #[strum(message = "Reveal in System File Explorer")] + RevealInFileExplorer, + + #[cfg(target_os = "macos")] + #[strum(serialize = "reveal_in_file_explorer")] + #[strum(message = "Reveal in Finder")] RevealInFileExplorer, #[strum(serialize = "run_in_terminal")] diff --git a/lapce-app/src/editor.rs b/lapce-app/src/editor.rs index 4029973269..76d68fab04 100644 --- a/lapce-app/src/editor.rs +++ b/lapce-app/src/editor.rs @@ -2736,23 +2736,21 @@ impl EditorData { Some(CommandKind::Workbench( LapceWorkbenchCommand::ShowCallHierarchy, )), - None, Some(CommandKind::Focus(FocusCommand::Rename)), + Some(CommandKind::Workbench(LapceWorkbenchCommand::RunInTerminal)), + None, + Some(CommandKind::Workbench(LapceWorkbenchCommand::RevealInPanel)), + Some(CommandKind::Workbench( + LapceWorkbenchCommand::RevealInFileExplorer, + )), None, Some(CommandKind::Edit(EditCommand::ClipboardCut)), Some(CommandKind::Edit(EditCommand::ClipboardCopy)), Some(CommandKind::Edit(EditCommand::ClipboardPaste)), None, - Some(CommandKind::Workbench( - LapceWorkbenchCommand::RevealInFileTree, - )), - Some(CommandKind::Workbench( - LapceWorkbenchCommand::RevealInFileExplorer, - )), Some(CommandKind::Workbench( LapceWorkbenchCommand::PaletteCommand, )), - Some(CommandKind::Workbench(LapceWorkbenchCommand::RunInTerminal)), ] } else { vec![ diff --git a/lapce-app/src/file_explorer/data.rs b/lapce-app/src/file_explorer/data.rs index 5a3d2bf172..44a98a688d 100644 --- a/lapce-app/src/file_explorer/data.rs +++ b/lapce-app/src/file_explorer/data.rs @@ -546,21 +546,23 @@ impl FileExplorerData { // TODO: there are situations where we can open the file explorer to remote files if !common.workspace.kind.is_remote() { let path = path_a.clone(); - menu = menu.entry(MenuItem::new("Reveal in file explorer").action( - move || { - let path = path.parent().unwrap_or(&path); - if !path.exists() { - return; - } + #[cfg(not(target_os = "macos"))] + let title = "Reveal in system file explorer"; + #[cfg(target_os = "macos")] + let title = "Reveal in Finder"; + menu = menu.entry(MenuItem::new(title).action(move || { + let path = path.parent().unwrap_or(&path); + if !path.exists() { + return; + } - if let Err(err) = open::that(path) { - tracing::error!( - "Failed to reveal file in system file explorer: {}", - err - ); - } - }, - )); + if let Err(err) = open::that(path) { + tracing::error!( + "Failed to reveal file in system file explorer: {}", + err + ); + } + })); } if !is_workspace { diff --git a/lapce-app/src/window_tab.rs b/lapce-app/src/window_tab.rs index 70798c265c..49895a31bc 100644 --- a/lapce-app/src/window_tab.rs +++ b/lapce-app/src/window_tab.rs @@ -1378,7 +1378,7 @@ impl WindowTabData { Quit => { floem::quit_app(); } - RevealInFileTree => { + RevealInPanel => { if let Some(editor_data) = self.main_split.active_editor.get_untracked() { From 30ebe951d581496176a4e4930d4ba3909e10e8e9 Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Wed, 21 Aug 2024 21:05:01 +0100 Subject: [PATCH 22/69] bump to latest floem --- Cargo.lock | 12 ++++++------ Cargo.toml | 4 ++-- lapce-app/src/about.rs | 2 +- lapce-app/src/alert.rs | 2 +- lapce-app/src/app.rs | 18 +++++++++--------- lapce-app/src/code_action.rs | 2 +- lapce-app/src/completion.rs | 2 +- lapce-app/src/db.rs | 2 +- lapce-app/src/debug.rs | 2 +- lapce-app/src/doc.rs | 4 +++- lapce-app/src/editor.rs | 9 +++++++-- lapce-app/src/editor/diff.rs | 2 +- lapce-app/src/editor/gutter.rs | 2 +- lapce-app/src/editor/view.rs | 7 ++++--- lapce-app/src/editor_tab.rs | 5 ++++- lapce-app/src/file_explorer/data.rs | 2 +- lapce-app/src/file_explorer/view.rs | 4 +++- lapce-app/src/find.rs | 2 +- lapce-app/src/global_search.rs | 2 +- lapce-app/src/inline_completion.rs | 2 +- lapce-app/src/keymap.rs | 2 +- lapce-app/src/keypress.rs | 2 +- lapce-app/src/listener.rs | 2 +- lapce-app/src/main_split.rs | 2 +- lapce-app/src/palette.rs | 5 ++++- lapce-app/src/panel/call_hierarchy_view.rs | 2 +- lapce-app/src/panel/data.rs | 4 +++- lapce-app/src/panel/debug_view.rs | 4 +++- lapce-app/src/panel/document_symbol.rs | 2 +- lapce-app/src/panel/global_search_view.rs | 2 +- lapce-app/src/panel/plugin_view.rs | 14 +++++++------- lapce-app/src/panel/problem_view.rs | 5 ++++- lapce-app/src/panel/source_control_view.rs | 2 +- lapce-app/src/panel/terminal_view.rs | 2 +- lapce-app/src/panel/view.rs | 4 +++- lapce-app/src/plugin.rs | 1 + lapce-app/src/rename.rs | 2 +- lapce-app/src/settings.rs | 2 +- lapce-app/src/source_control.rs | 2 +- lapce-app/src/status.rs | 4 +++- lapce-app/src/terminal/data.rs | 2 +- lapce-app/src/terminal/panel.rs | 2 +- lapce-app/src/terminal/tab.rs | 2 +- lapce-app/src/terminal/view.rs | 2 +- lapce-app/src/text_area.rs | 4 +++- lapce-app/src/text_input.rs | 2 +- lapce-app/src/title.rs | 4 +++- lapce-app/src/window.rs | 5 ++++- lapce-app/src/window_tab.rs | 5 ++++- 49 files changed, 109 insertions(+), 71 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 22a6965a81..abe1afb2f8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1684,7 +1684,7 @@ checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" [[package]] name = "floem" version = "0.1.1" -source = "git+https://github.com/lapce/floem?rev=3a974c9bbc0c1dfefc17affb976ea8e9ae31369b#3a974c9bbc0c1dfefc17affb976ea8e9ae31369b" +source = "git+https://github.com/lapce/floem?rev=ba6ca44c01044ddf45c9a7985d5dfe4e7942fe64#ba6ca44c01044ddf45c9a7985d5dfe4e7942fe64" dependencies = [ "bitflags 2.6.0", "copypasta", @@ -1721,7 +1721,7 @@ dependencies = [ [[package]] name = "floem-editor-core" version = "0.1.1" -source = "git+https://github.com/lapce/floem?rev=3a974c9bbc0c1dfefc17affb976ea8e9ae31369b#3a974c9bbc0c1dfefc17affb976ea8e9ae31369b" +source = "git+https://github.com/lapce/floem?rev=ba6ca44c01044ddf45c9a7985d5dfe4e7942fe64#ba6ca44c01044ddf45c9a7985d5dfe4e7942fe64" dependencies = [ "bitflags 2.6.0", "itertools 0.12.1", @@ -1798,7 +1798,7 @@ dependencies = [ [[package]] name = "floem_reactive" version = "0.1.1" -source = "git+https://github.com/lapce/floem?rev=3a974c9bbc0c1dfefc17affb976ea8e9ae31369b#3a974c9bbc0c1dfefc17affb976ea8e9ae31369b" +source = "git+https://github.com/lapce/floem?rev=ba6ca44c01044ddf45c9a7985d5dfe4e7942fe64#ba6ca44c01044ddf45c9a7985d5dfe4e7942fe64" dependencies = [ "smallvec", ] @@ -1806,7 +1806,7 @@ dependencies = [ [[package]] name = "floem_renderer" version = "0.1.1" -source = "git+https://github.com/lapce/floem?rev=3a974c9bbc0c1dfefc17affb976ea8e9ae31369b#3a974c9bbc0c1dfefc17affb976ea8e9ae31369b" +source = "git+https://github.com/lapce/floem?rev=ba6ca44c01044ddf45c9a7985d5dfe4e7942fe64#ba6ca44c01044ddf45c9a7985d5dfe4e7942fe64" dependencies = [ "cosmic-text", "image", @@ -1819,7 +1819,7 @@ dependencies = [ [[package]] name = "floem_tiny_skia_renderer" version = "0.1.1" -source = "git+https://github.com/lapce/floem?rev=3a974c9bbc0c1dfefc17affb976ea8e9ae31369b#3a974c9bbc0c1dfefc17affb976ea8e9ae31369b" +source = "git+https://github.com/lapce/floem?rev=ba6ca44c01044ddf45c9a7985d5dfe4e7942fe64#ba6ca44c01044ddf45c9a7985d5dfe4e7942fe64" dependencies = [ "anyhow", "bytemuck", @@ -1836,7 +1836,7 @@ dependencies = [ [[package]] name = "floem_vger_renderer" version = "0.1.1" -source = "git+https://github.com/lapce/floem?rev=3a974c9bbc0c1dfefc17affb976ea8e9ae31369b#3a974c9bbc0c1dfefc17affb976ea8e9ae31369b" +source = "git+https://github.com/lapce/floem?rev=ba6ca44c01044ddf45c9a7985d5dfe4e7942fe64#ba6ca44c01044ddf45c9a7985d5dfe4e7942fe64" dependencies = [ "anyhow", "floem-vger", diff --git a/Cargo.toml b/Cargo.toml index 28ddba1ae6..638b10af2b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -76,9 +76,9 @@ lapce-core = { path = "./lapce-core" } lapce-rpc = { path = "./lapce-rpc" } lapce-proxy = { path = "./lapce-proxy" } -floem = { git = "https://github.com/lapce/floem", rev = "3a974c9bbc0c1dfefc17affb976ea8e9ae31369b", features = ["editor", "serde", "default-image-formats", "rfd-async-std"] } +floem = { git = "https://github.com/lapce/floem", rev = "ba6ca44c01044ddf45c9a7985d5dfe4e7942fe64", 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 = "3a974c9bbc0c1dfefc17affb976ea8e9ae31369b", features = ["serde"] } +floem-editor-core = { git = "https://github.com/lapce/floem", rev = "ba6ca44c01044ddf45c9a7985d5dfe4e7942fe64", features = ["serde"] } # floem-editor-core = { path = "../floem/editor-core/", features = ["serde"] } [patch.crates-io] diff --git a/lapce-app/src/about.rs b/lapce-app/src/about.rs index 7a3c47b913..a800a99ad3 100644 --- a/lapce-app/src/about.rs +++ b/lapce-app/src/about.rs @@ -3,7 +3,7 @@ use std::rc::Rc; use floem::{ event::EventListener, keyboard::Modifiers, - reactive::{RwSignal, Scope}, + reactive::{RwSignal, Scope, SignalGet, SignalUpdate}, style::{CursorStyle, Display, Position}, views::{container, label, stack, svg, Decorators}, View, diff --git a/lapce-app/src/alert.rs b/lapce-app/src/alert.rs index c56f32eb8b..8e2b7ac853 100644 --- a/lapce-app/src/alert.rs +++ b/lapce-app/src/alert.rs @@ -6,7 +6,7 @@ use std::{ use floem::{ event::EventListener, - reactive::{ReadSignal, RwSignal, Scope}, + reactive::{ReadSignal, RwSignal, Scope, SignalGet, SignalUpdate}, style::CursorStyle, views::{container, dyn_stack, label, stack, svg, Decorators}, View, diff --git a/lapce-app/src/app.rs b/lapce-app/src/app.rs index b9e6a2a7d6..024e5ff39e 100644 --- a/lapce-app/src/app.rs +++ b/lapce-app/src/app.rs @@ -23,7 +23,7 @@ use floem::{ }, reactive::{ create_effect, create_memo, create_rw_signal, provide_context, use_context, - ReadSignal, RwSignal, Scope, + ReadSignal, RwSignal, Scope, SignalGet, SignalUpdate, SignalWith, }, style::{ AlignItems, CursorStyle, Display, FlexDirection, JustifyContent, Position, @@ -38,9 +38,7 @@ use floem::{ views::{ clip, container, drag_resize_window_area, drag_window_area, dyn_stack, empty, label, rich_text, - scroll::{ - scroll, HideBar, PropagatePointerWheel, VerticalScrollAsHorizontal, - }, + scroll::{scroll, PropagatePointerWheel, VerticalScrollAsHorizontal}, stack, svg, tab, text, tooltip, virtual_stack, Decorators, VirtualDirection, VirtualItemSize, VirtualVector, }, @@ -1055,9 +1053,9 @@ fn editor_tab_header( .with_untracked(|editor_tab| editor_tab.children[active].1) .get_untracked() }) + .scroll_style(|s| s.hide_bars(true)) .style(|s| { - s.set(HideBar, true) - .set(VerticalScrollAsHorizontal, true) + s.set(VerticalScrollAsHorizontal, true) .absolute() .size_full() }), @@ -3624,7 +3622,11 @@ fn window(window_data: WindowData) -> impl View { } pub fn launch() { - logging::panic_hook(); + let cli = Cli::parse(); + + if !cli.wait { + logging::panic_hook(); + } let (reload_handle, _guard) = logging::logging(); trace!(TraceLevel::INFO, "Starting up Lapce.."); @@ -3660,8 +3662,6 @@ pub fn launch() { load_shell_env(); } - let cli = Cli::parse(); - // small hack to unblock terminal if launched from it // launch it as a separate process that waits if !cli.wait { diff --git a/lapce-app/src/code_action.rs b/lapce-app/src/code_action.rs index 0db20e3d17..f3b93903ff 100644 --- a/lapce-app/src/code_action.rs +++ b/lapce-app/src/code_action.rs @@ -3,7 +3,7 @@ use std::rc::Rc; use floem::{ keyboard::Modifiers, peniko::kurbo::Rect, - reactive::{RwSignal, Scope}, + reactive::{RwSignal, Scope, SignalGet, SignalUpdate}, }; use lapce_core::{command::FocusCommand, mode::Mode, movement::Movement}; use lapce_rpc::plugin::PluginId; diff --git a/lapce-app/src/completion.rs b/lapce-app/src/completion.rs index b71cfe1dae..201612651e 100644 --- a/lapce-app/src/completion.rs +++ b/lapce-app/src/completion.rs @@ -2,7 +2,7 @@ use std::{borrow::Cow, path::PathBuf, str::FromStr, sync::Arc}; use floem::{ peniko::kurbo::Rect, - reactive::{ReadSignal, RwSignal, Scope}, + reactive::{ReadSignal, RwSignal, Scope, SignalGet, SignalUpdate, SignalWith}, views::editor::{id::EditorId, text::Document}, }; use lapce_core::{ diff --git a/lapce-app/src/db.rs b/lapce-app/src/db.rs index 1ed885931f..05bb1cf0ab 100644 --- a/lapce-app/src/db.rs +++ b/lapce-app/src/db.rs @@ -6,7 +6,7 @@ use std::{ use anyhow::{anyhow, Result}; use crossbeam_channel::{unbounded, Sender}; -use floem::peniko::kurbo::Vec2; +use floem::{peniko::kurbo::Vec2, reactive::SignalGet}; use lapce_core::directory::Directory; use lapce_rpc::plugin::VoltID; use sha2::{Digest, Sha256}; diff --git a/lapce-app/src/debug.rs b/lapce-app/src/debug.rs index 71aebe827b..a213af5b79 100644 --- a/lapce-app/src/debug.rs +++ b/lapce-app/src/debug.rs @@ -8,7 +8,7 @@ use std::{ use floem::{ ext_event::create_ext_action, - reactive::{Memo, RwSignal, Scope}, + reactive::{Memo, RwSignal, Scope, SignalGet, SignalUpdate, SignalWith}, views::VirtualVector, }; use lapce_rpc::{ diff --git a/lapce-app/src/doc.rs b/lapce-app/src/doc.rs index b733036af9..3369db3d3a 100644 --- a/lapce-app/src/doc.rs +++ b/lapce-app/src/doc.rs @@ -17,7 +17,9 @@ use floem::{ ext_event::create_ext_action, keyboard::Modifiers, peniko::Color, - reactive::{batch, ReadSignal, RwSignal, Scope}, + reactive::{ + batch, ReadSignal, RwSignal, Scope, SignalGet, SignalUpdate, SignalWith, + }, text::{Attrs, AttrsList, FamilyOwned, TextLayout}, views::editor::{ actions::CommonAction, diff --git a/lapce-app/src/editor.rs b/lapce-app/src/editor.rs index 76d68fab04..882ee3664e 100644 --- a/lapce-app/src/editor.rs +++ b/lapce-app/src/editor.rs @@ -13,7 +13,10 @@ use floem::{ kurbo::{Point, Rect, Vec2}, menu::{Menu, MenuItem}, pointer::{PointerButton, PointerInputEvent, PointerMoveEvent}, - reactive::{batch, use_context, ReadSignal, RwSignal, Scope}, + reactive::{ + batch, use_context, ReadSignal, RwSignal, Scope, SignalGet, SignalUpdate, + SignalWith, + }, views::editor::{ command::CommandExecuted, id::EditorId, @@ -766,7 +769,9 @@ impl EditorData { self.cancel_completion(); } FocusCommand::SplitVertical => { - if let Some(editor_tab_id) = self.editor_tab_id.get_untracked() { + if let Some(editor_tab_id) = + self.editor_tab_id.read_only().get_untracked() + { self.common.internal_command.send(InternalCommand::Split { direction: SplitDirection::Vertical, editor_tab_id, diff --git a/lapce-app/src/editor/diff.rs b/lapce-app/src/editor/diff.rs index 5af8d9a919..e4f8152b0a 100644 --- a/lapce-app/src/editor/diff.rs +++ b/lapce-app/src/editor/diff.rs @@ -3,7 +3,7 @@ use std::{rc::Rc, sync::atomic}; use floem::{ event::EventListener, ext_event::create_ext_action, - reactive::{RwSignal, Scope}, + reactive::{RwSignal, Scope, SignalGet, SignalUpdate, SignalWith}, style::CursorStyle, views::{ clip, dyn_stack, editor::id::EditorId, empty, label, stack, svg, Decorators, diff --git a/lapce-app/src/editor/gutter.rs b/lapce-app/src/editor/gutter.rs index 373ab81de1..d75183aa68 100644 --- a/lapce-app/src/editor/gutter.rs +++ b/lapce-app/src/editor/gutter.rs @@ -1,7 +1,7 @@ use floem::{ context::PaintCx, peniko::kurbo::{Point, Rect, Size}, - reactive::Memo, + reactive::{Memo, SignalGet, SignalWith}, text::{Attrs, AttrsList, FamilyOwned, TextLayout}, Renderer, View, ViewId, }; diff --git a/lapce-app/src/editor/view.rs b/lapce-app/src/editor/view.rs index 0f249822a2..ab4c1467e0 100644 --- a/lapce-app/src/editor/view.rs +++ b/lapce-app/src/editor/view.rs @@ -11,6 +11,7 @@ use floem::{ }, reactive::{ create_effect, create_memo, create_rw_signal, Memo, ReadSignal, RwSignal, + SignalGet, SignalUpdate, SignalWith, }, style::{CursorColor, CursorStyle, Style, TextColor}, taffy::prelude::NodeId, @@ -30,7 +31,7 @@ use floem::{ ShowIndentGuide, SmartTab, VisibleWhitespaceColor, WrapProp, }, empty, label, - scroll::{scroll, HideBar, PropagatePointerWheel}, + scroll::{scroll, PropagatePointerWheel}, stack, svg, Decorators, }, Renderer, View, ViewId, @@ -1897,9 +1898,9 @@ fn editor_breadcrumbs( doc.track(); Some(Point::new(3000.0, 0.0)) }) + .scroll_style(|s| s.hide_bars(true)) .style(move |s| { - s.set(HideBar, true) - .absolute() + s.absolute() .size_pct(100.0, 100.0) .border_bottom(1.0) .border_color(config.get().color(LapceColor::LAPCE_BORDER)) diff --git a/lapce-app/src/editor_tab.rs b/lapce-app/src/editor_tab.rs index 3ba7a96b09..0bfe7c0aea 100644 --- a/lapce-app/src/editor_tab.rs +++ b/lapce-app/src/editor_tab.rs @@ -9,7 +9,10 @@ use floem::{ kurbo::{Point, Rect}, Color, }, - reactive::{create_memo, create_rw_signal, Memo, ReadSignal, RwSignal, Scope}, + reactive::{ + create_memo, create_rw_signal, Memo, ReadSignal, RwSignal, Scope, SignalGet, + SignalUpdate, SignalWith, + }, views::editor::id::EditorId, }; use lapce_rpc::plugin::VoltID; diff --git a/lapce-app/src/file_explorer/data.rs b/lapce-app/src/file_explorer/data.rs index 44a98a688d..2c695e387f 100644 --- a/lapce-app/src/file_explorer/data.rs +++ b/lapce-app/src/file_explorer/data.rs @@ -12,7 +12,7 @@ use floem::{ ext_event::create_ext_action, keyboard::Modifiers, menu::{Menu, MenuItem}, - reactive::{RwSignal, Scope}, + reactive::{RwSignal, Scope, SignalGet, SignalUpdate, SignalWith}, views::editor::text::SystemClipboard, }; use globset::Glob; diff --git a/lapce-app/src/file_explorer/view.rs b/lapce-app/src/file_explorer/view.rs index 7304705d44..5b0b77bce3 100644 --- a/lapce-app/src/file_explorer/view.rs +++ b/lapce-app/src/file_explorer/view.rs @@ -4,7 +4,9 @@ use floem::{ event::{Event, EventListener}, kurbo::Rect, peniko::Color, - reactive::{create_rw_signal, ReadSignal, RwSignal}, + reactive::{ + create_rw_signal, ReadSignal, RwSignal, SignalGet, SignalUpdate, SignalWith, + }, style::{AlignItems, CursorStyle, Position, Style}, text::Style as FontStyle, views::{ diff --git a/lapce-app/src/find.rs b/lapce-app/src/find.rs index a723f501a8..111478996e 100644 --- a/lapce-app/src/find.rs +++ b/lapce-app/src/find.rs @@ -1,6 +1,6 @@ use std::cmp::{max, min}; -use floem::reactive::{RwSignal, Scope}; +use floem::reactive::{RwSignal, Scope, SignalGet, SignalUpdate, SignalWith}; use lapce_core::{ selection::{SelRegion, Selection}, word::WordCursor, diff --git a/lapce-app/src/global_search.rs b/lapce-app/src/global_search.rs index 41f0b0bf09..b94132972e 100644 --- a/lapce-app/src/global_search.rs +++ b/lapce-app/src/global_search.rs @@ -3,7 +3,7 @@ use std::{ops::Range, path::PathBuf, rc::Rc}; use floem::{ ext_event::create_ext_action, keyboard::Modifiers, - reactive::{Memo, RwSignal, Scope}, + reactive::{Memo, RwSignal, Scope, SignalGet, SignalUpdate, SignalWith}, views::VirtualVector, }; use indexmap::IndexMap; diff --git a/lapce-app/src/inline_completion.rs b/lapce-app/src/inline_completion.rs index fc4da549fa..da19a5d173 100644 --- a/lapce-app/src/inline_completion.rs +++ b/lapce-app/src/inline_completion.rs @@ -1,6 +1,6 @@ use std::{borrow::Cow, ops::Range, path::PathBuf, str::FromStr}; -use floem::reactive::{batch, RwSignal, Scope}; +use floem::reactive::{batch, RwSignal, Scope, SignalGet, SignalUpdate, SignalWith}; use lapce_core::{ buffer::{ rope_text::{RopeText, RopeTextRef}, diff --git a/lapce-app/src/keymap.rs b/lapce-app/src/keymap.rs index 2cc6b2c6bc..cc7057a599 100644 --- a/lapce-app/src/keymap.rs +++ b/lapce-app/src/keymap.rs @@ -4,7 +4,7 @@ use floem::{ event::{Event, EventListener}, reactive::{ create_effect, create_memo, create_rw_signal, Memo, ReadSignal, RwSignal, - Scope, + Scope, SignalGet, SignalUpdate, SignalWith, }, style::CursorStyle, views::{ diff --git a/lapce-app/src/keypress.rs b/lapce-app/src/keypress.rs index 3a14175073..3700dccc1c 100644 --- a/lapce-app/src/keypress.rs +++ b/lapce-app/src/keypress.rs @@ -10,7 +10,7 @@ use anyhow::Result; use floem::{ keyboard::{Key, KeyEvent, KeyEventExtModifierSupplement, Modifiers, NamedKey}, pointer::{PointerButton, PointerInputEvent}, - reactive::{RwSignal, Scope}, + reactive::{RwSignal, Scope, SignalUpdate, SignalWith}, }; use indexmap::IndexMap; use itertools::Itertools; diff --git a/lapce-app/src/listener.rs b/lapce-app/src/listener.rs index 813da30799..55e4fa74b8 100644 --- a/lapce-app/src/listener.rs +++ b/lapce-app/src/listener.rs @@ -1,4 +1,4 @@ -use floem::reactive::{RwSignal, Scope}; +use floem::reactive::{RwSignal, Scope, SignalGet, SignalUpdate}; /// A signal listener that receives 'events' from the outside and runs the callback. /// This is implemented using effects and normal rw signals. This should be used when it doesn't diff --git a/lapce-app/src/main_split.rs b/lapce-app/src/main_split.rs index 11c8e79a7b..8bf27d4af3 100644 --- a/lapce-app/src/main_split.rs +++ b/lapce-app/src/main_split.rs @@ -10,7 +10,7 @@ use floem::{ file::{FileDialogOptions, FileInfo}, keyboard::Modifiers, peniko::kurbo::{Point, Rect, Vec2}, - reactive::{Memo, RwSignal, Scope}, + reactive::{Memo, RwSignal, Scope, SignalGet, SignalUpdate, SignalWith}, views::editor::id::EditorId, }; use itertools::Itertools; diff --git a/lapce-app/src/palette.rs b/lapce-app/src/palette.rs index 1a5e549aed..92ddb6fa2a 100644 --- a/lapce-app/src/palette.rs +++ b/lapce-app/src/palette.rs @@ -15,7 +15,10 @@ use crossbeam_channel::{Receiver, Sender, TryRecvError}; use floem::{ ext_event::{create_ext_action, create_signal_from_channel}, keyboard::Modifiers, - reactive::{use_context, ReadSignal, RwSignal, Scope}, + reactive::{ + use_context, ReadSignal, RwSignal, Scope, SignalGet, SignalUpdate, + SignalWith, + }, }; use itertools::Itertools; use lapce_core::{ diff --git a/lapce-app/src/panel/call_hierarchy_view.rs b/lapce-app/src/panel/call_hierarchy_view.rs index 47934c38b9..8d90c6347b 100644 --- a/lapce-app/src/panel/call_hierarchy_view.rs +++ b/lapce-app/src/panel/call_hierarchy_view.rs @@ -1,7 +1,7 @@ use std::{ops::AddAssign, rc::Rc}; use floem::{ - reactive::RwSignal, + reactive::{RwSignal, SignalGet, SignalUpdate, SignalWith}, style::CursorStyle, views::{ container, empty, label, scroll, stack, svg, virtual_stack, Decorators, diff --git a/lapce-app/src/panel/data.rs b/lapce-app/src/panel/data.rs index 4aba1d9440..f984856909 100644 --- a/lapce-app/src/panel/data.rs +++ b/lapce-app/src/panel/data.rs @@ -2,7 +2,9 @@ use std::{rc::Rc, sync::Arc}; use floem::{ kurbo::Size, - reactive::{use_context, Memo, RwSignal, Scope}, + reactive::{ + use_context, Memo, RwSignal, Scope, SignalGet, SignalUpdate, SignalWith, + }, }; use serde::{Deserialize, Serialize}; diff --git a/lapce-app/src/panel/debug_view.rs b/lapce-app/src/panel/debug_view.rs index a88bc29088..4c796de4ef 100644 --- a/lapce-app/src/panel/debug_view.rs +++ b/lapce-app/src/panel/debug_view.rs @@ -3,7 +3,9 @@ use std::{rc::Rc, sync::Arc}; use floem::{ event::EventListener, peniko::Color, - reactive::{create_rw_signal, ReadSignal, RwSignal}, + reactive::{ + create_rw_signal, ReadSignal, RwSignal, SignalGet, SignalUpdate, SignalWith, + }, style::CursorStyle, text::Style as FontStyle, views::{ diff --git a/lapce-app/src/panel/document_symbol.rs b/lapce-app/src/panel/document_symbol.rs index 8c4e8b2f2f..6d887a64e4 100644 --- a/lapce-app/src/panel/document_symbol.rs +++ b/lapce-app/src/panel/document_symbol.rs @@ -2,7 +2,7 @@ use std::{ops::AddAssign, path::PathBuf, rc::Rc}; use floem::{ peniko::Color, - reactive::{RwSignal, Scope}, + reactive::{RwSignal, Scope, SignalGet, SignalUpdate, SignalWith}, style::CursorStyle, views::{ container, editor::id::Id, label, scroll, stack, svg, virtual_stack, diff --git a/lapce-app/src/panel/global_search_view.rs b/lapce-app/src/panel/global_search_view.rs index ccbbf0eb68..23636b011e 100644 --- a/lapce-app/src/panel/global_search_view.rs +++ b/lapce-app/src/panel/global_search_view.rs @@ -2,7 +2,7 @@ use std::{path::PathBuf, rc::Rc, sync::Arc}; use floem::{ event::EventListener, - reactive::ReadSignal, + reactive::{ReadSignal, SignalGet, SignalUpdate}, style::{CursorStyle, Style}, views::{ container, label, scroll, stack, svg, virtual_stack, Decorators, diff --git a/lapce-app/src/panel/plugin_view.rs b/lapce-app/src/panel/plugin_view.rs index 3315f3ddba..29ac62767d 100644 --- a/lapce-app/src/panel/plugin_view.rs +++ b/lapce-app/src/panel/plugin_view.rs @@ -3,13 +3,13 @@ use std::{ops::Range, rc::Rc}; use floem::{ event::EventListener, peniko::kurbo::{Point, Rect, Size}, - reactive::{create_memo, create_rw_signal, RwSignal}, + reactive::{ + create_memo, create_rw_signal, RwSignal, SignalGet, SignalUpdate, SignalWith, + }, style::CursorStyle, views::{ - container, dyn_container, img, label, - scroll::{scroll, HideBar}, - stack, svg, virtual_stack, Decorators, VirtualDirection, VirtualItemSize, - VirtualVector, + container, dyn_container, img, label, scroll::scroll, stack, svg, + virtual_stack, Decorators, VirtualDirection, VirtualItemSize, VirtualVector, }, IntoView, View, }; @@ -363,10 +363,10 @@ fn available_view(plugin: PluginData, core_rpc: CoreRpcHandler) -> impl View { .on_event_cont(EventListener::PointerDown, move |_| { focus.set(Focus::Panel(PanelKind::Plugin)); }) + .scroll_style(|s| s.hide_bars(true)) .style(move |s| { let config = config.get(); - s.set(HideBar, true) - .width_pct(100.0) + s.width_pct(100.0) .cursor(CursorStyle::Text) .items_center() .background(config.color(LapceColor::EDITOR_BACKGROUND)) diff --git a/lapce-app/src/panel/problem_view.rs b/lapce-app/src/panel/problem_view.rs index 1e413b7683..0bf51e8b65 100644 --- a/lapce-app/src/panel/problem_view.rs +++ b/lapce-app/src/panel/problem_view.rs @@ -2,7 +2,10 @@ use std::{path::PathBuf, rc::Rc, sync::Arc}; use floem::{ peniko::Color, - reactive::{create_effect, create_rw_signal, ReadSignal}, + reactive::{ + create_effect, create_rw_signal, ReadSignal, SignalGet, SignalUpdate, + SignalWith, + }, style::{CursorStyle, Style}, views::{container, dyn_stack, label, scroll, stack, svg, Decorators}, View, diff --git a/lapce-app/src/panel/source_control_view.rs b/lapce-app/src/panel/source_control_view.rs index e5b1d01a8b..7bb69e986c 100644 --- a/lapce-app/src/panel/source_control_view.rs +++ b/lapce-app/src/panel/source_control_view.rs @@ -5,7 +5,7 @@ use floem::{ event::{Event, EventListener}, menu::{Menu, MenuItem}, peniko::kurbo::Rect, - reactive::{create_memo, create_rw_signal}, + reactive::{create_memo, create_rw_signal, SignalGet, SignalUpdate, SignalWith}, style::{CursorStyle, Style}, views::{ container, dyn_stack, diff --git a/lapce-app/src/panel/terminal_view.rs b/lapce-app/src/panel/terminal_view.rs index 1be37f0ea2..d69d006556 100644 --- a/lapce-app/src/panel/terminal_view.rs +++ b/lapce-app/src/panel/terminal_view.rs @@ -5,7 +5,7 @@ use floem::{ event::{Event, EventListener, EventPropagation}, kurbo::Size, menu::{Menu, MenuItem}, - reactive::create_rw_signal, + reactive::{create_rw_signal, SignalGet, SignalUpdate, SignalWith}, views::{ container, dyn_stack, empty, label, scroll::{scroll, Thickness, VerticalScrollAsHorizontal}, diff --git a/lapce-app/src/panel/view.rs b/lapce-app/src/panel/view.rs index 4e7d370b31..050f29b113 100644 --- a/lapce-app/src/panel/view.rs +++ b/lapce-app/src/panel/view.rs @@ -3,7 +3,9 @@ use std::{rc::Rc, sync::Arc}; use floem::{ event::{Event, EventListener, EventPropagation}, kurbo::{Point, Size}, - reactive::{create_rw_signal, ReadSignal, RwSignal}, + reactive::{ + create_rw_signal, ReadSignal, RwSignal, SignalGet, SignalUpdate, SignalWith, + }, style::{CursorStyle, Style}, taffy::AlignItems, unit::PxPctAuto, diff --git a/lapce-app/src/plugin.rs b/lapce-app/src/plugin.rs index 7f3da3e0de..03a4c7ae14 100644 --- a/lapce-app/src/plugin.rs +++ b/lapce-app/src/plugin.rs @@ -13,6 +13,7 @@ use floem::{ menu::{Menu, MenuItem}, reactive::{ create_effect, create_memo, create_rw_signal, use_context, RwSignal, Scope, + SignalGet, SignalUpdate, SignalWith, }, style::CursorStyle, views::{ diff --git a/lapce-app/src/rename.rs b/lapce-app/src/rename.rs index 102c65802f..74943b43db 100644 --- a/lapce-app/src/rename.rs +++ b/lapce-app/src/rename.rs @@ -4,7 +4,7 @@ use floem::{ ext_event::create_ext_action, keyboard::Modifiers, peniko::kurbo::Rect, - reactive::{RwSignal, Scope}, + reactive::{RwSignal, Scope, SignalGet, SignalUpdate, SignalWith}, }; use lapce_core::{command::FocusCommand, mode::Mode, selection::Selection}; use lapce_rpc::proxy::ProxyResponse; diff --git a/lapce-app/src/settings.rs b/lapce-app/src/settings.rs index fe845827d5..a48f080be7 100644 --- a/lapce-app/src/settings.rs +++ b/lapce-app/src/settings.rs @@ -7,7 +7,7 @@ use floem::{ peniko::kurbo::{Point, Rect, Size}, reactive::{ create_effect, create_memo, create_rw_signal, Memo, ReadSignal, RwSignal, - Scope, + Scope, SignalGet, SignalUpdate, SignalWith, }, style::CursorStyle, text::{Attrs, AttrsList, FamilyOwned, TextLayout}, diff --git a/lapce-app/src/source_control.rs b/lapce-app/src/source_control.rs index 0da881b6dc..70d9e852ef 100644 --- a/lapce-app/src/source_control.rs +++ b/lapce-app/src/source_control.rs @@ -2,7 +2,7 @@ use std::{path::PathBuf, rc::Rc}; use floem::{ keyboard::Modifiers, - reactive::{RwSignal, Scope}, + reactive::{RwSignal, Scope, SignalWith}, }; use indexmap::IndexMap; use lapce_core::mode::Mode; diff --git a/lapce-app/src/status.rs b/lapce-app/src/status.rs index 31a6c31b49..7bc0376493 100644 --- a/lapce-app/src/status.rs +++ b/lapce-app/src/status.rs @@ -5,7 +5,9 @@ use std::{ use floem::{ event::EventPropagation, - reactive::{create_memo, Memo, ReadSignal, RwSignal}, + reactive::{ + create_memo, Memo, ReadSignal, RwSignal, SignalGet, SignalUpdate, SignalWith, + }, style::{AlignItems, CursorStyle, Display, FlexWrap}, views::{dyn_stack, label, stack, svg, Decorators}, View, diff --git a/lapce-app/src/terminal/data.rs b/lapce-app/src/terminal/data.rs index b7488cb3ee..a7c60b2054 100644 --- a/lapce-app/src/terminal/data.rs +++ b/lapce-app/src/terminal/data.rs @@ -10,7 +10,7 @@ use alacritty_terminal::{ use anyhow::anyhow; use floem::{ keyboard::{Key, KeyEvent, Modifiers, NamedKey}, - reactive::{RwSignal, Scope}, + reactive::{RwSignal, Scope, SignalGet, SignalUpdate}, views::editor::text::SystemClipboard, }; use lapce_core::{ diff --git a/lapce-app/src/terminal/panel.rs b/lapce-app/src/terminal/panel.rs index 817a1ca356..223ca9602a 100644 --- a/lapce-app/src/terminal/panel.rs +++ b/lapce-app/src/terminal/panel.rs @@ -2,7 +2,7 @@ use std::{collections::HashMap, path::PathBuf, rc::Rc, sync::Arc}; use floem::{ ext_event::create_ext_action, - reactive::{Memo, RwSignal, Scope}, + reactive::{Memo, RwSignal, Scope, SignalGet, SignalUpdate, SignalWith}, }; use lapce_core::mode::Mode; use lapce_rpc::{ diff --git a/lapce-app/src/terminal/tab.rs b/lapce-app/src/terminal/tab.rs index 5e66eb7d08..32214b77a3 100644 --- a/lapce-app/src/terminal/tab.rs +++ b/lapce-app/src/terminal/tab.rs @@ -1,6 +1,6 @@ use std::{rc::Rc, sync::Arc}; -use floem::reactive::{RwSignal, Scope}; +use floem::reactive::{RwSignal, Scope, SignalGet, SignalWith}; use lapce_rpc::terminal::TerminalProfile; use super::data::TerminalData; diff --git a/lapce-app/src/terminal/view.rs b/lapce-app/src/terminal/view.rs index f0f69c618a..3bee251484 100644 --- a/lapce-app/src/terminal/view.rs +++ b/lapce-app/src/terminal/view.rs @@ -14,7 +14,7 @@ use floem::{ Color, }, pointer::PointerInputEvent, - reactive::{create_effect, ReadSignal, RwSignal}, + reactive::{create_effect, ReadSignal, RwSignal, SignalGet, SignalWith}, text::{Attrs, AttrsList, FamilyOwned, TextLayout, Weight}, views::editor::{core::register::Clipboard, text::SystemClipboard}, Renderer, View, ViewId, diff --git a/lapce-app/src/text_area.rs b/lapce-app/src/text_area.rs index cb54e45a40..c9f89a3bfc 100644 --- a/lapce-app/src/text_area.rs +++ b/lapce-app/src/text_area.rs @@ -1,6 +1,8 @@ use floem::{ peniko::kurbo::Rect, - reactive::{create_effect, create_rw_signal}, + reactive::{ + create_effect, create_rw_signal, SignalGet, SignalUpdate, SignalWith, + }, text::{Attrs, AttrsList, LineHeightValue, TextLayout}, views::{container, label, rich_text, scroll, stack, Decorators}, View, diff --git a/lapce-app/src/text_input.rs b/lapce-app/src/text_input.rs index 05f9f85b9e..d49165cd29 100644 --- a/lapce-app/src/text_input.rs +++ b/lapce-app/src/text_input.rs @@ -11,7 +11,7 @@ use floem::{ prop_extractor, reactive::{ create_effect, create_memo, create_rw_signal, Memo, ReadSignal, RwSignal, - Scope, + Scope, SignalGet, SignalUpdate, SignalWith, }, style::{ CursorStyle, FontFamily, FontSize, FontStyle, FontWeight, LineHeight, diff --git a/lapce-app/src/title.rs b/lapce-app/src/title.rs index 60e3cdfdb7..287c79e636 100644 --- a/lapce-app/src/title.rs +++ b/lapce-app/src/title.rs @@ -4,7 +4,9 @@ use floem::{ event::EventListener, menu::{Menu, MenuItem}, peniko::Color, - reactive::{create_memo, Memo, ReadSignal, RwSignal}, + reactive::{ + create_memo, Memo, ReadSignal, RwSignal, SignalGet, SignalUpdate, SignalWith, + }, style::{AlignItems, CursorStyle, JustifyContent}, views::{container, drag_window_area, empty, label, stack, svg, Decorators}, View, diff --git a/lapce-app/src/window.rs b/lapce-app/src/window.rs index 9750ceb718..84bc83c553 100644 --- a/lapce-app/src/window.rs +++ b/lapce-app/src/window.rs @@ -3,7 +3,10 @@ use std::{path::PathBuf, rc::Rc, sync::Arc}; use floem::{ action::TimerToken, peniko::kurbo::{Point, Size}, - reactive::{use_context, Memo, ReadSignal, RwSignal, Scope}, + reactive::{ + use_context, Memo, ReadSignal, RwSignal, Scope, SignalGet, SignalUpdate, + SignalWith, + }, window::WindowId, ViewId, }; diff --git a/lapce-app/src/window_tab.rs b/lapce-app/src/window_tab.rs index 49895a31bc..51b928b581 100644 --- a/lapce-app/src/window_tab.rs +++ b/lapce-app/src/window_tab.rs @@ -16,7 +16,10 @@ use floem::{ keyboard::Modifiers, kurbo::Size, peniko::kurbo::{Point, Rect, Vec2}, - reactive::{use_context, Memo, ReadSignal, RwSignal, Scope, WriteSignal}, + reactive::{ + use_context, Memo, ReadSignal, RwSignal, Scope, SignalGet, SignalUpdate, + SignalWith, WriteSignal, + }, text::{Attrs, AttrsList, FamilyOwned, LineHeightValue, TextLayout}, ViewId, }; From 15958294e22c1e7fe883918c23cfaf2449a18fb4 Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Thu, 22 Aug 2024 20:31:09 +0100 Subject: [PATCH 23/69] bump floem to fix panic --- Cargo.lock | 12 ++++++------ Cargo.toml | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index abe1afb2f8..704bbab103 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1684,7 +1684,7 @@ checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" [[package]] name = "floem" version = "0.1.1" -source = "git+https://github.com/lapce/floem?rev=ba6ca44c01044ddf45c9a7985d5dfe4e7942fe64#ba6ca44c01044ddf45c9a7985d5dfe4e7942fe64" +source = "git+https://github.com/lapce/floem?rev=157631a49d6ba13a3467dcb994eb46a98c52eb76#157631a49d6ba13a3467dcb994eb46a98c52eb76" dependencies = [ "bitflags 2.6.0", "copypasta", @@ -1721,7 +1721,7 @@ dependencies = [ [[package]] name = "floem-editor-core" version = "0.1.1" -source = "git+https://github.com/lapce/floem?rev=ba6ca44c01044ddf45c9a7985d5dfe4e7942fe64#ba6ca44c01044ddf45c9a7985d5dfe4e7942fe64" +source = "git+https://github.com/lapce/floem?rev=157631a49d6ba13a3467dcb994eb46a98c52eb76#157631a49d6ba13a3467dcb994eb46a98c52eb76" dependencies = [ "bitflags 2.6.0", "itertools 0.12.1", @@ -1798,7 +1798,7 @@ dependencies = [ [[package]] name = "floem_reactive" version = "0.1.1" -source = "git+https://github.com/lapce/floem?rev=ba6ca44c01044ddf45c9a7985d5dfe4e7942fe64#ba6ca44c01044ddf45c9a7985d5dfe4e7942fe64" +source = "git+https://github.com/lapce/floem?rev=157631a49d6ba13a3467dcb994eb46a98c52eb76#157631a49d6ba13a3467dcb994eb46a98c52eb76" dependencies = [ "smallvec", ] @@ -1806,7 +1806,7 @@ dependencies = [ [[package]] name = "floem_renderer" version = "0.1.1" -source = "git+https://github.com/lapce/floem?rev=ba6ca44c01044ddf45c9a7985d5dfe4e7942fe64#ba6ca44c01044ddf45c9a7985d5dfe4e7942fe64" +source = "git+https://github.com/lapce/floem?rev=157631a49d6ba13a3467dcb994eb46a98c52eb76#157631a49d6ba13a3467dcb994eb46a98c52eb76" dependencies = [ "cosmic-text", "image", @@ -1819,7 +1819,7 @@ dependencies = [ [[package]] name = "floem_tiny_skia_renderer" version = "0.1.1" -source = "git+https://github.com/lapce/floem?rev=ba6ca44c01044ddf45c9a7985d5dfe4e7942fe64#ba6ca44c01044ddf45c9a7985d5dfe4e7942fe64" +source = "git+https://github.com/lapce/floem?rev=157631a49d6ba13a3467dcb994eb46a98c52eb76#157631a49d6ba13a3467dcb994eb46a98c52eb76" dependencies = [ "anyhow", "bytemuck", @@ -1836,7 +1836,7 @@ dependencies = [ [[package]] name = "floem_vger_renderer" version = "0.1.1" -source = "git+https://github.com/lapce/floem?rev=ba6ca44c01044ddf45c9a7985d5dfe4e7942fe64#ba6ca44c01044ddf45c9a7985d5dfe4e7942fe64" +source = "git+https://github.com/lapce/floem?rev=157631a49d6ba13a3467dcb994eb46a98c52eb76#157631a49d6ba13a3467dcb994eb46a98c52eb76" dependencies = [ "anyhow", "floem-vger", diff --git a/Cargo.toml b/Cargo.toml index 638b10af2b..687f7c77ff 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -76,9 +76,9 @@ lapce-core = { path = "./lapce-core" } lapce-rpc = { path = "./lapce-rpc" } lapce-proxy = { path = "./lapce-proxy" } -floem = { git = "https://github.com/lapce/floem", rev = "ba6ca44c01044ddf45c9a7985d5dfe4e7942fe64", features = ["editor", "serde", "default-image-formats", "rfd-async-std"] } +floem = { git = "https://github.com/lapce/floem", rev = "157631a49d6ba13a3467dcb994eb46a98c52eb76", 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 = "ba6ca44c01044ddf45c9a7985d5dfe4e7942fe64", features = ["serde"] } +floem-editor-core = { git = "https://github.com/lapce/floem", rev = "157631a49d6ba13a3467dcb994eb46a98c52eb76", features = ["serde"] } # floem-editor-core = { path = "../floem/editor-core/", features = ["serde"] } [patch.crates-io] From 8047100baf3be98a5c852289e77e758e52b7ce21 Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Fri, 23 Aug 2024 21:20:15 +0100 Subject: [PATCH 24/69] only cancel completion popup if scrolled vertically --- lapce-app/src/editor/view.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/lapce-app/src/editor/view.rs b/lapce-app/src/editor/view.rs index ab4c1467e0..5cab4b7dae 100644 --- a/lapce-app/src/editor/view.rs +++ b/lapce-app/src/editor/view.rs @@ -1955,6 +1955,8 @@ fn editor_content( }); } + let current_scroll = create_rw_signal(Rect::ZERO); + scroll({ let editor_content_view = editor_view(e_data.get_untracked(), debug_breakline, is_active).style( @@ -2002,10 +2004,14 @@ fn editor_content( .on_move(move |point| { window_origin.set(point); }) - .on_scroll(move |_| { - let e_data = e_data.get_untracked(); - e_data.cancel_completion(); - e_data.cancel_inline_completion(); + .on_scroll(move |rect| { + if rect.y0 != current_scroll.get_untracked().y0 { + // only cancel completion if scrolled vertically + let e_data = e_data.get_untracked(); + e_data.cancel_completion(); + e_data.cancel_inline_completion(); + } + current_scroll.set(rect); }) .scroll_to(move || scroll_to.get().map(|s| s.to_point())) .scroll_delta(move || scroll_delta.get()) From b618c25e1db20f16869312eda4b4a68a28c12c0a Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Sat, 24 Aug 2024 19:04:16 +0100 Subject: [PATCH 25/69] update CHANGELOG --- CHANGELOG.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a4a3c8306..6ba40c0e4a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,8 +5,10 @@ ### Features/Changes - Implement "Run in terminal" - Implement document symbols in a panel -- Implement 'Go To Location' functionality in the Diff editor. -- implement on screen find which is similar to `f` in vim but for the whole screen. +- Implement "Go To Location" functionality in the Diff editor. +- Implement on screen find which is similar to `f` in vim but for the whole screen. +- Make file explorer horizontal scrollable +- Implement "Reveal in system file explorer" ### Bug Fixes - Fix markdown syntax highlighting From 76ed075cd9932ebc24d20c36fbbf7d4a9b556d2c Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Sat, 24 Aug 2024 19:44:43 +0100 Subject: [PATCH 26/69] bump version to 0.4.2 --- CHANGELOG.md | 6 ++++++ Cargo.lock | 10 +++++----- Cargo.toml | 2 +- extra/linux/dev.lapce.lapce.metainfo.xml | 2 +- extra/macos/Lapce.app/Contents/Info.plist | 2 +- extra/windows/wix/lapce.wxs | 2 +- lapce.spec | 2 +- 7 files changed, 16 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ba40c0e4a..e265fe071c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ ## Unreleased +### Features/Changes + +### Bug Fixes + +## 0.4.2 + ### Features/Changes - Implement "Run in terminal" - Implement document symbols in a panel diff --git a/Cargo.lock b/Cargo.lock index 704bbab103..512e479805 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2904,7 +2904,7 @@ dependencies = [ [[package]] name = "lapce" -version = "0.4.1" +version = "0.4.2" dependencies = [ "lapce-app", "lapce-proxy", @@ -2912,7 +2912,7 @@ dependencies = [ [[package]] name = "lapce-app" -version = "0.4.1" +version = "0.4.2" dependencies = [ "Inflector", "alacritty_terminal", @@ -2976,7 +2976,7 @@ dependencies = [ [[package]] name = "lapce-core" -version = "0.4.1" +version = "0.4.2" dependencies = [ "ahash", "anyhow", @@ -3004,7 +3004,7 @@ dependencies = [ [[package]] name = "lapce-proxy" -version = "0.4.1" +version = "0.4.2" dependencies = [ "alacritty_terminal", "anyhow", @@ -3053,7 +3053,7 @@ dependencies = [ [[package]] name = "lapce-rpc" -version = "0.4.1" +version = "0.4.2" dependencies = [ "anyhow", "crossbeam-channel", diff --git a/Cargo.toml b/Cargo.toml index 687f7c77ff..b142f39dc7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ path = "lapce-proxy/src/bin/lapce-proxy.rs" members = ["lapce-app", "lapce-proxy", "lapce-rpc", "lapce-core"] [workspace.package] -version = "0.4.1" +version = "0.4.2" edition = "2021" rust-version = "1.77.0" license = "Apache-2.0" diff --git a/extra/linux/dev.lapce.lapce.metainfo.xml b/extra/linux/dev.lapce.lapce.metainfo.xml index 3c6ad2db59..2156280bdf 100644 --- a/extra/linux/dev.lapce.lapce.metainfo.xml +++ b/extra/linux/dev.lapce.lapce.metainfo.xml @@ -30,6 +30,6 @@ - + diff --git a/extra/macos/Lapce.app/Contents/Info.plist b/extra/macos/Lapce.app/Contents/Info.plist index 5896e12833..45b6321f10 100644 --- a/extra/macos/Lapce.app/Contents/Info.plist +++ b/extra/macos/Lapce.app/Contents/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.4.1 + 0.4.2 CFBundleSupportedPlatforms MacOSX diff --git a/extra/windows/wix/lapce.wxs b/extra/windows/wix/lapce.wxs index 305f835e22..dbc0890515 100644 --- a/extra/windows/wix/lapce.wxs +++ b/extra/windows/wix/lapce.wxs @@ -1,6 +1,6 @@ - + diff --git a/lapce.spec b/lapce.spec index 9996f3b8ca..767eedce40 100644 --- a/lapce.spec +++ b/lapce.spec @@ -1,5 +1,5 @@ Name: lapce-git -Version: 0.4.1.{{{ git_dir_version }}} +Version: 0.4.2.{{{ git_dir_version }}} Release: 1 Summary: Lightning-fast and Powerful Code Editor written in Rust License: Apache-2.0 From 5f07fc3334f6d5939947fe927a7750c4a67ee398 Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Tue, 27 Aug 2024 22:57:54 +0800 Subject: [PATCH 27/69] about dap: (#3456) 1. add some log 2. add seq field to response msg 3. support runInTerminal in Windows 4. Changed ConfigurationDone to an asynchronous request --- lapce-proxy/src/dispatch.rs | 8 ++++---- lapce-proxy/src/plugin/dap.rs | 14 +++++++++----- lapce-rpc/src/dap_types.rs | 1 + 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/lapce-proxy/src/dispatch.rs b/lapce-proxy/src/dispatch.rs index d27e397afe..32895d9527 100644 --- a/lapce-proxy/src/dispatch.rs +++ b/lapce-proxy/src/dispatch.rs @@ -177,12 +177,12 @@ impl ProxyHandler for Dispatcher { #[allow(unused)] let mut child_id = None; + #[cfg(target_os = "windows")] + { + child_id = terminal.pty.child_watcher().pid().map(|x| x.get()); + } #[cfg(not(target_os = "windows"))] { - // Alacritty currently doesn't expose the child process ID on windows, so this won't compile - // Alacritty does acquire this information, but it is discarded - // This is currently only used for debug adapter protocol's RunInTerminal request, which we - // specify isn't supported on Windows at the moment child_id = Some(terminal.pty.child().id()); } diff --git a/lapce-proxy/src/plugin/dap.rs b/lapce-proxy/src/plugin/dap.rs index ba22379048..7c71bce928 100644 --- a/lapce-proxy/src/plugin/dap.rs +++ b/lapce-proxy/src/plugin/dap.rs @@ -112,6 +112,7 @@ impl DapClient { thread::spawn(move || -> Result<()> { for msg in io_rx { if let Ok(msg) = serde_json::to_string(&msg) { + tracing::debug!("write to dap server: {}", msg); let msg = format!("Content-Length: {}\r\n\r\n{}", msg.len(), msg); writer.write_all(msg.as_bytes())?; @@ -128,6 +129,7 @@ impl DapClient { loop { match crate::plugin::lsp::read_message(&mut reader) { Ok(message_str) => { + tracing::debug!("read from dap server: {}", message_str); dap_rpc.handle_server_message(&message_str); } Err(_err) => { @@ -220,7 +222,11 @@ impl DapClient { } } // send dap configurations here - let _ = self.dap_rpc.request::(()); + self.dap_rpc.request_async::((), |rs| { + if let Err(e) = rs { + tracing::error!("request ConfigurationDone: {:?}", e) + } + }); } DapEvent::Stopped(stopped) => { let all_threads_stopped = @@ -313,10 +319,6 @@ impl DapClient { path_format: Some("path".to_owned()), supports_variable_type: Some(true), supports_variable_paging: Some(false), - // See comment on dispatch of `NewTerminal` - #[cfg(target_os = "windows")] - supports_run_in_terminal_request: Some(false), - #[cfg(not(target_os = "windows"))] supports_run_in_terminal_request: Some(true), supports_memory_references: Some(false), supports_progress_reporting: Some(false), @@ -449,7 +451,9 @@ impl DapRpcHandler { match msg { DapRpc::HostRequest(req) => { let result = dap_client.handle_host_request(&req); + let seq = self.seq_counter.fetch_add(1, Ordering::Relaxed); let resp = DapResponse { + seq, request_seq: req.seq, success: result.is_ok(), command: req.command.clone(), diff --git a/lapce-rpc/src/dap_types.rs b/lapce-rpc/src/dap_types.rs index bb4851fc51..ba26ef2804 100644 --- a/lapce-rpc/src/dap_types.rs +++ b/lapce-rpc/src/dap_types.rs @@ -74,6 +74,7 @@ pub struct DapRequest { #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)] pub struct DapResponse { + pub seq: u64, pub request_seq: u64, pub success: bool, pub command: String, From a983f0bddff9be40fd9ab54523a54ccd5cb27637 Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Wed, 28 Aug 2024 03:31:37 +0800 Subject: [PATCH 28/69] The double-click event restriction only takes effect at the top of the terminal. (#3442) --- lapce-app/src/panel/terminal_view.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lapce-app/src/panel/terminal_view.rs b/lapce-app/src/panel/terminal_view.rs index d69d006556..c35cd30b6b 100644 --- a/lapce-app/src/panel/terminal_view.rs +++ b/lapce-app/src/panel/terminal_view.rs @@ -38,12 +38,6 @@ pub fn terminal_panel(window_tab_data: Rc) -> impl View { focus.set(Focus::Panel(PanelKind::Terminal)); } }) - .on_double_click(move |_| { - window_tab_data - .panel - .toggle_maximize(&crate::panel::kind::PanelKind::Terminal); - EventPropagation::Stop - }) .style(|s| s.absolute().size_pct(100.0, 100.0).flex_col()) .debug_name("Terminal Panel") } @@ -249,6 +243,12 @@ fn terminal_tab_header(window_tab_data: Rc) -> impl View { header_height.set(size.height); } }) + .on_double_click(move |_| { + window_tab_data + .panel + .toggle_maximize(&crate::panel::kind::PanelKind::Terminal); + EventPropagation::Stop + }) .style(move |s| { let config = config.get(); s.width_pct(100.0) From c88a8a0a78ff4d2327e1367a622274a964c9f6f4 Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Thu, 29 Aug 2024 16:50:33 +0800 Subject: [PATCH 29/69] support codeLens/resolve of lsp (#3458) --- lapce-proxy/src/dispatch.rs | 16 ++++++++++++++++ lapce-proxy/src/plugin/mod.rs | 21 ++++++++++++++++++++- lapce-proxy/src/plugin/psp.rs | 8 +++++++- lapce-rpc/src/proxy.rs | 17 +++++++++++++++++ 4 files changed, 60 insertions(+), 2 deletions(-) diff --git a/lapce-proxy/src/dispatch.rs b/lapce-proxy/src/dispatch.rs index 32895d9527..e076798448 100644 --- a/lapce-proxy/src/dispatch.rs +++ b/lapce-proxy/src/dispatch.rs @@ -1073,6 +1073,22 @@ impl ProxyHandler for Dispatcher { proxy_rpc.handle_response(id, result); }); } + GetCodeLensResolve { code_lens, path } => { + let proxy_rpc = self.proxy_rpc.clone(); + self.catalog_rpc.get_code_lens_resolve( + &path, + &code_lens, + move |plugin_id, result| { + let result = result.map(|resp| { + ProxyResponse::GetCodeLensResolveResponse { + plugin_id, + resp, + } + }); + proxy_rpc.handle_response(id, result); + }, + ); + } } } } diff --git a/lapce-proxy/src/plugin/mod.rs b/lapce-proxy/src/plugin/mod.rs index 8b09527ccc..ca0d6d0a35 100644 --- a/lapce-proxy/src/plugin/mod.rs +++ b/lapce-proxy/src/plugin/mod.rs @@ -34,7 +34,7 @@ use lapce_xi_rope::{Rope, RopeDelta}; use lsp_types::{ request::{ CallHierarchyIncomingCalls, CallHierarchyPrepare, CodeActionRequest, - CodeActionResolveRequest, CodeLensRequest, Completion, + CodeActionResolveRequest, CodeLensRequest, CodeLensResolve, Completion, DocumentSymbolRequest, Formatting, GotoDefinition, GotoTypeDefinition, GotoTypeDefinitionParams, GotoTypeDefinitionResponse, HoverRequest, InlayHintRequest, InlineCompletionRequest, PrepareRenameRequest, References, @@ -739,6 +739,25 @@ impl PluginCatalogRpcHandler { ); } + pub fn get_code_lens_resolve( + &self, + path: &Path, + code_lens: &CodeLens, + cb: impl FnOnce(PluginId, Result) + Clone + Send + 'static, + ) { + let method = CodeLensResolve::METHOD; + let language_id = + Some(language_id_from_path(path).unwrap_or("").to_string()); + + self.send_request_to_all_plugins( + method, + code_lens, + language_id, + Some(path.to_path_buf()), + cb, + ); + } + pub fn get_inlay_hints( &self, path: &Path, diff --git a/lapce-proxy/src/plugin/psp.rs b/lapce-proxy/src/plugin/psp.rs index 7bf54e22af..c264f12717 100644 --- a/lapce-proxy/src/plugin/psp.rs +++ b/lapce-proxy/src/plugin/psp.rs @@ -30,7 +30,7 @@ use lsp_types::{ }, request::{ CallHierarchyIncomingCalls, CallHierarchyPrepare, CodeActionRequest, - CodeActionResolveRequest, CodeLensRequest, Completion, + CodeActionResolveRequest, CodeLensRequest, CodeLensResolve, Completion, DocumentSymbolRequest, Formatting, GotoDefinition, GotoTypeDefinition, HoverRequest, Initialize, InlayHintRequest, InlineCompletionRequest, PrepareRenameRequest, References, RegisterCapability, Rename, @@ -796,6 +796,12 @@ impl PluginHostHandler { CodeLensRequest::METHOD => { self.server_capabilities.code_lens_provider.is_some() } + CodeLensResolve::METHOD => self + .server_capabilities + .code_lens_provider + .as_ref() + .and_then(|x| x.resolve_provider) + .unwrap_or(false), CallHierarchyPrepare::METHOD => { self.server_capabilities.call_hierarchy_provider.is_some() } diff --git a/lapce-rpc/src/proxy.rs b/lapce-rpc/src/proxy.rs index 09c813d9f6..50473ebedd 100644 --- a/lapce-rpc/src/proxy.rs +++ b/lapce-rpc/src/proxy.rs @@ -146,6 +146,10 @@ pub enum ProxyRequest { GetCodeLens { path: PathBuf, }, + GetCodeLensResolve { + code_lens: CodeLens, + path: PathBuf, + }, GetDocumentSymbols { path: PathBuf, }, @@ -388,6 +392,10 @@ pub enum ProxyResponse { plugin_id: PluginId, resp: Option>, }, + GetCodeLensResolveResponse { + plugin_id: PluginId, + resp: CodeLens, + }, GetFilesResponse { items: Vec, }, @@ -924,6 +932,15 @@ impl ProxyRpcHandler { self.request_async(ProxyRequest::GetCodeLens { path }, f); } + pub fn get_code_lens_resolve( + &self, + code_lens: CodeLens, + path: PathBuf, + f: impl ProxyCallback + 'static, + ) { + self.request_async(ProxyRequest::GetCodeLensResolve { code_lens, path }, f); + } + pub fn get_document_formatting( &self, path: PathBuf, From f690ea7dee8b884ed739cdc34d178c7f05d3231c Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Mon, 2 Sep 2024 05:31:27 +0800 Subject: [PATCH 30/69] Ensure the line height is not too small. (#3459) --- lapce-app/src/keymap.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lapce-app/src/keymap.rs b/lapce-app/src/keymap.rs index cc7057a599..8d76e9623a 100644 --- a/lapce-app/src/keymap.rs +++ b/lapce-app/src/keymap.rs @@ -410,6 +410,7 @@ fn keyboard_picker_view( s.padding_horiz(5.0) .padding_vert(1.0) .margin_right(5.0) + .height(ui_line_height.get() as f32) .border(1.0) .border_radius(6.0) .border_color( @@ -424,7 +425,7 @@ fn keyboard_picker_view( .justify_center() .width_pct(100.0) .margin_top(20.0) - .height(ui_line_height.get() as f32 + 16.0) + .height((ui_line_height.get() as f32) * 1.2) .border(1.0) .border_radius(6.0) .border_color(config.color(LapceColor::LAPCE_BORDER)) @@ -548,7 +549,8 @@ fn keyboard_picker_view( .items_center() .justify_center() .apply_if(picker.keymap.with(|keymap| keymap.is_none()), |s| s.hide()) - }); + }) + .debug_name("keyboard picker"); let id = view.id(); create_effect(move |_| { From 31178fdd8c9a2f8b7cd1fb00dbdc0b083f3b51b8 Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Mon, 2 Sep 2024 05:32:32 +0800 Subject: [PATCH 31/69] implement "Open in GitHub" command (#3440) * implement "Open in GitHub" command * rename --- lapce-app/src/command.rs | 4 ++++ lapce-app/src/editor.rs | 3 +++ lapce-app/src/window_tab.rs | 27 +++++++++++++++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/lapce-app/src/command.rs b/lapce-app/src/command.rs index b4bafd768c..1d6aa0ed27 100644 --- a/lapce-app/src/command.rs +++ b/lapce-app/src/command.rs @@ -191,6 +191,10 @@ pub enum LapceWorkbenchCommand { #[strum(message = "Reveal in Panel")] RevealInPanel, + #[strum(serialize = "source_control_open_active_file_remote_url")] + #[strum(message = "Source Control: Open Remote File Url")] + SourceControlOpenActiveFileRemoteUrl, + #[cfg(not(target_os = "macos"))] #[strum(serialize = "reveal_in_file_explorer")] #[strum(message = "Reveal in System File Explorer")] diff --git a/lapce-app/src/editor.rs b/lapce-app/src/editor.rs index 882ee3664e..1b5a1d4df8 100644 --- a/lapce-app/src/editor.rs +++ b/lapce-app/src/editor.rs @@ -2748,6 +2748,9 @@ impl EditorData { Some(CommandKind::Workbench( LapceWorkbenchCommand::RevealInFileExplorer, )), + Some(CommandKind::Workbench( + LapceWorkbenchCommand::SourceControlOpenActiveFileRemoteUrl, + )), None, Some(CommandKind::Edit(EditCommand::ClipboardCut)), Some(CommandKind::Edit(EditCommand::ClipboardCopy)), diff --git a/lapce-app/src/window_tab.rs b/lapce-app/src/window_tab.rs index 51b928b581..cf21bdbe71 100644 --- a/lapce-app/src/window_tab.rs +++ b/lapce-app/src/window_tab.rs @@ -21,6 +21,7 @@ use floem::{ SignalWith, WriteSignal, }, text::{Attrs, AttrsList, FamilyOwned, LineHeightValue, TextLayout}, + views::editor::core::buffer::rope_text::RopeText, ViewId, }; use indexmap::IndexMap; @@ -1395,6 +1396,32 @@ impl WindowTabData { } } } + SourceControlOpenActiveFileRemoteUrl => { + if let Some(editor_data) = + self.main_split.active_editor.get_untracked() + { + if let DocContent::File {path, ..} = editor_data.doc().content.get_untracked() { + let offset = editor_data.cursor().with_untracked(|c| c.offset()); + let line = editor_data.doc() + .buffer + .with_untracked(|buffer| buffer.line_of_offset(offset)); + self.common.proxy.git_get_remote_file_url( + path, + create_ext_action(self.scope, move |result| { + if let Ok(ProxyResponse::GitGetRemoteFileUrl { + file_url + }) = result + { + if let Err(err) = open::that(format!("{}#L{}", file_url, line)) { + error!("Failed to open file in github: {}", err); + } + } + }), + ); + + } + } + } RevealInFileExplorer => { if let Some(editor_data) = self.main_split.active_editor.get_untracked() From 3125034892afe9303bb939056dbfd0ea1e8c752a Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Mon, 2 Sep 2024 05:41:27 +0800 Subject: [PATCH 32/69] Closing a terminal tab should also close the underlying terminal. (#3460) * Closing a terminal tab should also close the underlying terminal. * The current task will only be executed if the preceding task is successful. --- lapce-app/src/terminal/panel.rs | 50 ++++++++++++++++++++++++--------- lapce-app/src/window_tab.rs | 4 +-- lapce-proxy/src/terminal.rs | 6 ++-- lapce-rpc/src/core.rs | 8 ++++-- 4 files changed, 48 insertions(+), 20 deletions(-) diff --git a/lapce-app/src/terminal/panel.rs b/lapce-app/src/terminal/panel.rs index 223ca9602a..c71951a045 100644 --- a/lapce-app/src/terminal/panel.rs +++ b/lapce-app/src/terminal/panel.rs @@ -220,19 +220,40 @@ impl TerminalPanelData { } pub fn close_tab(&self, terminal_tab_id: Option) { - self.tab_info.update(|info| { - if let Some(terminal_tab_id) = terminal_tab_id { - info.tabs - .retain(|(_, t)| t.terminal_tab_id != terminal_tab_id); - } else { - let active = info.active.min(info.tabs.len().saturating_sub(1)); - if !info.tabs.is_empty() { - info.tabs.remove(active); + if let Some(close_tab) = self + .tab_info + .try_update(|info| { + let mut close_tab = None; + if let Some(terminal_tab_id) = terminal_tab_id { + if let Some(index) = + info.tabs.iter().enumerate().find_map(|(index, (_, t))| { + if t.terminal_tab_id == terminal_tab_id { + Some(index) + } else { + None + } + }) + { + close_tab = Some( + info.tabs.remove(index).1.terminals.get_untracked(), + ); + } + } else { + let active = info.active.min(info.tabs.len().saturating_sub(1)); + if !info.tabs.is_empty() { + info.tabs.remove(active); + } } - } - let new_active = info.active.min(info.tabs.len().saturating_sub(1)); - info.active = new_active; - }); + let new_active = info.active.min(info.tabs.len().saturating_sub(1)); + info.active = new_active; + close_tab + }) + .flatten() + { + close_tab + .into_iter() + .for_each(|x| self.common.proxy.terminal_close(x.1.term_id)); + } self.update_debug_active_term(); } @@ -356,7 +377,7 @@ impl TerminalPanelData { } } - pub fn terminal_stopped(&self, term_id: &TermId) { + pub fn terminal_stopped(&self, term_id: &TermId, exit_code: Option) { if let Some(terminal) = self.get_terminal(term_id) { if terminal.run_debug.with_untracked(|r| r.is_some()) { let was_prelaunch = terminal @@ -381,7 +402,8 @@ impl TerminalPanelData { } }) .unwrap(); - if was_prelaunch == Some(true) { + let exit_code = exit_code.unwrap_or(0); + if was_prelaunch == Some(true) && exit_code == 0 { let run_debug = terminal.run_debug.get_untracked(); if let Some(run_debug) = run_debug { if run_debug.mode == RunDebugMode::Debug { diff --git a/lapce-app/src/window_tab.rs b/lapce-app/src/window_tab.rs index cf21bdbe71..839fac200c 100644 --- a/lapce-app/src/window_tab.rs +++ b/lapce-app/src/window_tab.rs @@ -2066,12 +2066,12 @@ impl WindowTabData { }); } } - CoreNotification::TerminalProcessStopped { term_id } => { + CoreNotification::TerminalProcessStopped { term_id, exit_code } => { let _ = self .common .term_tx .send((*term_id, TermEvent::CloseTerminal)); - self.terminal.terminal_stopped(term_id); + self.terminal.terminal_stopped(term_id, *exit_code); if self .terminal .tab_info diff --git a/lapce-proxy/src/terminal.rs b/lapce-proxy/src/terminal.rs index 76a89e6cdf..202eb48fa2 100644 --- a/lapce-proxy/src/terminal.rs +++ b/lapce-proxy/src/terminal.rs @@ -116,6 +116,7 @@ impl Terminal { polling::Events::with_capacity(NonZeroUsize::new(1024).unwrap()); let timeout = Some(Duration::from_secs(6)); + let mut exit_code = None; 'event_loop: loop { events.clear(); if let Err(err) = self.poller.wait(&mut events, timeout) { @@ -133,10 +134,11 @@ impl Terminal { for event in events.iter() { match event.key { PTY_CHILD_EVENT_TOKEN => { - if let Some(tty::ChildEvent::Exited(_)) = + if let Some(tty::ChildEvent::Exited(exited_code)) = self.pty.next_child_event() { let _ = self.pty_read(&core_rpc, &mut buf); + exit_code = exited_code; break 'event_loop; } } @@ -192,7 +194,7 @@ impl Terminal { .unwrap(); } } - core_rpc.terminal_process_stopped(self.term_id); + core_rpc.terminal_process_stopped(self.term_id, exit_code); let _ = self.pty.deregister(&self.poller); } diff --git a/lapce-rpc/src/core.rs b/lapce-rpc/src/core.rs index f18d3d9911..d52b74019e 100644 --- a/lapce-rpc/src/core.rs +++ b/lapce-rpc/src/core.rs @@ -112,6 +112,7 @@ pub enum CoreNotification { }, TerminalProcessStopped { term_id: TermId, + exit_code: Option, }, RunInTerminal { config: RunDebugConfig, @@ -328,8 +329,11 @@ impl CoreRpcHandler { }); } - pub fn terminal_process_stopped(&self, term_id: TermId) { - self.notification(CoreNotification::TerminalProcessStopped { term_id }); + pub fn terminal_process_stopped(&self, term_id: TermId, exit_code: Option) { + self.notification(CoreNotification::TerminalProcessStopped { + term_id, + exit_code, + }); } pub fn terminal_launch_failed(&self, term_id: TermId, error: String) { From 0adf2b3c968b9cd76b5918778dcc393a7402d194 Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Mon, 2 Sep 2024 05:50:40 +0800 Subject: [PATCH 33/69] 1. Add `repeat` field to filter out long press (#3462) 2. Add SystemTime to filter out excessively long intervals. --- lapce-app/src/keymap.rs | 23 ++++++------- lapce-app/src/keypress.rs | 58 ++++++++++++++++++++++----------- lapce-app/src/keypress/key.rs | 18 ++++++---- lapce-app/src/keypress/press.rs | 9 +++-- 4 files changed, 67 insertions(+), 41 deletions(-) diff --git a/lapce-app/src/keymap.rs b/lapce-app/src/keymap.rs index 8d76e9623a..8ae2c52323 100644 --- a/lapce-app/src/keymap.rs +++ b/lapce-app/src/keymap.rs @@ -519,18 +519,19 @@ fn keyboard_picker_view( .on_event_stop(EventListener::KeyDown, move |event| { if let Event::KeyDown(key_event) = event { if let Some(keypress) = KeyPressData::keypress(key_event) { - let keypress = keypress.keymap_press(); - picker.keys.update(|keys| { - if let Some((last_key, last_key_confirmed)) = keys.last() { - if !*last_key_confirmed && last_key.is_modifiers() { - keys.pop(); + if let Some(keypress) = keypress.keymap_press() { + picker.keys.update(|keys| { + if let Some((last_key, last_key_confirmed)) = keys.last() { + if !*last_key_confirmed && last_key.is_modifiers() { + keys.pop(); + } } - } - if keys.len() == 2 { - keys.clear(); - } - keys.push((keypress, false)); - }) + if keys.len() == 2 { + keys.clear(); + } + keys.push((keypress, false)); + }) + } } } }) diff --git a/lapce-app/src/keypress.rs b/lapce-app/src/keypress.rs index 3700dccc1c..78a6753cdf 100644 --- a/lapce-app/src/keypress.rs +++ b/lapce-app/src/keypress.rs @@ -4,7 +4,7 @@ pub mod keymap; mod loader; mod press; -use std::{path::PathBuf, rc::Rc, str::FromStr}; +use std::{path::PathBuf, rc::Rc, str::FromStr, time::SystemTime}; use anyhow::Result; use floem::{ @@ -147,7 +147,7 @@ pub struct KeyPressHandle { #[derive(Clone, Debug)] pub struct KeyPressData { count: RwSignal>, - pending_keypress: RwSignal>, + pending_keypress: RwSignal<(Vec, Option)>, pub commands: Rc>, pub keymaps: Rc, Vec>>, pub command_keymaps: Rc>>, @@ -161,7 +161,7 @@ impl KeyPressData { Self::get_keymaps(config).unwrap_or((IndexMap::new(), IndexMap::new())); let mut keypress = Self { count: cx.create_rw_signal(None), - pending_keypress: cx.create_rw_signal(Vec::new()), + pending_keypress: cx.create_rw_signal((Vec::new(), None)), keymaps: Rc::new(keymaps), command_keymaps: Rc::new(command_keymaps), commands: Rc::new(lapce_internal_commands()), @@ -259,6 +259,7 @@ impl KeyPressData { physical: ev.key.physical_key, key_without_modifiers: ev.key.key_without_modifiers(), location: ev.key.location, + repeat: ev.key.repeat, }, mods: Self::get_key_modifiers(ev), }, @@ -297,13 +298,26 @@ impl KeyPressData { }; } - self.pending_keypress.update(|pending_keypress| { - pending_keypress.push(keypress.clone()); - }); + self.pending_keypress + .update(|(pending_keypress, last_time)| { + let last_time = last_time.replace(SystemTime::now()); + if let Some(last_time_val) = last_time { + if last_time_val + .elapsed() + .map(|x| x.as_millis() > 1000) + .unwrap_or_default() + { + pending_keypress.clear(); + } + } + pending_keypress.push(keypress.clone()); + }); - let keymatch = self.pending_keypress.with_untracked(|pending_keypress| { - self.match_keymap(pending_keypress, focus) - }); + let keymatch = + self.pending_keypress + .with_untracked(|(pending_keypress, _)| { + self.match_keymap(pending_keypress, focus) + }); self.handle_keymatch(focus, keymatch, keypress) } @@ -316,9 +330,11 @@ impl KeyPressData { let mods = keypress.mods; match &keymatch { KeymapMatch::Full(command) => { - self.pending_keypress.update(|pending_keypress| { - pending_keypress.clear(); - }); + self.pending_keypress + .update(|(pending_keypress, last_time)| { + last_time.take(); + pending_keypress.clear(); + }); let count = self.count.try_update(|count| count.take()).unwrap(); let handled = self.run_command(command, count, mods, focus) == CommandExecuted::Yes; @@ -329,9 +345,11 @@ impl KeyPressData { }; } KeymapMatch::Multiple(commands) => { - self.pending_keypress.update(|pending_keypress| { - pending_keypress.clear(); - }); + self.pending_keypress + .update(|(pending_keypress, last_time)| { + last_time.take(); + pending_keypress.clear(); + }); let count = self.count.try_update(|count| count.take()).unwrap(); for command in commands { let handled = self.run_command(command, count, mods, focus) @@ -361,9 +379,11 @@ impl KeyPressData { }; } KeymapMatch::None => { - self.pending_keypress.update(|pending_keypress| { - pending_keypress.clear(); - }); + self.pending_keypress + .update(|(pending_keypress, last_time)| { + pending_keypress.clear(); + last_time.take(); + }); if focus.get_mode() == Mode::Insert { let old_keypress = keypress.clone(); let mut keypress = keypress.clone(); @@ -449,7 +469,7 @@ impl KeyPressData { check: &T, ) -> KeymapMatch { let keypresses: Vec = - keypresses.iter().map(|k| k.keymap_press()).collect(); + keypresses.iter().filter_map(|k| k.keymap_press()).collect(); let matches: Vec<_> = self .keymaps .get(&keypresses) diff --git a/lapce-app/src/keypress/key.rs b/lapce-app/src/keypress/key.rs index 2b40a3a3fc..2ce5aaa0ae 100644 --- a/lapce-app/src/keypress/key.rs +++ b/lapce-app/src/keypress/key.rs @@ -1,7 +1,6 @@ use floem::keyboard::{Key, KeyLocation, NamedKey, PhysicalKey}; use super::keymap::KeyMapKey; -use crate::tracing::*; #[derive(Clone, Debug)] pub(crate) enum KeyInput { @@ -10,25 +9,32 @@ pub(crate) enum KeyInput { logical: Key, location: KeyLocation, key_without_modifiers: Key, + repeat: bool, }, Pointer(floem::pointer::PointerButton), } impl KeyInput { - #[instrument] - pub fn keymap_key(&self) -> KeyMapKey { - match self { + pub fn keymap_key(&self) -> Option { + if let KeyInput::Keyboard { repeat, .. } = self { + if *repeat { + return None; + } + } + + Some(match self { KeyInput::Pointer(b) => KeyMapKey::Pointer(*b), KeyInput::Keyboard { physical, key_without_modifiers, logical, location, + .. } => { #[allow(clippy::single_match)] match location { KeyLocation::Numpad => { - return KeyMapKey::Logical(logical.to_owned()) + return Some(KeyMapKey::Logical(logical.to_owned())) } _ => {} } @@ -52,6 +58,6 @@ impl KeyInput { Key::Dead(_) => KeyMapKey::Physical(*physical), } } - } + }) } } diff --git a/lapce-app/src/keypress/press.rs b/lapce-app/src/keypress/press.rs index a598d274dd..af262acfd4 100644 --- a/lapce-app/src/keypress/press.rs +++ b/lapce-app/src/keypress/press.rs @@ -9,11 +9,10 @@ pub struct KeyPress { } impl KeyPress { - #[tracing::instrument] - pub fn keymap_press(&self) -> KeyMapPress { - KeyMapPress { - key: self.key.keymap_key(), + pub fn keymap_press(&self) -> Option { + self.key.keymap_key().map(|key| KeyMapPress { + key, mods: self.mods, - } + }) } } From 840b915c4bb2ccca90ec651260dc815536ffb054 Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Tue, 3 Sep 2024 15:26:45 +0100 Subject: [PATCH 34/69] only modifiers keys can't repeat --- lapce-app/src/keypress/key.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/lapce-app/src/keypress/key.rs b/lapce-app/src/keypress/key.rs index 2ce5aaa0ae..905c47b4cc 100644 --- a/lapce-app/src/keypress/key.rs +++ b/lapce-app/src/keypress/key.rs @@ -16,8 +16,19 @@ pub(crate) enum KeyInput { impl KeyInput { pub fn keymap_key(&self) -> Option { - if let KeyInput::Keyboard { repeat, .. } = self { - if *repeat { + if let KeyInput::Keyboard { + repeat, logical, .. + } = self + { + if *repeat + && (matches!( + logical, + Key::Named(NamedKey::Meta) + | Key::Named(NamedKey::Shift) + | Key::Named(NamedKey::Alt) + | Key::Named(NamedKey::Control), + )) + { return None; } } From 81333eb375a7757aa5b9acbf5b2db6d0757522b5 Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Thu, 5 Sep 2024 17:50:19 +0800 Subject: [PATCH 35/69] add error log (#3466) --- lapce-proxy/src/dispatch.rs | 81 +++++++++++++----- lapce-proxy/src/lib.rs | 36 ++++++-- lapce-proxy/src/plugin/catalog.rs | 44 +++++++--- lapce-proxy/src/plugin/dap.rs | 66 +++++++++++---- lapce-proxy/src/plugin/lsp.rs | 31 +++++-- lapce-proxy/src/plugin/mod.rs | 131 ++++++++++++++++++++---------- lapce-proxy/src/plugin/psp.rs | 54 ++++++++---- lapce-proxy/src/plugin/wasi.rs | 21 +++-- lapce-proxy/src/terminal.rs | 16 +++- lapce-proxy/src/watcher.rs | 12 ++- 10 files changed, 357 insertions(+), 135 deletions(-) diff --git a/lapce-proxy/src/dispatch.rs b/lapce-proxy/src/dispatch.rs index e076798448..a55d691081 100644 --- a/lapce-proxy/src/dispatch.rs +++ b/lapce-proxy/src/dispatch.rs @@ -163,7 +163,9 @@ impl ProxyHandler for Dispatcher { ); } UpdatePluginConfigs { configs } => { - let _ = self.catalog_rpc.update_plugin_configs(configs); + if let Err(err) = self.catalog_rpc.update_plugin_configs(configs) { + tracing::error!("{:?}", err); + } } NewTerminal { term_id, profile } => { let mut terminal = match Terminal::new(term_id, profile, 50, 10) { @@ -226,57 +228,86 @@ impl ProxyHandler for Dispatcher { config, breakpoints, } => { - let _ = self.catalog_rpc.dap_start(config, breakpoints); + if let Err(err) = self.catalog_rpc.dap_start(config, breakpoints) { + tracing::error!("{:?}", err); + } } DapProcessId { dap_id, process_id, term_id, } => { - let _ = self.catalog_rpc.dap_process_id(dap_id, process_id, term_id); + if let Err(err) = + self.catalog_rpc.dap_process_id(dap_id, process_id, term_id) + { + tracing::error!("{:?}", err); + } } DapContinue { dap_id, thread_id } => { - let _ = self.catalog_rpc.dap_continue(dap_id, thread_id); + if let Err(err) = self.catalog_rpc.dap_continue(dap_id, thread_id) { + tracing::error!("{:?}", err); + } } DapPause { dap_id, thread_id } => { - let _ = self.catalog_rpc.dap_pause(dap_id, thread_id); + if let Err(err) = self.catalog_rpc.dap_pause(dap_id, thread_id) { + tracing::error!("{:?}", err); + } } DapStepOver { dap_id, thread_id } => { - let _ = self.catalog_rpc.dap_step_over(dap_id, thread_id); + if let Err(err) = self.catalog_rpc.dap_step_over(dap_id, thread_id) { + tracing::error!("{:?}", err); + } } DapStepInto { dap_id, thread_id } => { - let _ = self.catalog_rpc.dap_step_into(dap_id, thread_id); + if let Err(err) = self.catalog_rpc.dap_step_into(dap_id, thread_id) { + tracing::error!("{:?}", err); + } } DapStepOut { dap_id, thread_id } => { - let _ = self.catalog_rpc.dap_step_out(dap_id, thread_id); + if let Err(err) = self.catalog_rpc.dap_step_out(dap_id, thread_id) { + tracing::error!("{:?}", err); + } } DapStop { dap_id } => { - let _ = self.catalog_rpc.dap_stop(dap_id); + if let Err(err) = self.catalog_rpc.dap_stop(dap_id) { + tracing::error!("{:?}", err); + } } DapDisconnect { dap_id } => { - let _ = self.catalog_rpc.dap_disconnect(dap_id); + if let Err(err) = self.catalog_rpc.dap_disconnect(dap_id) { + tracing::error!("{:?}", err); + } } DapRestart { dap_id, breakpoints, } => { - let _ = self.catalog_rpc.dap_restart(dap_id, breakpoints); + if let Err(err) = self.catalog_rpc.dap_restart(dap_id, breakpoints) { + tracing::error!("{:?}", err); + } } DapSetBreakpoints { dap_id, path, breakpoints, } => { - let _ = + if let Err(err) = self.catalog_rpc - .dap_set_breakpoints(dap_id, path, breakpoints); + .dap_set_breakpoints(dap_id, path, breakpoints) + { + tracing::error!("{:?}", err); + } } InstallVolt { volt } => { let catalog_rpc = self.catalog_rpc.clone(); - let _ = catalog_rpc.install_volt(volt); + if let Err(err) = catalog_rpc.install_volt(volt) { + tracing::error!("{:?}", err); + } } ReloadVolt { volt } => { - let _ = self.catalog_rpc.reload_volt(volt); + if let Err(err) = self.catalog_rpc.reload_volt(volt) { + tracing::error!("{:?}", err); + } } RemoveVolt { volt } => { self.catalog_rpc.remove_volt(volt); @@ -285,7 +316,9 @@ impl ProxyHandler for Dispatcher { self.catalog_rpc.stop_volt(volt); } EnableVolt { volt } => { - let _ = self.catalog_rpc.enable_volt(volt); + if let Err(err) = self.catalog_rpc.enable_volt(volt) { + tracing::error!("{:?}", err); + } } GitCommit { message, diffs } => { if let Some(workspace) = self.workspace.as_ref() { @@ -1192,14 +1225,18 @@ impl FileWatchNotifier { if let Some(sender) = handler.as_mut() { if explorer_change { // only send the value if we need to update file explorer as well - let _ = sender.send(explorer_change); + if let Err(err) = sender.send(explorer_change) { + tracing::error!("{:?}", err); + } } return; } let (sender, receiver) = crossbeam_channel::unbounded(); if explorer_change { // only send the value if we need to update file explorer as well - let _ = sender.send(explorer_change); + if let Err(err) = sender.send(explorer_change) { + tracing::error!("{:?}", err); + } } let local_handler = self.workspace_fs_change_handler.clone(); @@ -1571,7 +1608,7 @@ fn search_in_path( if path.is_file() { let mut line_matches = Vec::new(); - let _ = searcher.search_path( + if let Err(err) = searcher.search_path( &matcher, path.clone(), UTF8(|lnum, line| { @@ -1610,7 +1647,11 @@ fn search_in_path( }); Ok(true) }), - ); + ) { + { + tracing::error!("{:?}", err); + } + } if !line_matches.is_empty() { matches.insert(path.clone(), line_matches); } diff --git a/lapce-proxy/src/lib.rs b/lapce-proxy/src/lib.rs index b694870216..7130434142 100644 --- a/lapce-proxy/src/lib.rs +++ b/lapce-proxy/src/lib.rs @@ -66,10 +66,18 @@ pub fn mainloop() { for msg in local_core_rpc.rx() { match msg { CoreRpc::Request(id, rpc) => { - let _ = local_writer_tx.send(RpcMessage::Request(id, rpc)); + if let Err(err) = + local_writer_tx.send(RpcMessage::Request(id, rpc)) + { + tracing::error!("{:?}", err); + } } CoreRpc::Notification(rpc) => { - let _ = local_writer_tx.send(RpcMessage::Notification(rpc)); + if let Err(err) = + local_writer_tx.send(RpcMessage::Notification(rpc)) + { + tracing::error!("{:?}", err); + } } CoreRpc::Shutdown => { return; @@ -87,10 +95,18 @@ pub fn mainloop() { let writer_tx = writer_tx.clone(); local_proxy_rpc.request_async(req, move |result| match result { Ok(resp) => { - let _ = writer_tx.send(RpcMessage::Response(id, resp)); + if let Err(err) = + writer_tx.send(RpcMessage::Response(id, resp)) + { + tracing::error!("{:?}", err); + } } Err(e) => { - let _ = writer_tx.send(RpcMessage::Error(id, e)); + if let Err(err) = + writer_tx.send(RpcMessage::Error(id, e)) + { + tracing::error!("{:?}", err); + } } }); } @@ -110,9 +126,13 @@ pub fn mainloop() { let local_proxy_rpc = proxy_rpc.clone(); std::thread::spawn(move || { - let _ = listen_local_socket(local_proxy_rpc); + if let Err(err) = listen_local_socket(local_proxy_rpc) { + tracing::error!("{:?}", err); + } }); - let _ = register_lapce_path(); + if let Err(err) = register_lapce_path() { + tracing::error!("{:?}", err); + } proxy_rpc.mainloop(&mut dispatcher); } @@ -138,7 +158,9 @@ pub fn register_lapce_path() -> Result<()> { fn listen_local_socket(proxy_rpc: ProxyRpcHandler) -> Result<()> { let local_socket = Directory::local_socket() .ok_or_else(|| anyhow!("can't get local socket folder"))?; - let _ = std::fs::remove_file(&local_socket); + if let Err(err) = std::fs::remove_file(&local_socket) { + tracing::error!("{:?}", err); + } let socket = interprocess::local_socket::LocalSocketListener::bind(local_socket)?; for stream in socket.incoming().flatten() { diff --git a/lapce-proxy/src/plugin/catalog.rs b/lapce-proxy/src/plugin/catalog.rs index be97ef1bb0..bee41ffbcf 100644 --- a/lapce-proxy/src/plugin/catalog.rs +++ b/lapce-proxy/src/plugin/catalog.rs @@ -209,7 +209,11 @@ impl PluginCatalog { self.plugin_configurations.get(&meta.name).cloned(); let plugin_rpc = self.plugin_rpc.clone(); thread::spawn(move || { - let _ = start_volt(workspace, configurations, plugin_rpc, meta); + if let Err(err) = + start_volt(workspace, configurations, plugin_rpc, meta) + { + tracing::error!("{:?}", err); + } }); } } @@ -512,8 +516,11 @@ impl PluginCatalog { let catalog_rpc = self.plugin_rpc.clone(); catalog_rpc.stop_volt(volt.clone()); thread::spawn(move || { - let _ = - install_volt(catalog_rpc, workspace, configurations, volt); + if let Err(err) = + install_volt(catalog_rpc, workspace, configurations, volt) + { + tracing::error!("{:?}", err); + } }); } ReloadVolt(volt) => { @@ -525,7 +532,9 @@ impl PluginCatalog { plugin.shutdown(); } } - let _ = self.plugin_rpc.unactivated_volts(vec![volt]); + if let Err(err) = self.plugin_rpc.unactivated_volts(vec![volt]) { + tracing::error!("{:?}", err); + } } StopVolt(volt) => { let volt_id = volt.id(); @@ -546,7 +555,9 @@ impl PluginCatalog { } let plugin_rpc = self.plugin_rpc.clone(); thread::spawn(move || { - let _ = enable_volt(plugin_rpc, volt); + if let Err(err) = enable_volt(plugin_rpc, volt) { + tracing::error!("{:?}", err); + } }); } DapLoaded(dap_rpc) => { @@ -577,9 +588,14 @@ impl PluginCatalog { breakpoints, plugin_rpc.clone(), ) { - let _ = plugin_rpc.dap_loaded(dap_rpc.clone()); + if let Err(err) = plugin_rpc.dap_loaded(dap_rpc.clone()) + { + tracing::error!("{:?}", err); + } - let _ = dap_rpc.launch(&config); + if let Err(err) = dap_rpc.launch(&config) { + tracing::error!("{:?}", err); + } } }); } @@ -590,7 +606,11 @@ impl PluginCatalog { term_id, } => { if let Some(dap) = self.daps.get(&dap_id) { - let _ = dap.termain_process_tx.send((term_id, process_id)); + if let Err(err) = + dap.termain_process_tx.send((term_id, process_id)) + { + tracing::error!("{:?}", err); + } } } DapContinue { dap_id, thread_id } => { @@ -606,7 +626,9 @@ impl PluginCatalog { DapPause { dap_id, thread_id } => { if let Some(dap) = self.daps.get(&dap_id).cloned() { thread::spawn(move || { - let _ = dap.pause_thread(thread_id); + if let Err(err) = dap.pause_thread(thread_id) { + tracing::error!("{:?}", err); + } }); } } @@ -633,7 +655,9 @@ impl PluginCatalog { DapDisconnect { dap_id } => { if let Some(dap) = self.daps.get(&dap_id).cloned() { thread::spawn(move || { - let _ = dap.disconnect(); + if let Err(err) = dap.disconnect() { + tracing::error!("{:?}", err); + } }); } } diff --git a/lapce-proxy/src/plugin/dap.rs b/lapce-proxy/src/plugin/dap.rs index 7c71bce928..20e8509cf0 100644 --- a/lapce-proxy/src/plugin/dap.rs +++ b/lapce-proxy/src/plugin/dap.rs @@ -133,9 +133,11 @@ impl DapClient { dap_rpc.handle_server_message(&message_str); } Err(_err) => { - let _ = io_tx.send(DapPayload::Event( - DapEvent::Initialized(None), - )); + if let Err(err) = io_tx + .send(DapPayload::Event(DapEvent::Initialized(None))) + { + tracing::error!("{:?}", err); + } plugin_rpc.core_rpc.log( lapce_rpc::core::LogLevel::Error, format!("dap server {program} stopped!"), @@ -294,7 +296,9 @@ impl DapClient { if let Some(term_id) = self.term_id { self.plugin_rpc.proxy_rpc.terminal_close(term_id); } - let _ = self.check_restart(); + if let Err(err) = self.check_restart() { + tracing::error!("{:?}", err); + } } DapEvent::Thread { .. } => {} DapEvent::Output(_) => {} @@ -343,11 +347,15 @@ impl DapClient { .unwrap_or(false) { thread::spawn(move || { - let _ = dap_rpc.terminate(); + if let Err(err) = dap_rpc.terminate() { + tracing::error!("{:?}", err); + } }); } else { thread::spawn(move || { - let _ = dap_rpc.disconnect(); + if let Err(err) = dap_rpc.disconnect() { + tracing::error!("{:?}", err); + } }); } } @@ -381,7 +389,9 @@ impl DapClient { let dap_rpc = self.dap_rpc.clone(); let config = self.config.clone(); thread::spawn(move || { - let _ = dap_rpc.launch(&config); + if let Err(err) = dap_rpc.launch(&config) { + tracing::error!("{:?}", err); + } }); Ok(()) @@ -393,7 +403,9 @@ impl DapClient { if !self.terminated { self.stop(); } else { - let _ = self.check_restart(); + if let Err(err) = self.check_restart() { + tracing::error!("{:?}", err); + } } } } @@ -460,10 +472,14 @@ impl DapRpcHandler { message: result.as_ref().err().map(|e| e.to_string()), body: result.ok(), }; - let _ = self.io_tx.send(DapPayload::Response(resp)); + if let Err(err) = self.io_tx.send(DapPayload::Response(resp)) { + tracing::error!("{:?}", err); + } } DapRpc::HostEvent(event) => { - let _ = dap_client.handle_host_event(&event); + if let Err(err) = dap_client.handle_host_event(&event) { + tracing::error!("{:?}", err); + } } DapRpc::Stop => { dap_client.stop(); @@ -482,7 +498,9 @@ impl DapRpcHandler { if let Some(term_id) = dap_client.term_id { dap_client.plugin_rpc.proxy_rpc.terminal_close(term_id); } - let _ = dap_client.check_restart(); + if let Err(err) = dap_client.check_restart() { + tracing::error!("{:?}", err); + } } } } @@ -562,11 +580,13 @@ impl DapRpcHandler { let mut pending = self.server_pending.lock(); pending.insert(seq, rh); } - let _ = self.io_tx.send(DapPayload::Request(DapRequest { + if let Err(err) = self.io_tx.send(DapPayload::Request(DapRequest { seq, command: command.to_string(), arguments: Some(arguments), - })); + })) { + tracing::error!("{:?}", err); + } } fn handle_server_response(&self, resp: DapResponse) { @@ -579,10 +599,14 @@ impl DapRpcHandler { if let Ok(payload) = serde_json::from_str::(message_str) { match payload { DapPayload::Request(req) => { - let _ = self.rpc_tx.send(DapRpc::HostRequest(req)); + if let Err(err) = self.rpc_tx.send(DapRpc::HostRequest(req)) { + tracing::error!("{:?}", err); + } } DapPayload::Event(event) => { - let _ = self.rpc_tx.send(DapRpc::HostEvent(event)); + if let Err(err) = self.rpc_tx.send(DapRpc::HostEvent(event)) { + tracing::error!("{:?}", err); + } } DapPayload::Response(resp) => { self.handle_server_response(resp); @@ -605,15 +629,21 @@ impl DapRpcHandler { } pub fn stop(&self) { - let _ = self.rpc_tx.send(DapRpc::Stop); + if let Err(err) = self.rpc_tx.send(DapRpc::Stop) { + tracing::error!("{:?}", err); + } } pub fn restart(&self, breakpoints: HashMap>) { - let _ = self.rpc_tx.send(DapRpc::Restart(breakpoints)); + if let Err(err) = self.rpc_tx.send(DapRpc::Restart(breakpoints)) { + tracing::error!("{:?}", err); + } } fn disconnected(&self) { - let _ = self.rpc_tx.send(DapRpc::Disconnected); + if let Err(err) = self.rpc_tx.send(DapRpc::Disconnected) { + tracing::error!("{:?}", err); + } } pub fn disconnect(&self) -> Result<()> { diff --git a/lapce-proxy/src/plugin/lsp.rs b/lapce-proxy/src/plugin/lsp.rs index ca8473e0ef..defaf36d99 100644 --- a/lapce-proxy/src/plugin/lsp.rs +++ b/lapce-proxy/src/plugin/lsp.rs @@ -114,7 +114,9 @@ impl PluginServerHandler for LspClient { params: Params, from: String, ) { - let _ = self.host.handle_notification(method, params, from); + if let Err(err) = self.host.handle_notification(method, params, from) { + tracing::error!("{:?}", err); + } } fn handle_did_save_text_document( @@ -185,10 +187,13 @@ impl LspClient { "file" => { let path = server_uri.to_file_path().map_err(|_| anyhow!(""))?; #[cfg(unix)] - let _ = std::process::Command::new("chmod") + if let Err(err) = std::process::Command::new("chmod") .arg("+x") .arg(&path) - .output(); + .output() + { + tracing::error!("{:?}", err); + } path.to_str().ok_or_else(|| anyhow!(""))?.to_string() } "urn" => server_uri.path().to_string(), @@ -220,8 +225,12 @@ impl LspClient { if let Ok(msg) = serde_json::to_string(&msg) { let msg = format!("Content-Length: {}\r\n\r\n{}", msg.len(), msg); - let _ = writer.write(msg.as_bytes()); - let _ = writer.flush(); + if let Err(err) = writer.write(msg.as_bytes()) { + tracing::error!("{:?}", err); + } + if let Err(err) = writer.flush() { + tracing::error!("{:?}", err); + } } } }); @@ -240,7 +249,9 @@ impl LspClient { &message_str, &name, ) { - let _ = io_tx.send(resp); + if let Err(err) = io_tx.send(resp) { + tracing::error!("{:?}", err); + } } } Err(_err) => { @@ -406,8 +417,12 @@ impl LspClient { } fn shutdown(&mut self) { - let _ = self.process.kill(); - let _ = self.process.wait(); + if let Err(err) = self.process.kill() { + tracing::error!("{:?}", err); + } + if let Err(err) = self.process.wait() { + tracing::error!("{:?}", err); + } } fn process( diff --git a/lapce-proxy/src/plugin/mod.rs b/lapce-proxy/src/plugin/mod.rs index ca0d6d0a35..187c9b525d 100644 --- a/lapce-proxy/src/plugin/mod.rs +++ b/lapce-proxy/src/plugin/mod.rs @@ -241,7 +241,9 @@ impl PluginCatalogRpcHandler { #[allow(dead_code)] fn handle_response(&self, id: RequestId, result: Result) { if let Some(chan) = { self.pending.lock().remove(&id) } { - let _ = chan.send(result); + if let Err(err) = chan.send(result) { + tracing::error!("{:?}", err); + } } } @@ -354,8 +356,14 @@ impl PluginCatalogRpcHandler { } pub fn shutdown(&self) { - let _ = self.catalog_notification(PluginCatalogNotification::Shutdown); - let _ = self.plugin_tx.send(PluginCatalogRpc::Shutdown); + if let Err(err) = + self.catalog_notification(PluginCatalogNotification::Shutdown) + { + tracing::error!("{:?}", err); + } + if let Err(err) = self.plugin_tx.send(PluginCatalogRpc::Shutdown) { + tracing::error!("{:?}", err); + } } fn catalog_notification( @@ -443,7 +451,9 @@ impl PluginCatalogRpcHandler { check, f: Box::new(f), }; - let _ = self.plugin_tx.send(rpc); + if let Err(err) = self.plugin_tx.send(rpc) { + tracing::error!("{:?}", err); + } } #[allow(clippy::too_many_arguments)] @@ -465,7 +475,9 @@ impl PluginCatalogRpcHandler { path, check, }; - let _ = self.plugin_tx.send(rpc); + if let Err(err) = self.plugin_tx.send(rpc) { + tracing::error!("{:?}", err); + } } pub fn format_semantic_tokens( @@ -475,24 +487,32 @@ impl PluginCatalogRpcHandler { text: Rope, f: Box, RpcError>>, ) { - let _ = self.plugin_tx.send(PluginCatalogRpc::FormatSemanticTokens { - plugin_id, - tokens, - text, - f, - }); + if let Err(err) = + self.plugin_tx.send(PluginCatalogRpc::FormatSemanticTokens { + plugin_id, + tokens, + text, + f, + }) + { + tracing::error!("{:?}", err); + } } pub fn did_save_text_document(&self, path: &Path, text: Rope) { let text_document = TextDocumentIdentifier::new(Url::from_file_path(path).unwrap()); let language_id = language_id_from_path(path).unwrap_or("").to_string(); - let _ = self.plugin_tx.send(PluginCatalogRpc::DidSaveTextDocument { - language_id, - text_document, - path: path.into(), - text, - }); + if let Err(err) = + self.plugin_tx.send(PluginCatalogRpc::DidSaveTextDocument { + language_id, + text_document, + path: path.into(), + text, + }) + { + tracing::error!("{:?}", err); + } } pub fn did_change_text_document( @@ -508,15 +528,18 @@ impl PluginCatalogRpcHandler { rev as i32, ); let language_id = language_id_from_path(path).unwrap_or("").to_string(); - let _ = self - .plugin_tx - .send(PluginCatalogRpc::DidChangeTextDocument { - language_id, - document, - delta, - text, - new_text, - }); + if let Err(err) = + self.plugin_tx + .send(PluginCatalogRpc::DidChangeTextDocument { + language_id, + document, + delta, + text, + new_text, + }) + { + tracing::error!("{:?}", err); + } } pub fn get_definition( @@ -1194,14 +1217,18 @@ impl PluginCatalogRpcHandler { ) { match Url::from_file_path(path) { Ok(path) => { - let _ = self.plugin_tx.send(PluginCatalogRpc::DidOpenTextDocument { - document: TextDocumentItem::new( - path, - language_id, - version, - text, - ), - }); + if let Err(err) = + self.plugin_tx.send(PluginCatalogRpc::DidOpenTextDocument { + document: TextDocumentItem::new( + path, + language_id, + version, + text, + ), + }) + { + tracing::error!("{:?}", err); + } } Err(_) => { tracing::error!("Failed to parse URL from file path: {path:?}"); @@ -1245,7 +1272,9 @@ impl PluginCatalogRpcHandler { } }), }; - let _ = self.plugin_tx.send(rpc); + if let Err(err) = self.plugin_tx.send(rpc) { + tracing::error!("{:?}", err); + } } pub fn remove_volt(&self, volt: VoltMetadata) { @@ -1262,7 +1291,9 @@ impl PluginCatalogRpcHandler { } }), }; - let _ = self.plugin_tx.send(rpc); + if let Err(err) = self.plugin_tx.send(rpc) { + tracing::error!("{:?}", err); + } } pub fn reload_volt(&self, volt: VoltMetadata) -> Result<()> { @@ -1380,11 +1411,13 @@ impl PluginCatalogRpcHandler { reference: usize, f: impl FnOnce(Result, RpcError>) + Send + 'static, ) { - let _ = self.plugin_tx.send(PluginCatalogRpc::DapVariable { + if let Err(err) = self.plugin_tx.send(PluginCatalogRpc::DapVariable { dap_id, reference, f: Box::new(f), - }); + }) { + tracing::error!("{:?}", err); + } } pub fn dap_get_scopes( @@ -1396,11 +1429,13 @@ impl PluginCatalogRpcHandler { ) + Send + 'static, ) { - let _ = self.plugin_tx.send(PluginCatalogRpc::DapGetScopes { + if let Err(err) = self.plugin_tx.send(PluginCatalogRpc::DapGetScopes { dap_id, frame_id, f: Box::new(f), - }); + }) { + tracing::error!("{:?}", err); + } } pub fn register_debugger_type( @@ -1409,13 +1444,15 @@ impl PluginCatalogRpcHandler { program: String, args: Option>, ) { - let _ = self.catalog_notification( + if let Err(err) = self.catalog_notification( PluginCatalogNotification::RegisterDebuggerType { debugger_type, program, args, }, - ); + ) { + tracing::error!("{:?}", err); + } } } @@ -1476,7 +1513,9 @@ pub fn download_volt(volt: &VoltInfo) -> Result { let plugin_dir = Directory::plugins_directory() .ok_or_else(|| anyhow!("can't get plugin directory"))? .join(id.to_string()); - let _ = fs::remove_dir_all(&plugin_dir); + if let Err(err) = fs::remove_dir_all(&plugin_dir) { + tracing::error!("{:?}", err); + } fs::create_dir_all(&plugin_dir)?; if is_zstd { @@ -1509,7 +1548,11 @@ pub fn install_volt( let local_catalog_rpc = catalog_rpc.clone(); let local_meta = meta.clone(); - let _ = start_volt(workspace, configurations, local_catalog_rpc, local_meta); + if let Err(err) = + start_volt(workspace, configurations, local_catalog_rpc, local_meta) + { + tracing::error!("{:?}", err); + } let icon = volt_icon(&meta); catalog_rpc.core_rpc.volt_installed(meta, icon); Ok(()) diff --git a/lapce-proxy/src/plugin/psp.rs b/lapce-proxy/src/plugin/psp.rs index c264f12717..9491334d7e 100644 --- a/lapce-proxy/src/plugin/psp.rs +++ b/lapce-proxy/src/plugin/psp.rs @@ -72,7 +72,9 @@ impl ResponseHandler { pub fn invoke(self, result: Result) { match self { ResponseHandler::Chan(tx) => { - let _ = tx.send(result); + if let Err(err) = tx.send(result) { + tracing::error!("{:?}", err); + } } ResponseHandler::Callback(f) => f.call(result), } @@ -189,18 +191,24 @@ impl ResponseSender { code: 0, message: e.to_string(), }); - let _ = self.tx.send(result); + if let Err(err) = self.tx.send(result) { + tracing::error!("{:?}", err); + } } pub fn send_null(&self) { - let _ = self.tx.send(Ok(Value::Null)); + if let Err(err) = self.tx.send(Ok(Value::Null)) { + tracing::error!("{:?}", err); + } } pub fn send_err(&self, code: i64, message: impl Into) { - let _ = self.tx.send(Err(RpcError { + if let Err(err) = self.tx.send(Err(RpcError { code, message: message.into(), - })); + })) { + tracing::error!("{:?}", err); + } } } @@ -308,11 +316,15 @@ impl PluginServerRpcHandler { } fn send_server_rpc(&self, msg: JsonRpc) { - let _ = self.io_tx.send(msg); + if let Err(err) = self.io_tx.send(msg) { + tracing::error!("{:?}", err); + } } pub fn handle_rpc(&self, rpc: PluginServerRpc) { - let _ = self.rpc_tx.send(rpc); + if let Err(err) = self.rpc_tx.send(rpc) { + tracing::error!("{:?}", err); + } } /// Send a notification. @@ -329,12 +341,14 @@ impl PluginServerRpcHandler { let method = method.into(); if check { - let _ = self.rpc_tx.send(PluginServerRpc::ServerNotification { + if let Err(err) = self.rpc_tx.send(PluginServerRpc::ServerNotification { method, params, language_id, path, - }); + }) { + tracing::error!("{:?}", err); + } } else { self.send_server_notification(&method, params); } @@ -402,14 +416,16 @@ impl PluginServerRpcHandler { let id = self.id.fetch_add(1, Ordering::Relaxed); let params = Params::from(serde_json::to_value(params).unwrap()); if check { - let _ = self.rpc_tx.send(PluginServerRpc::ServerRequest { + if let Err(err) = self.rpc_tx.send(PluginServerRpc::ServerRequest { id: Id::Num(id as i64), method, params, language_id, path, rh, - }); + }) { + tracing::error!("{:?}", err); + } } else { self.send_server_request(Id::Num(id as i64), &method, params, rh); } @@ -852,7 +868,9 @@ impl PluginHostHandler { fn register_capabilities(&mut self, registrations: Vec) { for registration in registrations { - let _ = self.register_capability(registration); + if let Err(err) = self.register_capability(registration) { + tracing::error!("{:?}", err); + } } } @@ -952,7 +970,7 @@ impl PluginHostHandler { self.spawned_lsp .insert(plugin_id, SpawnedLspInfo { resp: Some(resp) }); thread::spawn(move || { - let _ = LspClient::start( + if let Err(err) = LspClient::start( catalog_rpc, params.document_selector, workspace, @@ -964,7 +982,9 @@ impl PluginHostHandler { params.server_uri, params.server_args, params.options, - ); + ) { + tracing::error!("{:?}", err); + } }); } SendLspNotification::METHOD => { @@ -1059,7 +1079,7 @@ impl PluginHostHandler { let volt_id = self.volt_id.clone(); let volt_display_name = self.volt_display_name.clone(); thread::spawn(move || { - let _ = LspClient::start( + if let Err(err) = LspClient::start( catalog_rpc, params.document_selector, workspace, @@ -1071,7 +1091,9 @@ impl PluginHostHandler { params.server_uri, params.server_args, params.options, - ); + ) { + tracing::error!("{:?}", err); + } }); } PublishDiagnostics::METHOD => { diff --git a/lapce-proxy/src/plugin/wasi.rs b/lapce-proxy/src/plugin/wasi.rs index 741d44a71f..8a87884dd5 100644 --- a/lapce-proxy/src/plugin/wasi.rs +++ b/lapce-proxy/src/plugin/wasi.rs @@ -129,7 +129,9 @@ impl PluginServerHandler for Plugin { params: Params, from: String, ) { - let _ = self.host.handle_notification(method, params, from); + if let Err(err) = self.host.handle_notification(method, params, from) { + tracing::error!("{:?}", err); + } } fn handle_host_request( @@ -260,7 +262,9 @@ pub fn load_all_volts( Some(meta) }) .collect(); - let _ = plugin_rpc.unactivated_volts(volts); + if let Err(err) = plugin_rpc.unactivated_volts(volts) { + tracing::error!("{:?}", err); + } } /// Find all installed volts. @@ -502,7 +506,10 @@ pub fn start_volt( handle_plugin_server_message(&local_rpc, &msg, &volt_name) { if let Ok(msg) = serde_json::to_string(&resp) { - let _ = writeln!(local_stdin.write().unwrap(), "{msg}"); + if let Err(err) = writeln!(local_stdin.write().unwrap(), "{msg}") + { + tracing::error!("{:?}", err); + } } } } @@ -535,9 +542,13 @@ pub fn start_volt( break; } if let Ok(msg) = serde_json::to_string(&msg) { - let _ = writeln!(stdin.write().unwrap(), "{msg}"); + if let Err(err) = writeln!(stdin.write().unwrap(), "{msg}") { + tracing::error!("{:?}", err); + } + } + if let Err(err) = handle_rpc.call(&mut store, ()) { + tracing::error!("{:?}", err); } - let _ = handle_rpc.call(&mut store, ()); } } if let Some(id) = exist_id { diff --git a/lapce-proxy/src/terminal.rs b/lapce-proxy/src/terminal.rs index 202eb48fa2..8202f0ec26 100644 --- a/lapce-proxy/src/terminal.rs +++ b/lapce-proxy/src/terminal.rs @@ -45,8 +45,12 @@ impl TerminalSender { } pub fn send(&self, msg: Msg) { - let _ = self.tx.send(msg); - let _ = self.poller.notify(); + if let Err(err) = self.tx.send(msg) { + tracing::error!("{:?}", err); + } + if let Err(err) = self.poller.notify() { + tracing::error!("{:?}", err); + } } } @@ -137,7 +141,9 @@ impl Terminal { if let Some(tty::ChildEvent::Exited(exited_code)) = self.pty.next_child_event() { - let _ = self.pty_read(&core_rpc, &mut buf); + if let Err(err) = self.pty_read(&core_rpc, &mut buf) { + tracing::error!("{:?}", err); + } exit_code = exited_code; break 'event_loop; } @@ -195,7 +201,9 @@ impl Terminal { } } core_rpc.terminal_process_stopped(self.term_id, exit_code); - let _ = self.pty.deregister(&self.poller); + if let Err(err) = self.pty.deregister(&self.poller) { + tracing::error!("{:?}", err); + } } /// Drain the channel. diff --git a/lapce-proxy/src/watcher.rs b/lapce-proxy/src/watcher.rs index 6d2713375c..88a5fdfbe1 100644 --- a/lapce-proxy/src/watcher.rs +++ b/lapce-proxy/src/watcher.rs @@ -145,7 +145,9 @@ impl FileWatcher { let mode = mode_from_bool(w.recursive); if !state.watchees.iter().any(|w2| w.path == w2.path) { - let _ = self.inner.watch(&w.path, mode); + if let Err(err) = self.inner.watch(&w.path, mode) { + tracing::error!("{:?}", err); + } } state.watchees.push(w); @@ -165,7 +167,9 @@ impl FileWatcher { if let Some(idx) = idx { let removed = state.watchees.remove(idx); if !state.watchees.iter().any(|w| w.path == removed.path) { - let _ = self.inner.unwatch(&removed.path); + if let Err(err) = self.inner.unwatch(&removed.path) { + tracing::error!("{:?}", err); + } } //TODO: Ideally we would be tracking what paths we're watching with // some prefix-tree-like structure, which would let us keep track @@ -189,7 +193,9 @@ impl FileWatcher { .collect::>(); for (path, mode) in to_add { - let _ = self.inner.watch(&path, mode); + if let Err(err) = self.inner.watch(&path, mode) { + tracing::error!("{:?}", err); + } } } } From 2815e17cc43bb354b451a1fafd47e2bd3cd6c0eb Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Thu, 5 Sep 2024 17:50:33 +0800 Subject: [PATCH 36/69] 1. add some error log for lapce-app (#3467) --- lapce-app/src/app.rs | 56 ++++++++++++++++------ lapce-app/src/config.rs | 14 ++++-- lapce-app/src/config/watcher.rs | 4 +- lapce-app/src/db.rs | 85 +++++++++++++++++++++++++-------- lapce-app/src/proxy.rs | 11 +++-- 5 files changed, 127 insertions(+), 43 deletions(-) diff --git a/lapce-app/src/app.rs b/lapce-app/src/app.rs index 024e5ff39e..971dfe4b37 100644 --- a/lapce-app/src/app.rs +++ b/lapce-app/src/app.rs @@ -254,7 +254,9 @@ impl AppData { match cmd { AppCommand::SaveApp => { let db: Arc = use_context().unwrap(); - let _ = db.save_app(self); + if let Err(err) = db.save_app(self) { + tracing::error!("{:?}", err); + } } AppCommand::WindowClosed(window_id) => { if self.app_terminated.get_untracked() { @@ -262,7 +264,9 @@ impl AppData { } let db: Arc = use_context().unwrap(); if self.windows.with_untracked(|w| w.len()) == 1 { - let _ = db.insert_app(self.clone()); + if let Err(err) = db.insert_app(self.clone()) { + tracing::error!("{:?}", err); + } } let window_data = self .windows @@ -271,7 +275,9 @@ impl AppData { if let Some(window_data) = window_data { window_data.scope.dispose(); } - let _ = db.save_app(self); + if let Err(err) = db.save_app(self) { + tracing::error!("{:?}", err); + } } AppCommand::CloseWindow(window_id) => { floem::close_window(window_id); @@ -3720,7 +3726,9 @@ pub fn launch() { #[cfg(feature = "updater")] crate::update::cleanup(); - let _ = lapce_proxy::register_lapce_path(); + if let Err(err) = lapce_proxy::register_lapce_path() { + tracing::error!("{:?}", err); + } let db = match LapceDb::new() { Ok(db) => Arc::new(db), Err(e) => { @@ -3743,16 +3751,24 @@ pub fn launch() { let (tx, rx) = crossbeam_channel::bounded(1); let mut watcher = notify::recommended_watcher(ConfigWatcher::new(tx)).unwrap(); if let Some(path) = LapceConfig::settings_file() { - let _ = watcher.watch(&path, notify::RecursiveMode::Recursive); + if let Err(err) = watcher.watch(&path, notify::RecursiveMode::Recursive) { + tracing::error!("{:?}", err); + } } if let Some(path) = Directory::themes_directory() { - let _ = watcher.watch(&path, notify::RecursiveMode::Recursive); + if let Err(err) = watcher.watch(&path, notify::RecursiveMode::Recursive) { + tracing::error!("{:?}", err); + } } if let Some(path) = LapceConfig::keymaps_file() { - let _ = watcher.watch(&path, notify::RecursiveMode::Recursive); + if let Err(err) = watcher.watch(&path, notify::RecursiveMode::Recursive) { + tracing::error!("{:?}", err); + } } if let Some(path) = Directory::plugins_directory() { - let _ = watcher.watch(&path, notify::RecursiveMode::Recursive); + if let Err(err) = watcher.watch(&path, notify::RecursiveMode::Recursive) { + tracing::error!("{:?}", err); + } } let windows = scope.create_rw_signal(im::HashMap::new()); @@ -3855,7 +3871,9 @@ pub fn launch() { }); std::thread::spawn(move || loop { if let Ok(release) = crate::update::get_latest_release() { - let _ = tx.send(release); + if let Err(err) = tx.send(release) { + tracing::error!("{:?}", err); + } } std::thread::sleep(std::time::Duration::from_secs(60 * 60)); }); @@ -3873,7 +3891,9 @@ pub fn launch() { } }); std::thread::spawn(move || { - let _ = listen_local_socket(tx); + if let Err(err) = listen_local_socket(tx) { + tracing::error!("{:?}", err); + } }); } @@ -3887,7 +3907,9 @@ pub fn launch() { app.on_event(move |event| match event { floem::AppEvent::WillTerminate => { app_data.app_terminated.set(true); - let _ = db.insert_app(app_data.clone()); + if let Err(err) = db.insert_app(app_data.clone()) { + tracing::error!("{:?}", err); + } } floem::AppEvent::Reopen { has_visible_windows, @@ -3993,7 +4015,9 @@ pub fn try_open_in_existing_process( fn listen_local_socket(tx: Sender) -> Result<()> { let local_socket = Directory::local_socket() .ok_or_else(|| anyhow!("can't get local socket folder"))?; - let _ = std::fs::remove_file(&local_socket); + if let Err(err) = std::fs::remove_file(&local_socket) { + tracing::error!("{:?}", err); + } let socket = interprocess::local_socket::LocalSocketListener::bind(local_socket)?; @@ -4012,8 +4036,12 @@ fn listen_local_socket(tx: Sender) -> Result<()> { } let stream_ref = reader.get_mut(); - let _ = stream_ref.write_all(b"received"); - let _ = stream_ref.flush(); + if let Err(err) = stream_ref.write_all(b"received") { + tracing::error!("{:?}", err); + } + if let Err(err) = stream_ref.flush() { + tracing::error!("{:?}", err); + } } }); } diff --git a/lapce-app/src/config.rs b/lapce-app/src/config.rs index 7c70e30340..1611db2b78 100644 --- a/lapce-app/src/config.rs +++ b/lapce-app/src/config.rs @@ -566,10 +566,13 @@ impl LapceConfig { let path = Directory::config_directory()?.join("settings.toml"); if !path.exists() { - let _ = std::fs::OpenOptions::new() + if let Err(err) = std::fs::OpenOptions::new() .create_new(true) .write(true) - .open(&path); + .open(&path) + { + tracing::error!("{:?}", err); + } } Some(path) @@ -579,10 +582,13 @@ impl LapceConfig { let path = Directory::config_directory()?.join("keymaps.toml"); if !path.exists() { - let _ = std::fs::OpenOptions::new() + if let Err(err) = std::fs::OpenOptions::new() .create_new(true) .write(true) - .open(&path); + .open(&path) + { + tracing::error!("{:?}", err); + } } Some(path) diff --git a/lapce-app/src/config/watcher.rs b/lapce-app/src/config/watcher.rs index c5ea690322..af30e2e97b 100644 --- a/lapce-app/src/config/watcher.rs +++ b/lapce-app/src/config/watcher.rs @@ -30,7 +30,9 @@ impl notify::EventHandler for ConfigWatcher { std::thread::sleep(std::time::Duration::from_millis( 500, )); - let _ = tx.send(()); + if let Err(err) = tx.send(()) { + tracing::error!("{:?}", err); + } config_mutex .store(false, std::sync::atomic::Ordering::Relaxed); }); diff --git a/lapce-app/src/db.rs b/lapce-app/src/db.rs index 05bb1cf0ab..db8750e052 100644 --- a/lapce-app/src/db.rs +++ b/lapce-app/src/db.rs @@ -51,7 +51,9 @@ impl LapceDb { .ok_or_else(|| anyhow!("can't get config directory"))? .join("db"); let workspace_folder = folder.join("workspaces"); - let _ = std::fs::create_dir_all(&workspace_folder); + if let Err(err) = std::fs::create_dir_all(&workspace_folder) { + tracing::error!("{:?}", err); + } let (save_tx, save_rx) = unbounded(); @@ -66,26 +68,44 @@ impl LapceDb { let event = save_rx.recv()?; match event { SaveEvent::App(info) => { - let _ = local_db.insert_app_info(info); + if let Err(err) = local_db.insert_app_info(info) { + tracing::error!("{:?}", err); + } } SaveEvent::Workspace(workspace, info) => { - let _ = local_db.insert_workspace(&workspace, &info); + if let Err(err) = + local_db.insert_workspace(&workspace, &info) + { + tracing::error!("{:?}", err); + } } SaveEvent::RecentWorkspace(workspace) => { - let _ = local_db.insert_recent_workspace(workspace); + if let Err(err) = local_db.insert_recent_workspace(workspace) + { + tracing::error!("{:?}", err); + } } SaveEvent::Doc(info) => { - let _ = local_db.insert_doc(&info); + if let Err(err) = local_db.insert_doc(&info) { + tracing::error!("{:?}", err); + } } SaveEvent::DisabledVolts(volts) => { - let _ = local_db.insert_disabled_volts(volts); + if let Err(err) = local_db.insert_disabled_volts(volts) { + tracing::error!("{:?}", err); + } } SaveEvent::WorkspaceDisabledVolts(workspace, volts) => { - let _ = local_db - .insert_workspace_disabled_volts(workspace, volts); + if let Err(err) = local_db + .insert_workspace_disabled_volts(workspace, volts) + { + tracing::error!("{:?}", err); + } } SaveEvent::PanelOrder(order) => { - let _ = local_db.insert_panel_orders(&order); + if let Err(err) = local_db.insert_panel_orders(&order) { + tracing::error!("{:?}", err); + } } } } @@ -100,7 +120,9 @@ impl LapceDb { } pub fn save_disabled_volts(&self, volts: Vec) { - let _ = self.save_tx.send(SaveEvent::DisabledVolts(volts)); + if let Err(err) = self.save_tx.send(SaveEvent::DisabledVolts(volts)) { + tracing::error!("{:?}", err); + } } pub fn save_workspace_disabled_volts( @@ -108,9 +130,12 @@ impl LapceDb { workspace: Arc, volts: Vec, ) { - let _ = self + if let Err(err) = self .save_tx - .send(SaveEvent::WorkspaceDisabledVolts(workspace, volts)); + .send(SaveEvent::WorkspaceDisabledVolts(workspace, volts)) + { + tracing::error!("{:?}", err); + } } pub fn insert_disabled_volts(&self, volts: Vec) -> Result<()> { @@ -127,7 +152,9 @@ impl LapceDb { let folder = self .workspace_folder .join(workspace_folder_name(&workspace)); - let _ = std::fs::create_dir_all(&folder); + if let Err(err) = std::fs::create_dir_all(&folder) { + tracing::error!("{:?}", err); + } let volts = serde_json::to_string_pretty(&volts)?; std::fs::write(folder.join(DISABLED_VOLTS), volts)?; @@ -219,7 +246,9 @@ impl LapceDb { info: &WorkspaceInfo, ) -> Result<()> { let folder = self.workspace_folder.join(workspace_folder_name(workspace)); - let _ = std::fs::create_dir_all(&folder); + if let Err(err) = std::fs::create_dir_all(&folder) { + tracing::error!("{:?}", err); + } let workspace_info = serde_json::to_string_pretty(info)?; std::fs::write(folder.join(WORKSPACE_INFO), workspace_info)?; Ok(()) @@ -228,7 +257,9 @@ impl LapceDb { pub fn save_app(&self, data: &AppData) -> Result<()> { let windows = data.windows.get_untracked(); for (_, window) in &windows { - let _ = self.save_window(window.clone()); + if let Err(err) = self.save_window(window.clone()) { + tracing::error!("{:?}", err); + } } let info = AppInfo { @@ -259,7 +290,9 @@ impl LapceDb { return Ok(()); } for (_, window) in &windows { - let _ = self.insert_window(window.clone()); + if let Err(err) = self.insert_window(window.clone()) { + tracing::error!("{:?}", err); + } } let info = AppInfo { windows: windows @@ -299,14 +332,18 @@ impl LapceDb { pub fn save_window(&self, data: WindowData) -> Result<()> { for (_, window_tab) in data.window_tabs.get_untracked().into_iter() { - let _ = self.save_window_tab(window_tab); + if let Err(err) = self.save_window_tab(window_tab) { + tracing::error!("{:?}", err); + } } Ok(()) } pub fn insert_window(&self, data: WindowData) -> Result<()> { for (_, window_tab) in data.window_tabs.get_untracked().into_iter() { - let _ = self.insert_window_tab(window_tab); + if let Err(err) = self.insert_window_tab(window_tab) { + tracing::error!("{:?}", err); + } } let info = data.info(); let info = serde_json::to_string_pretty(&info)?; @@ -340,7 +377,9 @@ impl LapceDb { } pub fn save_panel_orders(&self, order: PanelOrder) { - let _ = self.save_tx.send(SaveEvent::PanelOrder(order)); + if let Err(err) = self.save_tx.send(SaveEvent::PanelOrder(order)) { + tracing::error!("{:?}", err); + } } fn insert_panel_orders(&self, order: &PanelOrder) -> Result<()> { @@ -362,7 +401,9 @@ impl LapceDb { scroll_offset: (scroll_offset.x, scroll_offset.y), cursor_offset, }; - let _ = self.save_tx.send(SaveEvent::Doc(info)); + if let Err(err) = self.save_tx.send(SaveEvent::Doc(info)) { + tracing::error!("{:?}", err); + } } fn insert_doc(&self, info: &DocInfo) -> Result<()> { @@ -370,7 +411,9 @@ impl LapceDb { .workspace_folder .join(workspace_folder_name(&info.workspace)) .join(WORKSPACE_FILES); - let _ = std::fs::create_dir_all(&folder); + if let Err(err) = std::fs::create_dir_all(&folder) { + tracing::error!("{:?}", err); + } let contents = serde_json::to_string_pretty(info)?; std::fs::write(folder.join(doc_path_name(&info.path)), contents)?; Ok(()) diff --git a/lapce-app/src/proxy.rs b/lapce-app/src/proxy.rs index 6bacb93561..28503a0c67 100644 --- a/lapce-app/src/proxy.rs +++ b/lapce-app/src/proxy.rs @@ -128,12 +128,17 @@ pub fn new_proxy( impl CoreHandler for Proxy { fn handle_notification(&mut self, rpc: lapce_rpc::core::CoreNotification) { if let CoreNotification::UpdateTerminal { term_id, content } = &rpc { - let _ = self + if let Err(err) = self .term_tx - .send((*term_id, TermEvent::UpdateContent(content.to_vec()))); + .send((*term_id, TermEvent::UpdateContent(content.to_vec()))) + { + tracing::error!("{:?}", err); + } return; } - let _ = self.tx.send(rpc); + if let Err(err) = self.tx.send(rpc) { + tracing::error!("{:?}", err); + } } fn handle_request( From a239243287634757004732296d5e2d2d19327a53 Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Thu, 5 Sep 2024 17:51:09 +0800 Subject: [PATCH 37/69] 1. add another error log for lapce-app (#3468) --- lapce-app/src/editor.rs | 20 ++++++++++++++------ lapce-app/src/keypress/keymap.rs | 20 +++++++++++++++----- lapce-app/src/palette.rs | 16 ++++++++++++---- lapce-app/src/plugin.rs | 4 +++- lapce-app/src/proxy/remote.rs | 32 ++++++++++++++++++++++++++------ lapce-app/src/terminal/data.rs | 6 +++++- lapce-app/src/terminal/event.rs | 14 ++++++++++---- lapce-app/src/terminal/raw.rs | 19 +++++++++++++------ lapce-app/src/update.rs | 5 ++++- lapce-app/src/window.rs | 18 ++++++++++++++---- lapce-app/src/window_tab.rs | 7 +++++-- 11 files changed, 121 insertions(+), 40 deletions(-) diff --git a/lapce-app/src/editor.rs b/lapce-app/src/editor.rs index 1b5a1d4df8..8e817f6608 100644 --- a/lapce-app/src/editor.rs +++ b/lapce-app/src/editor.rs @@ -1447,7 +1447,9 @@ impl EditorData { return; }; - let _ = item.apply(self, start_offset); + if let Err(err) = item.apply(self, start_offset) { + tracing::error!("{:?}", err); + } } fn next_inline_completion(&self) { @@ -1613,7 +1615,9 @@ impl EditorData { { return; } - let _ = editor.apply_completion_item(&item); + if let Err(err) = editor.apply_completion_item(&item) { + tracing::error!("{:?}", err); + } }); self.common.proxy.completion_resolve( item.plugin_id, @@ -1631,8 +1635,8 @@ impl EditorData { send(item); }, ); - } else { - let _ = self.apply_completion_item(&item.item); + } else if let Err(err) = self.apply_completion_item(&item.item) { + tracing::error!("{:?}", err); } } } @@ -2238,7 +2242,9 @@ impl EditorData { let proxy = self.common.proxy.clone(); std::thread::spawn(move || { proxy.get_document_formatting(path, move |result| { - let _ = tx.send(result); + if let Err(err) = tx.send(result) { + tracing::error!("{:?}", err); + } }); let result = rx.recv_timeout(std::time::Duration::from_secs(1)); send(result); @@ -2270,7 +2276,9 @@ impl EditorData { let proxy = self.common.proxy.clone(); std::thread::spawn(move || { proxy.get_document_formatting(path, move |result| { - let _ = tx.send(result); + if let Err(err) = tx.send(result) { + tracing::error!("{:?}", err); + } }); let result = rx.recv_timeout(std::time::Duration::from_secs(1)); send(result); diff --git a/lapce-app/src/keypress/keymap.rs b/lapce-app/src/keypress/keymap.rs index 53c92a055c..ac0d2aacbe 100644 --- a/lapce-app/src/keypress/keymap.rs +++ b/lapce-app/src/keypress/keymap.rs @@ -317,19 +317,29 @@ impl FromStr for KeyMapKey { impl Display for KeyMapPress { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { if self.mods.contains(Modifiers::CONTROL) { - let _ = f.write_str("Ctrl+"); + if let Err(err) = f.write_str("Ctrl+") { + tracing::error!("{:?}", err); + } } if self.mods.contains(Modifiers::ALT) { - let _ = f.write_str("Alt+"); + if let Err(err) = f.write_str("Alt+") { + tracing::error!("{:?}", err); + } } if self.mods.contains(Modifiers::ALTGR) { - let _ = f.write_str("AltGr+"); + if let Err(err) = f.write_str("AltGr+") { + tracing::error!("{:?}", err); + } } if self.mods.contains(Modifiers::META) { - let _ = f.write_str("Meta+"); + if let Err(err) = f.write_str("Meta+") { + tracing::error!("{:?}", err); + } } if self.mods.contains(Modifiers::SHIFT) { - let _ = f.write_str("Shift+"); + if let Err(err) = f.write_str("Shift+") { + tracing::error!("{:?}", err); + } } f.write_str(&self.key.to_string()) } diff --git a/lapce-app/src/palette.rs b/lapce-app/src/palette.rs index 92ddb6fa2a..e402717b68 100644 --- a/lapce-app/src/palette.rs +++ b/lapce-app/src/palette.rs @@ -154,7 +154,11 @@ impl PaletteData { let run_id = run_id.get_untracked(); let preselect_index = preselect_index.try_update(|i| i.take()).unwrap(); - let _ = tx.send((run_id, input.input, items, preselect_index)); + if let Err(err) = + tx.send((run_id, input.input, items, preselect_index)) + { + tracing::error!("{:?}", err); + } }); } // this effect only monitors input change @@ -166,7 +170,9 @@ impl PaletteData { } let items = items.get_untracked(); let run_id = run_id.get_untracked(); - let _ = tx.send((run_id, input.input, items, None)); + if let Err(err) = tx.send((run_id, input.input, items, None)) { + tracing::error!("{:?}", err); + } kind }); } @@ -1610,12 +1616,14 @@ impl PaletteData { items, &mut matcher, ) { - let _ = resp_tx.send(( + if let Err(err) = resp_tx.send(( current_run_id, input, filtered_items, preselect_index, - )); + )) { + tracing::error!("{:?}", err); + } } } else { return; diff --git a/lapce-app/src/plugin.rs b/lapce-app/src/plugin.rs index 03a4c7ae14..d659cef297 100644 --- a/lapce-app/src/plugin.rs +++ b/lapce-app/src/plugin.rs @@ -434,7 +434,9 @@ impl PluginData { let buf = resp.bytes()?.to_vec(); if let Some(path) = cache_file_path.as_ref() { - let _ = std::fs::write(path, &buf); + if let Err(err) = std::fs::write(path, &buf) { + tracing::error!("{:?}", err); + } } buf diff --git a/lapce-app/src/proxy/remote.rs b/lapce-app/src/proxy/remote.rs index 919583e3ce..e4aa7e066e 100644 --- a/lapce-app/src/proxy/remote.rs +++ b/lapce-app/src/proxy/remote.rs @@ -181,14 +181,26 @@ pub fn start_remote( for msg in local_proxy_rpc.rx() { match msg { ProxyRpc::Request(id, rpc) => { - let _ = local_writer_tx.send(RpcMessage::Request(id, rpc)); + if let Err(err) = + local_writer_tx.send(RpcMessage::Request(id, rpc)) + { + tracing::error!("{:?}", err); + } } ProxyRpc::Notification(rpc) => { - let _ = local_writer_tx.send(RpcMessage::Notification(rpc)); + if let Err(err) = + local_writer_tx.send(RpcMessage::Notification(rpc)) + { + tracing::error!("{:?}", err); + } } ProxyRpc::Shutdown => { - let _ = child.kill(); - let _ = child.wait(); + if let Err(err) = child.kill() { + tracing::error!("{:?}", err); + } + if let Err(err) = child.wait() { + tracing::error!("{:?}", err); + } return; } } @@ -203,10 +215,18 @@ pub fn start_remote( let core_rpc = core_rpc.clone(); std::thread::spawn(move || match core_rpc.request(req) { Ok(resp) => { - let _ = writer_tx.send(RpcMessage::Response(id, resp)); + if let Err(err) = + writer_tx.send(RpcMessage::Response(id, resp)) + { + tracing::error!("{:?}", err); + } } Err(e) => { - let _ = writer_tx.send(RpcMessage::Error(id, e)); + if let Err(err) = + writer_tx.send(RpcMessage::Error(id, e)) + { + tracing::error!("{:?}", err); + } } }); } diff --git a/lapce-app/src/terminal/data.rs b/lapce-app/src/terminal/data.rs index a7c60b2054..97820621e8 100644 --- a/lapce-app/src/terminal/data.rs +++ b/lapce-app/src/terminal/data.rs @@ -420,7 +420,11 @@ impl TerminalData { { let raw = raw.clone(); - let _ = common.term_tx.send((term_id, TermEvent::NewTerminal(raw))); + if let Err(err) = + common.term_tx.send((term_id, TermEvent::NewTerminal(raw))) + { + tracing::error!("{:?}", err); + } common.proxy.new_terminal(term_id, profile); } diff --git a/lapce-app/src/terminal/event.rs b/lapce-app/src/terminal/event.rs index 03359b22a9..19455954df 100644 --- a/lapce-app/src/terminal/event.rs +++ b/lapce-app/src/terminal/event.rs @@ -50,13 +50,19 @@ pub fn terminal_update_process( if last_event.is_some() { if last_redraw.elapsed().as_millis() > 10 { last_redraw = Instant::now(); - let _ = term_notification_tx - .send(TermNotification::RequestPaint); + if let Err(err) = term_notification_tx + .send(TermNotification::RequestPaint) + { + tracing::error!("{:?}", err); + } } } else { last_redraw = Instant::now(); - let _ = term_notification_tx - .send(TermNotification::RequestPaint); + if let Err(err) = + term_notification_tx.send(TermNotification::RequestPaint) + { + tracing::error!("{:?}", err); + } } } } diff --git a/lapce-app/src/terminal/raw.rs b/lapce-app/src/terminal/raw.rs index ba88bbae74..4471340255 100644 --- a/lapce-app/src/terminal/raw.rs +++ b/lapce-app/src/terminal/raw.rs @@ -27,15 +27,22 @@ impl EventListener for EventProxy { self.proxy.terminal_write(self.term_id, s); } alacritty_terminal::event::Event::MouseCursorDirty => { - let _ = self + if let Err(err) = self .term_notification_tx - .send(TermNotification::RequestPaint); + .send(TermNotification::RequestPaint) + { + tracing::error!("{:?}", err); + } } alacritty_terminal::event::Event::Title(s) => { - let _ = self.term_notification_tx.send(TermNotification::SetTitle { - term_id: self.term_id, - title: s, - }); + if let Err(err) = + self.term_notification_tx.send(TermNotification::SetTitle { + term_id: self.term_id, + title: s, + }) + { + tracing::error!("{:?}", err); + } } _ => (), } diff --git a/lapce-app/src/update.rs b/lapce-app/src/update.rs index 535a62a168..e3ed5e8a4f 100644 --- a/lapce-app/src/update.rs +++ b/lapce-app/src/update.rs @@ -217,7 +217,10 @@ pub fn cleanup() { // Clean up backup exe after an update if let Ok(process_path) = std::env::current_exe() { if let Some(dst_parent) = process_path.parent() { - let _ = std::fs::remove_file(dst_parent.join("lapce.exe.bak")); + if let Err(err) = std::fs::remove_file(dst_parent.join("lapce.exe.bak")) + { + tracing::error!("{:?}", err); + } } } } diff --git a/lapce-app/src/window.rs b/lapce-app/src/window.rs index 84bc83c553..c377093ac1 100644 --- a/lapce-app/src/window.rs +++ b/lapce-app/src/window.rs @@ -203,13 +203,19 @@ impl WindowData { match cmd { WindowCommand::SetWorkspace { workspace } => { let db: Arc = use_context().unwrap(); - let _ = db.update_recent_workspace(&workspace); + if let Err(err) = db.update_recent_workspace(&workspace) { + tracing::error!("{:?}", err); + } let active = self.active.get_untracked(); self.window_tabs.with_untracked(|window_tabs| { if !window_tabs.is_empty() { let active = window_tabs.len().saturating_sub(1).min(active); - let _ = db.insert_window_tab(window_tabs[active].1.clone()); + if let Err(err) = + db.insert_window_tab(window_tabs[active].1.clone()) + { + tracing::error!("{:?}", err); + } } }); @@ -234,7 +240,9 @@ impl WindowData { } WindowCommand::NewWorkspaceTab { workspace, end } => { let db: Arc = use_context().unwrap(); - let _ = db.update_recent_workspace(&workspace); + if let Err(err) = db.update_recent_workspace(&workspace) { + tracing::error!("{:?}", err); + } let window_tab = Rc::new(WindowTabData::new( self.scope, @@ -275,7 +283,9 @@ impl WindowData { let (_, old_window_tab) = window_tabs.remove(index); old_window_tab.proxy.shutdown(); let db: Arc = use_context().unwrap(); - let _ = db.save_window_tab(old_window_tab); + if let Err(err) = db.save_window_tab(old_window_tab) { + tracing::error!("{:?}", err); + } } }); diff --git a/lapce-app/src/window_tab.rs b/lapce-app/src/window_tab.rs index 839fac200c..bee8aefa6f 100644 --- a/lapce-app/src/window_tab.rs +++ b/lapce-app/src/window_tab.rs @@ -2067,10 +2067,13 @@ impl WindowTabData { } } CoreNotification::TerminalProcessStopped { term_id, exit_code } => { - let _ = self + if let Err(err) = self .common .term_tx - .send((*term_id, TermEvent::CloseTerminal)); + .send((*term_id, TermEvent::CloseTerminal)) + { + tracing::error!("{:?}", err); + } self.terminal.terminal_stopped(term_id, *exit_code); if self .terminal From 3ff7ba9ca8dea080c1623b49a151a3744a73b77f Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Thu, 5 Sep 2024 17:51:22 +0800 Subject: [PATCH 38/69] 1. add error log for lapce-core (#3469) --- lapce-core/src/directory.rs | 40 +++++++++++++++++++++++++++--------- lapce-core/src/syntax/mod.rs | 11 +++++++--- 2 files changed, 38 insertions(+), 13 deletions(-) diff --git a/lapce-core/src/directory.rs b/lapce-core/src/directory.rs index 6541b3352e..42849773fd 100644 --- a/lapce-core/src/directory.rs +++ b/lapce-core/src/directory.rs @@ -37,7 +37,9 @@ impl Directory { Some(dir) => { let dir = dir.data_local_dir(); if !dir.exists() { - let _ = std::fs::create_dir_all(dir); + if let Err(err) = std::fs::create_dir_all(dir) { + tracing::error!("{:?}", err); + } } Some(dir.to_path_buf()) } @@ -51,7 +53,9 @@ impl Directory { if let Some(dir) = Self::data_local_directory() { let dir = dir.join("logs"); if !dir.exists() { - let _ = std::fs::create_dir(&dir); + if let Err(err) = std::fs::create_dir(&dir) { + tracing::error!("{:?}", err); + } } Some(dir) } else { @@ -64,7 +68,9 @@ impl Directory { if let Some(dir) = Self::data_local_directory() { let dir = dir.join("cache"); if !dir.exists() { - let _ = std::fs::create_dir(&dir); + if let Err(err) = std::fs::create_dir(&dir) { + tracing::error!("{:?}", err); + } } Some(dir) } else { @@ -79,7 +85,9 @@ impl Directory { if let Some(dir) = Self::data_local_directory() { let dir = dir.join("proxy"); if !dir.exists() { - let _ = std::fs::create_dir(&dir); + if let Err(err) = std::fs::create_dir(&dir) { + tracing::error!("{:?}", err); + } } Some(dir) } else { @@ -92,7 +100,9 @@ impl Directory { if let Some(dir) = Self::data_local_directory() { let dir = dir.join("themes"); if !dir.exists() { - let _ = std::fs::create_dir(&dir); + if let Err(err) = std::fs::create_dir(&dir) { + tracing::error!("{:?}", err); + } } Some(dir) } else { @@ -106,7 +116,9 @@ impl Directory { if let Some(dir) = Self::data_local_directory() { let dir = dir.join("plugins"); if !dir.exists() { - let _ = std::fs::create_dir(&dir); + if let Err(err) = std::fs::create_dir(&dir) { + tracing::error!("{:?}", err); + } } Some(dir) } else { @@ -120,7 +132,9 @@ impl Directory { Some(dir) => { let dir = dir.config_dir(); if !dir.exists() { - let _ = std::fs::create_dir_all(dir); + if let Err(err) = std::fs::create_dir_all(dir) { + tracing::error!("{:?}", err); + } } Some(dir.to_path_buf()) } @@ -136,7 +150,9 @@ impl Directory { if let Some(dir) = Self::data_local_directory() { let dir = dir.join("updates"); if !dir.exists() { - let _ = std::fs::create_dir(&dir); + if let Err(err) = std::fs::create_dir(&dir) { + tracing::error!("{:?}", err); + } } Some(dir) } else { @@ -148,7 +164,9 @@ impl Directory { if let Some(dir) = Self::config_directory() { let dir = dir.join("queries"); if !dir.exists() { - let _ = std::fs::create_dir(&dir); + if let Err(err) = std::fs::create_dir(&dir) { + tracing::error!("{:?}", err); + } } Some(dir) @@ -161,7 +179,9 @@ impl Directory { if let Some(dir) = Self::data_local_directory() { let dir = dir.join("grammars"); if !dir.exists() { - let _ = std::fs::create_dir(&dir); + if let Err(err) = std::fs::create_dir(&dir) { + tracing::error!("{:?}", err); + } } Some(dir) diff --git a/lapce-core/src/syntax/mod.rs b/lapce-core/src/syntax/mod.rs index 0a7c764bcf..063628e1da 100644 --- a/lapce-core/src/syntax/mod.rs +++ b/lapce-core/src/syntax/mod.rs @@ -491,7 +491,9 @@ impl SyntaxLayers { let cancel_flag = AtomicUsize::new(0); if let Some(source) = source { - let _ = syntax.update(0, 0, source, None, &cancel_flag); + if let Err(err) = syntax.update(0, 0, source, None, &cancel_flag) { + tracing::error!("{:?}", err); + } } syntax @@ -949,8 +951,11 @@ impl Syntax { None => return, }; let edits = edits.filter(|edits| new_rev == self.rev + edits.len() as u64); - let _ = - layers.update(self.rev, new_rev, &new_text, edits, &self.cancel_flag); + if let Err(err) = + layers.update(self.rev, new_rev, &new_text, edits, &self.cancel_flag) + { + tracing::error!("{:?}", err); + } let tree = layers.try_tree(); let styles = if tree.is_some() { From 35c5ff451aba7b22bdd9f208c6b770fff5a444dc Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Thu, 5 Sep 2024 17:51:37 +0800 Subject: [PATCH 39/69] 1. add error log for lapce-rpc (#3470) --- lapce-rpc/src/core.rs | 17 +++++++++++++---- lapce-rpc/src/proxy.rs | 16 ++++++++++++---- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/lapce-rpc/src/core.rs b/lapce-rpc/src/core.rs index d52b74019e..8c8f206f50 100644 --- a/lapce-rpc/src/core.rs +++ b/lapce-rpc/src/core.rs @@ -203,7 +203,9 @@ impl CoreRpcHandler { ) { let tx = { self.pending.lock().remove(&id) }; if let Some(tx) = tx { - let _ = tx.send(response); + if let Err(err) = tx.send(response) { + tracing::error!("{:?}", err); + } } } @@ -214,7 +216,9 @@ impl CoreRpcHandler { let mut pending = self.pending.lock(); pending.insert(id, tx); } - let _ = self.tx.send(CoreRpc::Request(id, request)); + if let Err(err) = self.tx.send(CoreRpc::Request(id, request)) { + tracing::error!("{:?}", err); + } rx.recv().unwrap_or_else(|_| { Err(RpcError { code: 0, @@ -224,11 +228,16 @@ impl CoreRpcHandler { } pub fn shutdown(&self) { - let _ = self.tx.send(CoreRpc::Shutdown); + if let Err(err) = self.tx.send(CoreRpc::Shutdown) { + tracing::error!("{:?}", err); + } } pub fn notification(&self, notification: CoreNotification) { - let _ = self.tx.send(CoreRpc::Notification(Box::new(notification))); + if let Err(err) = self.tx.send(CoreRpc::Notification(Box::new(notification))) + { + tracing::error!("{:?}", err); + } } pub fn workspace_file_change(&self) { diff --git a/lapce-rpc/src/proxy.rs b/lapce-rpc/src/proxy.rs index 50473ebedd..3125b78863 100644 --- a/lapce-rpc/src/proxy.rs +++ b/lapce-rpc/src/proxy.rs @@ -466,7 +466,9 @@ impl ResponseHandler { match self { ResponseHandler::Callback(f) => f(result), ResponseHandler::Chan(tx) => { - let _ = tx.send(result); + if let Err(err) = tx.send(result) { + tracing::error!("{:?}", err); + } } } } @@ -525,7 +527,9 @@ impl ProxyRpcHandler { self.pending.lock().insert(id, rh); - let _ = self.tx.send(ProxyRpc::Request(id, request)); + if let Err(err) = self.tx.send(ProxyRpc::Request(id, request)) { + tracing::error!("{:?}", err); + } } fn request(&self, request: ProxyRequest) -> Result { @@ -559,7 +563,9 @@ impl ProxyRpcHandler { } pub fn notification(&self, notification: ProxyNotification) { - let _ = self.tx.send(ProxyRpc::Notification(notification)); + if let Err(err) = self.tx.send(ProxyRpc::Notification(notification)) { + tracing::error!("{:?}", err); + } } pub fn git_init(&self) { @@ -596,7 +602,9 @@ impl ProxyRpcHandler { pub fn shutdown(&self) { self.notification(ProxyNotification::Shutdown {}); - let _ = self.tx.send(ProxyRpc::Shutdown); + if let Err(err) = self.tx.send(ProxyRpc::Shutdown) { + tracing::error!("{:?}", err); + } } pub fn initialize( From 0403fb2bcc75060f3dca15934f9fb3b7d210e74e Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Thu, 5 Sep 2024 23:38:04 +0800 Subject: [PATCH 40/69] 1. When closing a debug task, a stop request should be sent to the DAP (Debug Adapter Protocol). (#3473) 2. add some log --- lapce-app/src/terminal/data.rs | 18 ++++++++++++++++-- lapce-app/src/terminal/panel.rs | 6 +++--- lapce-app/src/window_tab.rs | 1 + lapce-proxy/src/plugin/dap.rs | 8 ++++---- 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/lapce-app/src/terminal/data.rs b/lapce-app/src/terminal/data.rs index 97820621e8..2471ef8c9b 100644 --- a/lapce-app/src/terminal/data.rs +++ b/lapce-app/src/terminal/data.rs @@ -10,7 +10,7 @@ use alacritty_terminal::{ use anyhow::anyhow; use floem::{ keyboard::{Key, KeyEvent, Modifiers, NamedKey}, - reactive::{RwSignal, Scope, SignalGet, SignalUpdate}, + reactive::{RwSignal, Scope, SignalGet, SignalUpdate, SignalWith}, views::editor::text::SystemClipboard, }; use lapce_core::{ @@ -32,7 +32,7 @@ use super::{ }; use crate::{ command::{CommandExecuted, CommandKind, InternalCommand}, - debug::RunDebugProcess, + debug::{RunDebugMode, RunDebugProcess}, keypress::{condition::Condition, KeyPressFocus}, window_tab::CommonData, workspace::LapceWorkspace, @@ -746,6 +746,20 @@ impl TerminalData { .proxy .terminal_resize(self.term_id, width, height); } + + pub fn stop(&self) { + if let Some(dap_id) = self.run_debug.with_untracked(|x| { + if let Some(process) = x { + if !process.is_prelaunch && process.mode == RunDebugMode::Debug { + return Some(process.config.dap_id); + } + } + None + }) { + self.common.proxy.dap_stop(dap_id); + } + self.common.proxy.terminal_close(self.term_id); + } } /// [`RunDebugConfig`] with expanded out program/arguments/etc. Used for creating the terminal. diff --git a/lapce-app/src/terminal/panel.rs b/lapce-app/src/terminal/panel.rs index c71951a045..f93564d775 100644 --- a/lapce-app/src/terminal/panel.rs +++ b/lapce-app/src/terminal/panel.rs @@ -250,9 +250,9 @@ impl TerminalPanelData { }) .flatten() { - close_tab - .into_iter() - .for_each(|x| self.common.proxy.terminal_close(x.1.term_id)); + for (_, data) in close_tab { + data.stop(); + } } self.update_debug_active_term(); } diff --git a/lapce-app/src/window_tab.rs b/lapce-app/src/window_tab.rs index bee8aefa6f..55886643a6 100644 --- a/lapce-app/src/window_tab.rs +++ b/lapce-app/src/window_tab.rs @@ -2067,6 +2067,7 @@ impl WindowTabData { } } CoreNotification::TerminalProcessStopped { term_id, exit_code } => { + debug!("TerminalProcessStopped {:?}, {:?}", term_id, exit_code); if let Err(err) = self .common .term_tx diff --git a/lapce-proxy/src/plugin/dap.rs b/lapce-proxy/src/plugin/dap.rs index 20e8509cf0..20e040c93b 100644 --- a/lapce-proxy/src/plugin/dap.rs +++ b/lapce-proxy/src/plugin/dap.rs @@ -119,6 +119,7 @@ impl DapClient { writer.flush()?; } } + tracing::debug!("thread(write to dap) exited"); Ok(()) }); @@ -145,6 +146,7 @@ impl DapClient { ); dap_rpc.disconnected(); + tracing::debug!("thread(read from dap) exited"); return; } }; @@ -402,10 +404,8 @@ impl DapClient { self.breakpoints = breakpoints; if !self.terminated { self.stop(); - } else { - if let Err(err) = self.check_restart() { - tracing::error!("{:?}", err); - } + } else if let Err(err) = self.check_restart() { + tracing::error!("{:?}", err); } } } From ef65fa614a2ff922244fa14019c867bb5c26fc59 Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Thu, 5 Sep 2024 23:38:26 +0800 Subject: [PATCH 41/69] 1. add error logging (#3474) --- lapce-core/src/language.rs | 10 ++- lapce-core/src/syntax/mod.rs | 55 ++++++++------- lapce-proxy/src/plugin/catalog.rs | 108 +++++++++++++++++++----------- lapce-proxy/src/plugin/dap.rs | 19 +++--- lapce-proxy/src/plugin/lsp.rs | 40 ++++++----- lapce-proxy/src/plugin/mod.rs | 14 ++-- lapce-proxy/src/plugin/wasi.rs | 7 +- lapce-proxy/src/terminal.rs | 11 ++- 8 files changed, 165 insertions(+), 99 deletions(-) diff --git a/lapce-core/src/language.rs b/lapce-core/src/language.rs index 292f66d9ee..c2979253e0 100644 --- a/lapce-core/src/language.rs +++ b/lapce-core/src/language.rs @@ -1765,10 +1765,14 @@ impl LapceLanguage { let grammar_fn_name = self.grammar_fn_name(); if let Some(grammars_dir) = Directory::grammars_directory() { - if let Ok(grammar) = - self::load_grammar(&grammar_name, &grammar_fn_name, &grammars_dir) + match self::load_grammar(&grammar_name, &grammar_fn_name, &grammars_dir) { - return Some(grammar); + Ok(grammar) => { + return Some(grammar); + } + Err(err) => { + tracing::error!("{:?}", err); + } } }; diff --git a/lapce-core/src/syntax/mod.rs b/lapce-core/src/syntax/mod.rs index 063628e1da..8295432d03 100644 --- a/lapce-core/src/syntax/mod.rs +++ b/lapce-core/src/syntax/mod.rs @@ -725,22 +725,26 @@ impl SyntaxLayers { if let (Some(injection_capture), Some(content_node)) = (injection_capture, content_node) { - if let Ok(config) = - (injection_callback)(&injection_capture) - { - let ranges = intersect_ranges( - &layer.ranges, - &[content_node], - included_children, - ); - - if !ranges.is_empty() { - if content_node.start_byte() < last_injection_end - { - continue; + match (injection_callback)(&injection_capture) { + Ok(config) => { + let ranges = intersect_ranges( + &layer.ranges, + &[content_node], + included_children, + ); + + if !ranges.is_empty() { + if content_node.start_byte() + < last_injection_end + { + continue; + } + last_injection_end = content_node.end_byte(); + injections.push((config, ranges)); } - last_injection_end = content_node.end_byte(); - injections.push((config, ranges)); + } + Err(err) => { + tracing::error!("{:?}", err); } } } @@ -752,14 +756,19 @@ impl SyntaxLayers { if let (Some(lang_name), false) = (lang_name, content_nodes.is_empty()) { - if let Ok(config) = (injection_callback)(&lang_name) { - let ranges = intersect_ranges( - &layer.ranges, - &content_nodes, - included_children, - ); - if !ranges.is_empty() { - injections.push((config, ranges)); + match (injection_callback)(&lang_name) { + Ok(config) => { + let ranges = intersect_ranges( + &layer.ranges, + &content_nodes, + included_children, + ); + if !ranges.is_empty() { + injections.push((config, ranges)); + } + } + Err(err) => { + tracing::error!("{:?}", err); } } } diff --git a/lapce-proxy/src/plugin/catalog.rs b/lapce-proxy/src/plugin/catalog.rs index bee41ffbcf..841aa63662 100644 --- a/lapce-proxy/src/plugin/catalog.rs +++ b/lapce-proxy/src/plugin/catalog.rs @@ -246,21 +246,31 @@ impl PluginCatalog { { let mut builder = globset::GlobSetBuilder::new(); for glob in globs { - if let Ok(glob) = globset::Glob::new(glob) { - builder.add(glob); + match globset::Glob::new(glob) { + Ok(glob) => { + builder.add(glob); + } + Err(err) => { + tracing::error!("{:?}", err); + } } } - if let Ok(matcher) = builder.build() { - if !matcher.is_empty() { - for entry in walkdir::WalkDir::new(workspace) - .into_iter() - .flatten() - { - if matcher.is_match(entry.path()) { - return Some(id.clone()); + match builder.build() { + Ok(matcher) => { + if !matcher.is_empty() { + for entry in walkdir::WalkDir::new(workspace) + .into_iter() + .flatten() + { + if matcher.is_match(entry.path()) { + return Some(id.clone()); + } } } } + Err(err) => { + tracing::error!("{:?}", err); + } } } } @@ -272,8 +282,13 @@ impl PluginCatalog { } pub fn handle_did_open_text_document(&mut self, document: TextDocumentItem) { - if let Ok(path) = document.uri.to_file_path() { - self.open_files.insert(path, document.language_id.clone()); + match document.uri.to_file_path() { + Ok(path) => { + self.open_files.insert(path, document.language_id.clone()); + } + Err(err) => { + tracing::error!("{:?}", err); + } } let to_be_activated: Vec = self @@ -476,21 +491,25 @@ impl PluginCatalog { } PluginServerLoaded(plugin) => { // TODO: check if the server has did open registered - if let Ok(ProxyResponse::GetOpenFilesContentResponse { items }) = - self.plugin_rpc.proxy_rpc.get_open_files_content() - { - for item in items { - let language_id = Some(item.language_id.clone()); - let path = item.uri.to_file_path().ok(); - plugin.server_notification( - DidOpenTextDocument::METHOD, - DidOpenTextDocumentParams { - text_document: item, - }, - language_id, - path, - true, - ); + match self.plugin_rpc.proxy_rpc.get_open_files_content() { + Ok(ProxyResponse::GetOpenFilesContentResponse { items }) => { + for item in items { + let language_id = Some(item.language_id.clone()); + let path = item.uri.to_file_path().ok(); + plugin.server_notification( + DidOpenTextDocument::METHOD, + DidOpenTextDocumentParams { + text_document: item, + }, + language_id, + path, + true, + ); + } + } + Ok(_) => {} + Err(err) => { + tracing::error!("{:?}", err); } } @@ -578,7 +597,7 @@ impl PluginCatalog { .and_then(|ty| self.debuggers.get(ty).cloned()) { thread::spawn(move || { - if let Ok(dap_rpc) = DapClient::start( + match DapClient::start( DapServer { program: debugger.program, args: debugger.args.unwrap_or_default(), @@ -588,12 +607,18 @@ impl PluginCatalog { breakpoints, plugin_rpc.clone(), ) { - if let Err(err) = plugin_rpc.dap_loaded(dap_rpc.clone()) - { - tracing::error!("{:?}", err); - } + Ok(dap_rpc) => { + if let Err(err) = + plugin_rpc.dap_loaded(dap_rpc.clone()) + { + tracing::error!("{:?}", err); + } - if let Err(err) = dap_rpc.launch(&config) { + if let Err(err) = dap_rpc.launch(&config) { + tracing::error!("{:?}", err); + } + } + Err(err) => { tracing::error!("{:?}", err); } } @@ -680,12 +705,17 @@ impl PluginCatalog { path.clone(), breakpoints, move |result: Result| { - if let Ok(resp) = result { - core_rpc.dap_breakpoints_resp( - dap_id, - path, - resp.breakpoints.unwrap_or_default(), - ); + match result { + Ok(resp) => { + core_rpc.dap_breakpoints_resp( + dap_id, + path, + resp.breakpoints.unwrap_or_default(), + ); + } + Err(err) => { + tracing::error!("{:?}", err); + } } }, ); diff --git a/lapce-proxy/src/plugin/dap.rs b/lapce-proxy/src/plugin/dap.rs index 20e040c93b..d7fbb11a44 100644 --- a/lapce-proxy/src/plugin/dap.rs +++ b/lapce-proxy/src/plugin/dap.rs @@ -215,14 +215,17 @@ impl DapClient { match event { DapEvent::Initialized(_) => { for (path, breakpoints) in self.breakpoints.clone().into_iter() { - if let Ok(breakpoints) = - self.dap_rpc.set_breakpoints(path.clone(), breakpoints) - { - self.plugin_rpc.core_rpc.dap_breakpoints_resp( - self.config.dap_id, - path, - breakpoints.breakpoints.unwrap_or_default(), - ); + match self.dap_rpc.set_breakpoints(path.clone(), breakpoints) { + Ok(breakpoints) => { + self.plugin_rpc.core_rpc.dap_breakpoints_resp( + self.config.dap_id, + path, + breakpoints.breakpoints.unwrap_or_default(), + ); + } + Err(err) => { + tracing::error!("{:?}", err); + } } } // send dap configurations here diff --git a/lapce-proxy/src/plugin/lsp.rs b/lapce-proxy/src/plugin/lsp.rs index defaf36d99..13ca50e460 100644 --- a/lapce-proxy/src/plugin/lsp.rs +++ b/lapce-proxy/src/plugin/lsp.rs @@ -379,29 +379,35 @@ impl LspClient { root_path: None, work_done_progress_params: WorkDoneProgressParams::default(), }; - if let Ok(value) = self.server_rpc.server_request( + match self.server_rpc.server_request( Initialize::METHOD, params, None, None, false, ) { - let result: InitializeResult = serde_json::from_value(value).unwrap(); - self.host.server_capabilities = result.capabilities; - self.server_rpc.server_notification( - Initialized::METHOD, - InitializedParams {}, - None, - None, - false, - ); - if self - .plugin_rpc - .plugin_server_loaded(self.server_rpc.clone()) - .is_err() - { - self.server_rpc.shutdown(); - self.shutdown(); + Ok(value) => { + let result: InitializeResult = + serde_json::from_value(value).unwrap(); + self.host.server_capabilities = result.capabilities; + self.server_rpc.server_notification( + Initialized::METHOD, + InitializedParams {}, + None, + None, + false, + ); + if self + .plugin_rpc + .plugin_server_loaded(self.server_rpc.clone()) + .is_err() + { + self.server_rpc.shutdown(); + self.shutdown(); + } + } + Err(err) => { + tracing::error!("{:?}", err); } } // move |result| { diff --git a/lapce-proxy/src/plugin/mod.rs b/lapce-proxy/src/plugin/mod.rs index 187c9b525d..e89e9f5527 100644 --- a/lapce-proxy/src/plugin/mod.rs +++ b/lapce-proxy/src/plugin/mod.rs @@ -1081,8 +1081,8 @@ impl PluginCatalogRpcHandler { params, language_id, Some(path.to_path_buf()), - move |plugin_id, result| { - if let Ok(value) = result { + move |plugin_id, result| match result { + Ok(value) => { if let Ok(resp) = serde_json::from_value::(value) { @@ -1090,6 +1090,9 @@ impl PluginCatalogRpcHandler { .completion_response(request_id, input, resp, plugin_id); } } + Err(err) => { + tracing::error!("{:?}", err); + } }, ); } @@ -1160,14 +1163,17 @@ impl PluginCatalogRpcHandler { language_id, Some(path.to_path_buf()), true, - move |plugin_id, result| { - if let Ok(value) = result { + move |plugin_id, result| match result { + Ok(value) => { if let Ok(resp) = serde_json::from_value::(value) { core_rpc .signature_help_response(request_id, resp, plugin_id); } } + Err(err) => { + tracing::error!("{:?}", err); + } }, ); } diff --git a/lapce-proxy/src/plugin/wasi.rs b/lapce-proxy/src/plugin/wasi.rs index 8a87884dd5..227be496a4 100644 --- a/lapce-proxy/src/plugin/wasi.rs +++ b/lapce-proxy/src/plugin/wasi.rs @@ -222,8 +222,8 @@ impl Plugin { None, None, false, - move |value| { - if let Ok(value) = value { + move |value| match value { + Ok(value) => { if let Ok(result) = serde_json::from_value(value) { server_rpc.handle_rpc(PluginServerRpc::Handler( PluginHandlerNotification::InitializeResult(result), @@ -237,6 +237,9 @@ impl Plugin { ); } } + Err(err) => { + tracing::error!("{:?}", err); + } }, ); } diff --git a/lapce-proxy/src/terminal.rs b/lapce-proxy/src/terminal.rs index 8202f0ec26..84ab5f8b41 100644 --- a/lapce-proxy/src/terminal.rs +++ b/lapce-proxy/src/terminal.rs @@ -280,9 +280,14 @@ impl Terminal { fn workdir(profile: &TerminalProfile) -> Option { if let Some(cwd) = &profile.workdir { - if let Ok(cwd) = cwd.to_file_path() { - if cwd.exists() { - return Some(cwd); + match cwd.to_file_path() { + Ok(cwd) => { + if cwd.exists() { + return Some(cwd); + } + } + Err(err) => { + tracing::error!("{:?}", err); } } } From dcc179e39978384cf95d020a23a0fef8bbab0dbb Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Fri, 6 Sep 2024 20:53:52 +0800 Subject: [PATCH 42/69] Set the Palette to default to the Help Palette. (#3463) * 1. Set the Palette to default to the Help Palette. * Optimize the default item. --- lapce-app/src/palette.rs | 51 ++++++++++++++++++++++++++++++++--- lapce-app/src/palette/kind.rs | 9 +++++-- 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/lapce-app/src/palette.rs b/lapce-app/src/palette.rs index e402717b68..cb73492daa 100644 --- a/lapce-app/src/palette.rs +++ b/lapce-app/src/palette.rs @@ -20,6 +20,7 @@ use floem::{ SignalWith, }, }; +use im::Vector; use itertools::Itertools; use lapce_core::{ buffer::rope_text::RopeText, command::FocusCommand, language::LapceLanguage, @@ -367,6 +368,7 @@ impl PaletteData { PaletteKind::File | PaletteKind::DiffFiles => { self.get_files(); } + PaletteKind::PaletteHelpAndFile => self.get_palette_help_and_file(), PaletteKind::Line => { self.get_lines(); } @@ -416,7 +418,12 @@ impl PaletteData { /// Initialize the palette with a list of the available palette kinds. fn get_palette_help(&self) { - let items = PaletteKind::iter() + let items = self.get_palette_help_items(); + self.items.set(items); + } + + fn get_palette_help_items(&self) -> Vector { + PaletteKind::iter() .filter_map(|kind| { // Don't include PaletteHelp as the user is already here. (kind != PaletteKind::PaletteHelp) @@ -443,9 +450,47 @@ impl PaletteData { indices: vec![], } }) - .collect(); + .collect() + } - self.items.set(items); + fn get_palette_help_and_file(&self) { + let help_items: Vector = self.get_palette_help_items(); + let workspace = self.workspace.clone(); + let set_items = self.items.write_only(); + let send = + create_ext_action(self.common.scope, move |items: Vec| { + let items = items + .into_iter() + .map(|full_path| { + // Strip the workspace prefix off the path, to avoid clutter + let path = + if let Some(workspace_path) = workspace.path.as_ref() { + full_path + .strip_prefix(workspace_path) + .unwrap_or(&full_path) + .to_path_buf() + } else { + full_path.clone() + }; + let filter_text = path.to_string_lossy().into_owned(); + PaletteItem { + content: PaletteItemContent::File { path, full_path }, + filter_text, + score: 0, + indices: Vec::new(), + } + }) + .collect::>(); + set_items.update(|x| { + x.append(help_items); + x.append(items); + }); + }); + self.common.proxy.get_files(move |result| { + if let Ok(ProxyResponse::GetFilesResponse { items }) = result { + send(items); + } + }); } /// Initialize the palette with the files in the current workspace. diff --git a/lapce-app/src/palette/kind.rs b/lapce-app/src/palette/kind.rs index 5cd123073d..847d092b26 100644 --- a/lapce-app/src/palette/kind.rs +++ b/lapce-app/src/palette/kind.rs @@ -23,6 +23,7 @@ pub enum PaletteKind { SCMReferences, TerminalProfile, DiffFiles, + PaletteHelpAndFile, } impl PaletteKind { @@ -46,6 +47,7 @@ impl PaletteKind { | PaletteKind::Language | PaletteKind::LineEnding | PaletteKind::SCMReferences + | PaletteKind::PaletteHelpAndFile | PaletteKind::DiffFiles => "", #[cfg(windows)] PaletteKind::WslHost => "", @@ -62,6 +64,7 @@ impl PaletteKind { _ if input.starts_with('>') => PaletteKind::Workspace, _ if input.starts_with(':') => PaletteKind::Command, _ if input.starts_with('<') => PaletteKind::TerminalProfile, + _ if input.is_empty() => PaletteKind::PaletteHelpAndFile, _ => PaletteKind::File, } } @@ -79,7 +82,9 @@ impl PaletteKind { } PaletteKind::Workspace => Some(LapceWorkbenchCommand::PaletteWorkspace), PaletteKind::Command => Some(LapceWorkbenchCommand::PaletteCommand), - PaletteKind::File => Some(LapceWorkbenchCommand::Palette), + PaletteKind::File | PaletteKind::PaletteHelpAndFile => { + Some(LapceWorkbenchCommand::Palette) + } PaletteKind::Reference => None, // InternalCommand::PaletteReferences PaletteKind::SshHost => Some(LapceWorkbenchCommand::ConnectSshHost), #[cfg(windows)] @@ -124,7 +129,7 @@ impl PaletteKind { | PaletteKind::IconTheme | PaletteKind::Language | PaletteKind::LineEnding - | PaletteKind::SCMReferences + | PaletteKind::SCMReferences | PaletteKind::PaletteHelpAndFile | PaletteKind::DiffFiles => input, PaletteKind::PaletteHelp | PaletteKind::Command From f6ff3aac4e4b5c564cce26b85798780e5dd46629 Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Fri, 6 Sep 2024 22:17:51 +0800 Subject: [PATCH 43/69] 1. When receiving a DapStopped event, display the Debug panel. (#3476) --- lapce-app/src/window_tab.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/lapce-app/src/window_tab.rs b/lapce-app/src/window_tab.rs index 55886643a6..57c31d5619 100644 --- a/lapce-app/src/window_tab.rs +++ b/lapce-app/src/window_tab.rs @@ -2105,6 +2105,7 @@ impl WindowTabData { stack_frames, variables, } => { + self.show_panel(PanelKind::Debug); self.terminal .dap_stopped(dap_id, stopped, stack_frames, variables); } From ad3c7e0bfcef8151c9f85b6d2b4db350be263937 Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Sat, 7 Sep 2024 01:13:21 +0800 Subject: [PATCH 44/69] add some error logging (#3478) --- lapce-app/src/app.rs | 56 +++++++++++++++++++-------------- lapce-app/src/config/watcher.rs | 7 +++-- 2 files changed, 38 insertions(+), 25 deletions(-) diff --git a/lapce-app/src/app.rs b/lapce-app/src/app.rs index 971dfe4b37..cd231c0208 100644 --- a/lapce-app/src/app.rs +++ b/lapce-app/src/app.rs @@ -363,24 +363,29 @@ impl AppData { } } else if files.is_empty() { // There were no dirs and no files specified, so we'll load the last windows - if let Ok(app_info) = db.get_app() { - for info in app_info.windows { - let config = self - .default_window_config() - .size(info.size) - .position(info.pos); - let config = if cfg!(target_os = "macos") - || self.config.get_untracked().core.custom_titlebar - { - config.show_titlebar(false) - } else { - config - }; - let app_data = self.clone(); - app = app.window( - move |window_id| app_data.app_view(window_id, info), - Some(config), - ); + match db.get_app() { + Ok(app_info) => { + for info in app_info.windows { + let config = self + .default_window_config() + .size(info.size) + .position(info.pos); + let config = if cfg!(target_os = "macos") + || self.config.get_untracked().core.custom_titlebar + { + config.show_titlebar(false) + } else { + config + }; + let app_data = self.clone(); + app = app.window( + move |window_id| app_data.app_view(window_id, info), + Some(config), + ); + } + } + Err(err) => { + tracing::error!("{:?}", err); } } } @@ -3715,11 +3720,16 @@ pub fn launch() { // If the cli is not requesting a new window, and we're not developing a plugin, we try to open // in the existing Lapce process if !cli.new { - if let Ok(socket) = get_socket() { - if let Err(e) = try_open_in_existing_process(socket, &cli.paths) { - trace!(TraceLevel::ERROR, "failed to open path(s): {e}"); - }; - return; + match get_socket() { + Ok(socket) => { + if let Err(e) = try_open_in_existing_process(socket, &cli.paths) { + trace!(TraceLevel::ERROR, "failed to open path(s): {e}"); + }; + return; + } + Err(err) => { + tracing::error!("{:?}", err); + } } } diff --git a/lapce-app/src/config/watcher.rs b/lapce-app/src/config/watcher.rs index af30e2e97b..7f65fd65f6 100644 --- a/lapce-app/src/config/watcher.rs +++ b/lapce-app/src/config/watcher.rs @@ -9,8 +9,8 @@ pub struct ConfigWatcher { impl notify::EventHandler for ConfigWatcher { fn handle_event(&mut self, event: notify::Result) { - if let Ok(event) = event { - match event.kind { + match event { + Ok(event) => match event.kind { notify::EventKind::Create(_) | notify::EventKind::Modify(_) | notify::EventKind::Remove(_) => { @@ -39,6 +39,9 @@ impl notify::EventHandler for ConfigWatcher { } } _ => {} + }, + Err(err) => { + tracing::error!("{:?}", err); } } } From 6f629148ff4f85b7f15d4056318131a856876dde Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Sat, 7 Sep 2024 21:57:30 +0100 Subject: [PATCH 45/69] some improvements on palette help and file --- lapce-app/src/command.rs | 4 +++ lapce-app/src/palette.rs | 53 ++++++++++------------------------- lapce-app/src/palette/kind.rs | 22 ++++++++++----- lapce-app/src/title.rs | 2 +- lapce-app/src/window_tab.rs | 1 + 5 files changed, 36 insertions(+), 46 deletions(-) diff --git a/lapce-app/src/command.rs b/lapce-app/src/command.rs index 1d6aa0ed27..c0ebf762df 100644 --- a/lapce-app/src/command.rs +++ b/lapce-app/src/command.rs @@ -390,6 +390,10 @@ pub enum LapceWorkbenchCommand { #[strum(serialize = "palette.palette_help")] PaletteHelp, + #[strum(message = "List Palette Types and Files")] + #[strum(serialize = "palette.palette_help_and_file")] + PaletteHelpAndFile, + #[strum(message = "Run and Debug Restart Current Running")] #[strum(serialize = "palette.run_and_debug_restart")] RunAndDebugRestart, diff --git a/lapce-app/src/palette.rs b/lapce-app/src/palette.rs index cb73492daa..2a2445241e 100644 --- a/lapce-app/src/palette.rs +++ b/lapce-app/src/palette.rs @@ -368,7 +368,7 @@ impl PaletteData { PaletteKind::File | PaletteKind::DiffFiles => { self.get_files(); } - PaletteKind::PaletteHelpAndFile => self.get_palette_help_and_file(), + PaletteKind::HelpAndFile => self.get_palette_help_and_file(), PaletteKind::Line => { self.get_lines(); } @@ -455,6 +455,13 @@ impl PaletteData { fn get_palette_help_and_file(&self) { let help_items: Vector = self.get_palette_help_items(); + self.get_files_and_prepend(Some(help_items)); + } + + // get the files in the current workspace + // and prepend items if prepend is some + // e.g. help_and_file + fn get_files_and_prepend(&self, prepend: Option>) { let workspace = self.workspace.clone(); let set_items = self.items.write_only(); let send = @@ -481,10 +488,12 @@ impl PaletteData { } }) .collect::>(); - set_items.update(|x| { - x.append(help_items); - x.append(items); - }); + let mut new_items = im::Vector::new(); + if let Some(prepend) = prepend { + new_items.append(prepend); + } + new_items.append(items); + set_items.set(new_items); }); self.common.proxy.get_files(move |result| { if let Ok(ProxyResponse::GetFilesResponse { items }) = result { @@ -495,39 +504,7 @@ impl PaletteData { /// Initialize the palette with the files in the current workspace. fn get_files(&self) { - let workspace = self.workspace.clone(); - let set_items = self.items.write_only(); - let send = - create_ext_action(self.common.scope, move |items: Vec| { - let items = items - .into_iter() - .map(|full_path| { - // Strip the workspace prefix off the path, to avoid clutter - let path = - if let Some(workspace_path) = workspace.path.as_ref() { - full_path - .strip_prefix(workspace_path) - .unwrap_or(&full_path) - .to_path_buf() - } else { - full_path.clone() - }; - let filter_text = path.to_string_lossy().into_owned(); - PaletteItem { - content: PaletteItemContent::File { path, full_path }, - filter_text, - score: 0, - indices: Vec::new(), - } - }) - .collect::>(); - set_items.set(items); - }); - self.common.proxy.get_files(move |result| { - if let Ok(ProxyResponse::GetFilesResponse { items }) = result { - send(items); - } - }); + self.get_files_and_prepend(None); } /// Initialize the palette with the lines in the current document. diff --git a/lapce-app/src/palette/kind.rs b/lapce-app/src/palette/kind.rs index 847d092b26..1a1b894134 100644 --- a/lapce-app/src/palette/kind.rs +++ b/lapce-app/src/palette/kind.rs @@ -23,7 +23,7 @@ pub enum PaletteKind { SCMReferences, TerminalProfile, DiffFiles, - PaletteHelpAndFile, + HelpAndFile, } impl PaletteKind { @@ -47,7 +47,7 @@ impl PaletteKind { | PaletteKind::Language | PaletteKind::LineEnding | PaletteKind::SCMReferences - | PaletteKind::PaletteHelpAndFile + | PaletteKind::HelpAndFile | PaletteKind::DiffFiles => "", #[cfg(windows)] PaletteKind::WslHost => "", @@ -64,7 +64,6 @@ impl PaletteKind { _ if input.starts_with('>') => PaletteKind::Workspace, _ if input.starts_with(':') => PaletteKind::Command, _ if input.starts_with('<') => PaletteKind::TerminalProfile, - _ if input.is_empty() => PaletteKind::PaletteHelpAndFile, _ => PaletteKind::File, } } @@ -82,8 +81,9 @@ impl PaletteKind { } PaletteKind::Workspace => Some(LapceWorkbenchCommand::PaletteWorkspace), PaletteKind::Command => Some(LapceWorkbenchCommand::PaletteCommand), - PaletteKind::File | PaletteKind::PaletteHelpAndFile => { - Some(LapceWorkbenchCommand::Palette) + PaletteKind::File => Some(LapceWorkbenchCommand::Palette), + PaletteKind::HelpAndFile => { + Some(LapceWorkbenchCommand::PaletteHelpAndFile) } PaletteKind::Reference => None, // InternalCommand::PaletteReferences PaletteKind::SshHost => Some(LapceWorkbenchCommand::ConnectSshHost), @@ -129,7 +129,7 @@ impl PaletteKind { | PaletteKind::IconTheme | PaletteKind::Language | PaletteKind::LineEnding - | PaletteKind::SCMReferences | PaletteKind::PaletteHelpAndFile + | PaletteKind::SCMReferences | PaletteKind::HelpAndFile | PaletteKind::DiffFiles => input, PaletteKind::PaletteHelp | PaletteKind::Command @@ -146,9 +146,17 @@ impl PaletteKind { /// Get the palette kind that it should be considered as based on the current /// [`PaletteKind`] and the current input. pub fn get_palette_kind(&self, input: &str) -> PaletteKind { - if self != &PaletteKind::File && self.symbol() == "" { + if self == &PaletteKind::HelpAndFile && input.is_empty() { return *self; } + + if self != &PaletteKind::File + && self != &PaletteKind::HelpAndFile + && self.symbol() == "" + { + return *self; + } + PaletteKind::from_input(input) } } diff --git a/lapce-app/src/title.rs b/lapce-app/src/title.rs index 287c79e636..4acff239d0 100644 --- a/lapce-app/src/title.rs +++ b/lapce-app/src/title.rs @@ -255,7 +255,7 @@ fn middle( .on_event_stop(EventListener::PointerDown, |_| {}) .on_click_stop(move |_| { if workspace.clone().path.is_some() { - workbench_command.send(LapceWorkbenchCommand::Palette); + workbench_command.send(LapceWorkbenchCommand::PaletteHelpAndFile); } else { workbench_command.send(LapceWorkbenchCommand::PaletteWorkspace); } diff --git a/lapce-app/src/window_tab.rs b/lapce-app/src/window_tab.rs index 57c31d5619..3ce6b272ac 100644 --- a/lapce-app/src/window_tab.rs +++ b/lapce-app/src/window_tab.rs @@ -1058,6 +1058,7 @@ impl WindowTabData { // ==== Palette Commands ==== PaletteHelp => self.palette.run(PaletteKind::PaletteHelp), + PaletteHelpAndFile => self.palette.run(PaletteKind::HelpAndFile), PaletteLine => { self.palette.run(PaletteKind::Line); } From fc021a6b192855c31b64202778721429d9c33899 Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Mon, 9 Sep 2024 17:55:40 +0800 Subject: [PATCH 46/69] Supports tracing the output of the task. (#3480) * Supports tracing the output of the task. * cargo fmt --- lapce-app/src/code_lens.rs | 19 ++++++++++++------- lapce-app/src/terminal/data.rs | 6 ++++++ lapce-app/src/terminal/raw.rs | 30 ++++++++++++++++++++++++++++++ lapce-app/src/window_tab.rs | 1 + lapce-rpc/src/dap_types.rs | 2 ++ 5 files changed, 51 insertions(+), 7 deletions(-) diff --git a/lapce-app/src/code_lens.rs b/lapce-app/src/code_lens.rs index 3dddfd164f..2d6f25fe2a 100644 --- a/lapce-app/src/code_lens.rs +++ b/lapce-app/src/code_lens.rs @@ -39,12 +39,12 @@ impl CodeLensData { pub fn run(&self, command: &str, args: Vec) { match command { "rust-analyzer.runSingle" | "rust-analyzer.debugSingle" => { - if let Some(config) = self.get_rust_command_config(&args) { - let mode = if command == "rust-analyzer.runSingle" { - RunDebugMode::Run - } else { - RunDebugMode::Debug - }; + let mode = if command == "rust-analyzer.runSingle" { + RunDebugMode::Run + } else { + RunDebugMode::Debug + }; + if let Some(config) = self.get_rust_command_config(&args, mode) { self.common .internal_command .send(InternalCommand::RunAndDebug { mode, config }); @@ -56,7 +56,11 @@ impl CodeLensData { } } - fn get_rust_command_config(&self, args: &[Value]) -> Option { + fn get_rust_command_config( + &self, + args: &[Value], + mode: RunDebugMode, + ) -> Option { if let Some(args) = args.first() { let Ok(mut cargo_args) = serde_json::from_value::(args.clone()) @@ -85,6 +89,7 @@ impl CodeLensData { prelaunch: None, debug_command: None, dap_id: Default::default(), + tracing_output: mode == RunDebugMode::Debug, }) } else { tracing::error!("no args"); diff --git a/lapce-app/src/terminal/data.rs b/lapce-app/src/terminal/data.rs index 2471ef8c9b..c007cf2304 100644 --- a/lapce-app/src/terminal/data.rs +++ b/lapce-app/src/terminal/data.rs @@ -367,10 +367,16 @@ impl TerminalData { common: Rc, launch_error: RwSignal>, ) -> Arc> { + let tracing_output = run_debug + .as_ref() + .map(|run_debug| run_debug.config.tracing_output) + .unwrap_or_default(); + let raw = Arc::new(RwLock::new(RawTerminal::new( term_id, common.proxy.clone(), common.term_notification_tx.clone(), + tracing_output, ))); let mut profile = profile.unwrap_or_default(); diff --git a/lapce-app/src/terminal/raw.rs b/lapce-app/src/terminal/raw.rs index 4471340255..30039b674f 100644 --- a/lapce-app/src/terminal/raw.rs +++ b/lapce-app/src/terminal/raw.rs @@ -49,10 +49,37 @@ impl EventListener for EventProxy { } } +pub enum TerminalOutPut { + Ingore, + Output(Vec), +} + +impl TerminalOutPut { + pub fn new(tracing_output: bool) -> Self { + if !tracing_output { + TerminalOutPut::Ingore + } else { + TerminalOutPut::Output(Vec::new()) + } + } + pub fn update(&mut self, output: &[u8]) { + if let Self::Output(content) = self { + content.extend(output) + } + } + pub fn output(&self) -> Option<&[u8]> { + match self { + TerminalOutPut::Ingore => None, + TerminalOutPut::Output(content) => Some(content), + } + } +} + pub struct RawTerminal { pub parser: ansi::Processor, pub term: Term, pub scroll_delta: f64, + pub output: TerminalOutPut, } impl RawTerminal { @@ -60,6 +87,7 @@ impl RawTerminal { term_id: TermId, proxy: ProxyRpcHandler, term_notification_tx: Sender, + tracing_output: bool, ) -> Self { let config = alacritty_terminal::term::Config { semantic_escape_chars: ",│`|\"' ()[]{}<>\t".to_string(), @@ -79,10 +107,12 @@ impl RawTerminal { parser, term, scroll_delta: 0.0, + output: TerminalOutPut::new(tracing_output), } } pub fn update_content(&mut self, content: Vec) { + self.output.update(&content); for byte in content { self.parser.advance(&mut self.term, byte); } diff --git a/lapce-app/src/window_tab.rs b/lapce-app/src/window_tab.rs index 3ce6b272ac..88a2debdf8 100644 --- a/lapce-app/src/window_tab.rs +++ b/lapce-app/src/window_tab.rs @@ -1473,6 +1473,7 @@ impl WindowTabData { prelaunch: None, debug_command: None, dap_id: Default::default(), + tracing_output: false, }; self.common .internal_command diff --git a/lapce-rpc/src/dap_types.rs b/lapce-rpc/src/dap_types.rs index ba26ef2804..d2ee6a4a3c 100644 --- a/lapce-rpc/src/dap_types.rs +++ b/lapce-rpc/src/dap_types.rs @@ -57,6 +57,8 @@ pub struct RunDebugConfig { pub debug_command: Option>, #[serde(skip)] pub dap_id: DapId, + #[serde(default)] + pub tracing_output: bool, } pub trait Request { From 88028d5af27699ba544851f6d63dd4bcc0f57038 Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Mon, 9 Sep 2024 17:56:45 +0800 Subject: [PATCH 47/69] When running a task, display the terminal(debug) panel (#3481) --- lapce-app/src/terminal/panel.rs | 8 +++++--- lapce-app/src/window_tab.rs | 11 +++++++++-- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/lapce-app/src/terminal/panel.rs b/lapce-app/src/terminal/panel.rs index f93564d775..097455fc44 100644 --- a/lapce-app/src/terminal/panel.rs +++ b/lapce-app/src/terminal/panel.rs @@ -460,14 +460,15 @@ impl TerminalPanelData { }) } - pub fn restart_run_debug(&self, term_id: TermId) -> Option<()> { + /// Return whether it is in debug mode. + pub fn restart_run_debug(&self, term_id: TermId) -> Option { let (_, terminal_tab, index, terminal) = self.get_terminal_in_tab(&term_id)?; let run_debug = terminal.run_debug.get_untracked()?; + let mut is_debug = false; let new_term_id = match run_debug.mode { RunDebugMode::Run => { self.common.proxy.terminal_close(term_id); - let mut run_debug = run_debug; run_debug.stopped = false; run_debug.is_prelaunch = true; @@ -487,6 +488,7 @@ impl TerminalPanelData { new_term_id } RunDebugMode::Debug => { + is_debug = true; let dap_id = terminal.run_debug.get_untracked().as_ref()?.config.dap_id; let daps = self.debug.daps.get_untracked(); @@ -500,7 +502,7 @@ impl TerminalPanelData { self.focus_terminal(new_term_id); - Some(()) + Some(is_debug) } pub fn focus_terminal(&self, term_id: TermId) { diff --git a/lapce-app/src/window_tab.rs b/lapce-app/src/window_tab.rs index 88a2debdf8..7fa70598e3 100644 --- a/lapce-app/src/window_tab.rs +++ b/lapce-app/src/window_tab.rs @@ -1098,10 +1098,14 @@ impl WindowTabData { // ==== Running / Debugging ==== RunAndDebugRestart => { let active_term = self.terminal.debug.active_term.get_untracked(); - if active_term + if let Some(is_debug) = active_term .and_then(|term_id| self.terminal.restart_run_debug(term_id)) - .is_none() { + self.panel.show_panel(&PanelKind::Terminal); + if is_debug { + self.panel.show_panel(&PanelKind::Debug); + } + } else { self.palette.run(PaletteKind::RunAndDebug); } } @@ -2648,6 +2652,9 @@ impl WindowTabData { self.terminal.debug.source_breakpoints(), ) }; + if !self.panel.is_panel_visible(&PanelKind::Debug) { + self.panel.show_panel(&PanelKind::Debug); + } } } } From 0e55cc4ce85d34c9c8ec2c1eaf7b1f7cb15fe58e Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Mon, 9 Sep 2024 17:57:01 +0800 Subject: [PATCH 48/69] Implement the LSP implementation method. (#3483) --- lapce-proxy/src/dispatch.rs | 16 +++++++++++++ lapce-proxy/src/plugin/mod.rs | 42 ++++++++++++++++++++++++++++++----- lapce-proxy/src/plugin/psp.rs | 38 ++++++++++++++++++++++--------- lapce-rpc/src/proxy.rs | 29 +++++++++++++++++++----- 4 files changed, 103 insertions(+), 22 deletions(-) diff --git a/lapce-proxy/src/dispatch.rs b/lapce-proxy/src/dispatch.rs index a55d691081..511b774002 100644 --- a/lapce-proxy/src/dispatch.rs +++ b/lapce-proxy/src/dispatch.rs @@ -1122,6 +1122,22 @@ impl ProxyHandler for Dispatcher { }, ); } + GotoImplementation { path, position } => { + let proxy_rpc = self.proxy_rpc.clone(); + self.catalog_rpc.go_to_implementation( + &path, + position, + move |plugin_id, result| { + let result = result.map(|resp| { + ProxyResponse::GotoImplementationResponse { + plugin_id, + resp, + } + }); + proxy_rpc.handle_response(id, result); + }, + ); + } } } } diff --git a/lapce-proxy/src/plugin/mod.rs b/lapce-proxy/src/plugin/mod.rs index e89e9f5527..677c3c4926 100644 --- a/lapce-proxy/src/plugin/mod.rs +++ b/lapce-proxy/src/plugin/mod.rs @@ -35,11 +35,12 @@ use lsp_types::{ request::{ CallHierarchyIncomingCalls, CallHierarchyPrepare, CodeActionRequest, CodeActionResolveRequest, CodeLensRequest, CodeLensResolve, Completion, - DocumentSymbolRequest, Formatting, GotoDefinition, GotoTypeDefinition, - GotoTypeDefinitionParams, GotoTypeDefinitionResponse, HoverRequest, - InlayHintRequest, InlineCompletionRequest, PrepareRenameRequest, References, - Rename, Request, ResolveCompletionItem, SelectionRangeRequest, - SemanticTokensFullRequest, SignatureHelpRequest, WorkspaceSymbolRequest, + DocumentSymbolRequest, Formatting, GotoDefinition, GotoImplementation, + GotoImplementationResponse, GotoTypeDefinition, GotoTypeDefinitionParams, + GotoTypeDefinitionResponse, HoverRequest, InlayHintRequest, + InlineCompletionRequest, PrepareRenameRequest, References, Rename, Request, + ResolveCompletionItem, SelectionRangeRequest, SemanticTokensFullRequest, + SignatureHelpRequest, WorkspaceSymbolRequest, }, CallHierarchyClientCapabilities, CallHierarchyIncomingCall, CallHierarchyIncomingCallsParams, CallHierarchyItem, CallHierarchyPrepareParams, @@ -697,6 +698,37 @@ impl PluginCatalogRpcHandler { ); } + pub fn go_to_implementation( + &self, + path: &Path, + position: Position, + cb: impl FnOnce(PluginId, Result, RpcError>) + + Clone + + Send + + 'static, + ) { + let uri = Url::from_file_path(path).unwrap(); + let method = GotoImplementation::METHOD; + let params = GotoTypeDefinitionParams { + text_document_position_params: TextDocumentPositionParams { + text_document: TextDocumentIdentifier { uri }, + position, + }, + work_done_progress_params: WorkDoneProgressParams::default(), + partial_result_params: PartialResultParams::default(), + }; + + let language_id = + Some(language_id_from_path(path).unwrap_or("").to_string()); + self.send_request_to_all_plugins( + method, + params, + language_id, + Some(path.to_path_buf()), + cb, + ); + } + pub fn get_code_actions( &self, path: &Path, diff --git a/lapce-proxy/src/plugin/psp.rs b/lapce-proxy/src/plugin/psp.rs index 9491334d7e..205aa72f48 100644 --- a/lapce-proxy/src/plugin/psp.rs +++ b/lapce-proxy/src/plugin/psp.rs @@ -31,20 +31,22 @@ use lsp_types::{ request::{ CallHierarchyIncomingCalls, CallHierarchyPrepare, CodeActionRequest, CodeActionResolveRequest, CodeLensRequest, CodeLensResolve, Completion, - DocumentSymbolRequest, Formatting, GotoDefinition, GotoTypeDefinition, - HoverRequest, Initialize, InlayHintRequest, InlineCompletionRequest, - PrepareRenameRequest, References, RegisterCapability, Rename, - ResolveCompletionItem, SelectionRangeRequest, SemanticTokensFullRequest, - SignatureHelpRequest, WorkDoneProgressCreate, WorkspaceSymbolRequest, + DocumentSymbolRequest, Formatting, GotoDefinition, GotoImplementation, + GotoTypeDefinition, HoverRequest, Initialize, InlayHintRequest, + InlineCompletionRequest, PrepareRenameRequest, References, + RegisterCapability, Rename, ResolveCompletionItem, SelectionRangeRequest, + SemanticTokensFullRequest, SignatureHelpRequest, WorkDoneProgressCreate, + WorkspaceSymbolRequest, }, CodeActionProviderCapability, DidChangeTextDocumentParams, DidSaveTextDocumentParams, DocumentSelector, HoverProviderCapability, - InitializeResult, LogMessageParams, MessageType, OneOf, ProgressParams, - PublishDiagnosticsParams, Range, Registration, RegistrationParams, - SemanticTokens, SemanticTokensLegend, SemanticTokensServerCapabilities, - ServerCapabilities, ShowMessageParams, TextDocumentContentChangeEvent, - TextDocumentIdentifier, TextDocumentSaveRegistrationOptions, - TextDocumentSyncCapability, TextDocumentSyncKind, TextDocumentSyncSaveOptions, + ImplementationProviderCapability, InitializeResult, LogMessageParams, + MessageType, OneOf, ProgressParams, PublishDiagnosticsParams, Range, + Registration, RegistrationParams, SemanticTokens, SemanticTokensLegend, + SemanticTokensServerCapabilities, ServerCapabilities, ShowMessageParams, + TextDocumentContentChangeEvent, TextDocumentIdentifier, + TextDocumentSaveRegistrationOptions, TextDocumentSyncCapability, + TextDocumentSyncKind, TextDocumentSyncSaveOptions, VersionedTextDocumentIdentifier, }; use parking_lot::Mutex; @@ -765,6 +767,20 @@ impl PluginHostHandler { OneOf::Right(_) => true, }) .unwrap_or(false), + GotoImplementation::METHOD => self + .server_capabilities + .implementation_provider + .as_ref() + .map(|r| match r { + ImplementationProviderCapability::Simple(is_capable) => { + *is_capable + } + ImplementationProviderCapability::Options(_) => { + // todo + false + } + }) + .unwrap_or(false), CodeActionRequest::METHOD => self .server_capabilities .code_action_provider diff --git a/lapce-rpc/src/proxy.rs b/lapce-rpc/src/proxy.rs index 3125b78863..f9d55bcb7f 100644 --- a/lapce-rpc/src/proxy.rs +++ b/lapce-rpc/src/proxy.rs @@ -11,12 +11,12 @@ use crossbeam_channel::{Receiver, Sender}; use indexmap::IndexMap; use lapce_xi_rope::RopeDelta; use lsp_types::{ - request::GotoTypeDefinitionResponse, CallHierarchyIncomingCall, - CallHierarchyItem, CodeAction, CodeActionResponse, CodeLens, CompletionItem, - Diagnostic, DocumentSymbolResponse, GotoDefinitionResponse, Hover, InlayHint, - InlineCompletionResponse, InlineCompletionTriggerKind, Location, Position, - PrepareRenameResponse, SelectionRange, SymbolInformation, TextDocumentItem, - TextEdit, WorkspaceEdit, + request::{GotoImplementationResponse, GotoTypeDefinitionResponse}, + CallHierarchyIncomingCall, CallHierarchyItem, CodeAction, CodeActionResponse, + CodeLens, CompletionItem, Diagnostic, DocumentSymbolResponse, + GotoDefinitionResponse, Hover, InlayHint, InlineCompletionResponse, + InlineCompletionTriggerKind, Location, Position, PrepareRenameResponse, + SelectionRange, SymbolInformation, TextDocumentItem, TextEdit, WorkspaceEdit, }; use parking_lot::Mutex; use serde::{Deserialize, Serialize}; @@ -100,6 +100,10 @@ pub enum ProxyRequest { path: PathBuf, position: Position, }, + GotoImplementation { + path: PathBuf, + position: Position, + }, GetDefinition { request_id: usize, path: PathBuf, @@ -396,6 +400,10 @@ pub enum ProxyResponse { plugin_id: PluginId, resp: CodeLens, }, + GotoImplementationResponse { + plugin_id: PluginId, + resp: Option, + }, GetFilesResponse { items: Vec, }, @@ -919,6 +927,15 @@ impl ProxyRpcHandler { self.request_async(ProxyRequest::GetReferences { path, position }, f); } + pub fn go_to_implementation( + &self, + path: PathBuf, + position: Position, + f: impl ProxyCallback + 'static, + ) { + self.request_async(ProxyRequest::GotoImplementation { path, position }, f); + } + pub fn get_code_actions( &self, path: PathBuf, From d3c87bfc1cbad2c185591aaeeaf8154cb6180009 Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Tue, 10 Sep 2024 17:20:29 +0800 Subject: [PATCH 49/69] 1. Preliminary implementation of the "Find References" panel (#3484) --- lapce-app/src/app/logging.rs | 1 + lapce-app/src/command.rs | 4 + lapce-app/src/config/icon.rs | 2 + lapce-app/src/editor.rs | 45 +- lapce-app/src/main_split.rs | 4 + lapce-app/src/panel/kind.rs | 2 + lapce-app/src/panel/mod.rs | 1 + lapce-app/src/panel/references_view.rs | 663 +++++++++++++++++++++++++ lapce-app/src/panel/view.rs | 5 + lapce-app/src/window_tab.rs | 10 +- 10 files changed, 735 insertions(+), 2 deletions(-) create mode 100644 lapce-app/src/panel/references_view.rs diff --git a/lapce-app/src/app/logging.rs b/lapce-app/src/app/logging.rs index 4a033ac218..1c083c1373 100644 --- a/lapce-app/src/app/logging.rs +++ b/lapce-app/src/app/logging.rs @@ -50,6 +50,7 @@ pub(super) fn logging() -> (Handle, Option) { fmt::Subscriber::default() .with_line_number(true) .with_target(true) + .with_thread_names(true) .with_filter(console_filter_targets), ) .init(); diff --git a/lapce-app/src/command.rs b/lapce-app/src/command.rs index c0ebf762df..74b8b2e37f 100644 --- a/lapce-app/src/command.rs +++ b/lapce-app/src/command.rs @@ -187,6 +187,10 @@ pub enum LapceWorkbenchCommand { #[strum(message = "Show Call Hierarchy")] ShowCallHierarchy, + #[strum(serialize = "find_references")] + #[strum(message = "Find References")] + FindReferences, + #[strum(serialize = "reveal_in_panel")] #[strum(message = "Reveal in Panel")] RevealInPanel, diff --git a/lapce-app/src/config/icon.rs b/lapce-app/src/config/icon.rs index 61a17bd421..0b9b89e38b 100644 --- a/lapce-app/src/config/icon.rs +++ b/lapce-app/src/config/icon.rs @@ -110,6 +110,8 @@ impl LapceIcons { pub const FILE_TYPE_SYMLINK_DIRECTORY: &'static str = "file-symlink-directory"; pub const DOCUMENT_SYMBOL: &'static str = "document_symbol"; + + pub const REFERENCES: &'static str = "document_symbol"; pub const SYMBOL_KIND_ARRAY: &'static str = "symbol_kind.array"; pub const SYMBOL_KIND_BOOLEAN: &'static str = "symbol_kind.boolean"; pub const SYMBOL_KIND_CLASS: &'static str = "symbol_kind.class"; diff --git a/lapce-app/src/editor.rs b/lapce-app/src/editor.rs index 8e817f6608..6db8b0201d 100644 --- a/lapce-app/src/editor.rs +++ b/lapce-app/src/editor.rs @@ -76,7 +76,10 @@ use crate::{ markdown::{ from_marked_string, from_plaintext, parse_markdown, MarkdownContent, }, - panel::{call_hierarchy_view::CallHierarchyItemData, kind::PanelKind}, + panel::{ + call_hierarchy_view::CallHierarchyItemData, kind::PanelKind, + references_view::init_references_root, + }, snippet::Snippet, tracing::*, window_tab::{CommonData, Focus, WindowTabData}, @@ -1419,6 +1422,43 @@ impl EditorData { ); } + pub fn find_refenrence(&self, window_tab_data: WindowTabData) { + let doc = self.doc(); + let path = match if doc.loaded() { + doc.content.with_untracked(|c| c.path().cloned()) + } else { + None + } { + Some(path) => path, + None => return, + }; + + let offset = self.cursor().with_untracked(|c| c.offset()); + let (_start_position, position) = doc.buffer.with_untracked(|buffer| { + let start_offset = buffer.prev_code_boundary(offset); + let start_position = buffer.offset_to_position(start_offset); + let position = buffer.offset_to_position(offset); + (start_position, position) + }); + let scope = window_tab_data.scope; + self.common.proxy.get_references( + path, + position, + create_ext_action(self.scope, move |result| { + if let Ok(ProxyResponse::GetReferencesResponse { references }) = + result + { + tracing::debug!("GetReferencesResponse {}", references.len()); + window_tab_data + .main_split + .references + .update(|x| *x = init_references_root(references, scope)); + window_tab_data.show_panel(PanelKind::References); + } + }), + ); + } + fn scroll(&self, down: bool, count: usize, mods: Modifiers) { self.editor.scroll( self.sticky_header_height.get_untracked(), @@ -2749,6 +2789,9 @@ impl EditorData { Some(CommandKind::Workbench( LapceWorkbenchCommand::ShowCallHierarchy, )), + Some(CommandKind::Workbench( + LapceWorkbenchCommand::FindReferences, + )), Some(CommandKind::Focus(FocusCommand::Rename)), Some(CommandKind::Workbench(LapceWorkbenchCommand::RunInTerminal)), None, diff --git a/lapce-app/src/main_split.rs b/lapce-app/src/main_split.rs index 8bf27d4af3..1d9a174f59 100644 --- a/lapce-app/src/main_split.rs +++ b/lapce-app/src/main_split.rs @@ -50,6 +50,7 @@ use crate::{ ThemeColorSettingsId, VoltViewId, }, keypress::{EventRef, KeyPressData, KeyPressHandle}, + panel::references_view::ReferencesRoot, window_tab::{CommonData, Focus, WindowTabData}, }; @@ -381,6 +382,7 @@ pub struct MainSplitData { pub docs: RwSignal>>, pub scratch_docs: RwSignal>>, pub diagnostics: RwSignal>, + pub references: RwSignal, pub active_editor: Memo>, pub find_editor: EditorData, pub replace_editor: EditorData, @@ -413,6 +415,7 @@ impl MainSplitData { cx.create_rw_signal(im::HashMap::new()); let scratch_docs = cx.create_rw_signal(im::HashMap::new()); let locations = cx.create_rw_signal(im::Vector::new()); + let references = cx.create_rw_signal(ReferencesRoot::default()); let current_location = cx.create_rw_signal(0); let diagnostics = cx.create_rw_signal(im::HashMap::new()); let find_editor = editors.make_local(cx, common.clone()); @@ -472,6 +475,7 @@ impl MainSplitData { width: cx.create_rw_signal(0.0), code_lens: cx.create_rw_signal(CodeLensData::new(common.clone())), common, + references, } } diff --git a/lapce-app/src/panel/kind.rs b/lapce-app/src/panel/kind.rs index 0f29f5c241..6d440cd73e 100644 --- a/lapce-app/src/panel/kind.rs +++ b/lapce-app/src/panel/kind.rs @@ -17,6 +17,7 @@ pub enum PanelKind { Debug, CallHierarchy, DocumentSymbol, + References, } impl PanelKind { @@ -31,6 +32,7 @@ impl PanelKind { PanelKind::Debug => LapceIcons::DEBUG, PanelKind::CallHierarchy => LapceIcons::TYPE_HIERARCHY, PanelKind::DocumentSymbol => LapceIcons::DOCUMENT_SYMBOL, + PanelKind::References => LapceIcons::REFERENCES, } } diff --git a/lapce-app/src/panel/mod.rs b/lapce-app/src/panel/mod.rs index 2398e4f5bb..db69c05cdf 100644 --- a/lapce-app/src/panel/mod.rs +++ b/lapce-app/src/panel/mod.rs @@ -7,6 +7,7 @@ pub mod kind; pub mod plugin_view; pub mod position; pub mod problem_view; +pub mod references_view; pub mod source_control_view; pub mod style; pub mod terminal_view; diff --git a/lapce-app/src/panel/references_view.rs b/lapce-app/src/panel/references_view.rs new file mode 100644 index 0000000000..137d2dcef3 --- /dev/null +++ b/lapce-app/src/panel/references_view.rs @@ -0,0 +1,663 @@ +use std::{ops::AddAssign, path::PathBuf, rc::Rc}; + +use floem::{ + reactive::{RwSignal, Scope, SignalGet, SignalUpdate}, + style::CursorStyle, + views::{ + container, label, scroll, stack, svg, virtual_stack, Decorators, + VirtualDirection, VirtualItemSize, VirtualVector, + }, + IntoView, View, ViewId, +}; +use im::HashMap; +use lsp_types::{Location, Position, SymbolKind}; + +use super::position::PanelPosition; +use crate::{ + command::InternalCommand, + config::{color::LapceColor, icon::LapceIcons}, + editor::location::EditorLocation, + window_tab::WindowTabData, +}; + +pub fn references_panel( + window_tab_data: Rc, + _position: PanelPosition, +) -> impl View { + let main_split = window_tab_data.main_split.clone(); + let config = window_tab_data.common.config; + let ui_line_height = window_tab_data.common.ui_line_height; + scroll( + virtual_stack( + VirtualDirection::Vertical, + VirtualItemSize::Fixed(Box::new(move || ui_line_height.get())), + move || main_split.references.get(), + move |(_, _, data)| data.view_id(), + move |(_, level, rw_data)| { + match rw_data { + ReferenceLocation::File { path, open, .. } => { + stack(( + container(svg(move || { + let config = config.get(); + let svg_str = match open.get() { + true => LapceIcons::ITEM_OPENED, + false => LapceIcons::ITEM_CLOSED, + }; + config.ui_svg(svg_str) + }) + .style(move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + s.size(size, size) + .color(config.color(LapceColor::LAPCE_ICON_ACTIVE)) + }) + ) + .style(|s| s.padding(4.0).margin_left(6.0).margin_right(2.0)) + .on_click_stop({ + move |_x| { + tracing::debug!("open = {:?} {}", SignalGet::id(&open), open.get_untracked()); + open.update(|x| { + *x = !*x; + }); + } + }), + svg(move || { + let config = config.get(); + config + .symbol_svg(&SymbolKind::FILE) + .unwrap_or_else(|| config.ui_svg(LapceIcons::FILE)) + }).style(move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + s.min_width(size) + .size(size, size) + .margin_right(5.0) + .color(config.symbol_color(&SymbolKind::FILE).unwrap_or_else(|| { + config.color(LapceColor::LAPCE_ICON_ACTIVE) + })) + }), + label(move || { + format!("{:?}", path) + }).style(move |s| s.margin_left(6.0) + .color(config.get().color(LapceColor::EDITOR_DIM)) + ).into_any() + )) + .style(move |s| { + s.padding_right(5.0) + .height(ui_line_height.get()) + .padding_left((level * 10) as f32) + .items_center() + .hover(|s| { + s.background( + config + .get() + .color(LapceColor::PANEL_HOVERED_BACKGROUND), + ) + .cursor(CursorStyle::Pointer) + }) + }) + } + ReferenceLocation::Line { path, range, .. } => { + stack( + ( + container( + label( + move || { + format!("{}", range.line + 1) + }) + .style(move |s| s.margin_left(6.0) + .color(config.get().color(LapceColor::EDITOR_DIM)) + ).into_any() + ) + .style(move |s| { + s.padding_right(5.0) + .height(ui_line_height.get()) + .padding_left((level * 20) as f32) + .items_center() + .hover(|s| { + s.background( + config + .get() + .color(LapceColor::PANEL_HOVERED_BACKGROUND), + ) + .cursor(CursorStyle::Pointer) + }) + }), + ) + ).on_click_stop({ + let window_tab_data = window_tab_data.clone(); + move |_| + { + let range = range; + tracing::info!("go to location: {:?}", range); + window_tab_data + .common + .internal_command + .send(InternalCommand::GoToLocation { + location: EditorLocation { + path: path.clone(), + position: Some(crate::editor::location::EditorPosition::Position(range)), + scroll_offset: None, + ignore_unconfirmed: false, + same_editor_tab: false, + } + }); + } + }) + } + }.style(move |s| { + s.padding_right(5.0) + .height(ui_line_height.get()) + .padding_left((level * 10) as f32) + .items_center() + .hover(|s| { + s.background( + config + .get() + .color(LapceColor::PANEL_HOVERED_BACKGROUND), + ) + .cursor(CursorStyle::Pointer) + }) + }) + }, + ) + .style(|s| s.flex_col().absolute().min_width_full()), + ) + .style(|s| s.absolute().size_full()) + .debug_name("references_section") +} + +pub fn init_references_root(items: Vec, scope: Scope) -> ReferencesRoot { + tracing::debug!("get_items {}", items.len()); + let mut refs_map = HashMap::new(); + for item in items { + if let Ok(path) = item.uri.to_file_path() { + let entry = refs_map.entry(path.clone()).or_insert(Vec::new()); + (*entry).push(Reference::Line { + location: ReferenceLocation::Line { + view_id: ViewId::new(), + path, + range: item.range.start, + }, + }) + } + } + let mut refs = Vec::new(); + for (path, items) in refs_map { + let open = scope.create_rw_signal(true); + let ref_item = Reference::File { + location: crate::panel::references_view::ReferenceLocation::File { + open, + path, + view_id: ViewId::new(), + }, + children: items, + open, + }; + refs.push(ref_item); + } + ReferencesRoot { children: refs } +} + +#[derive(Clone, Default)] +pub struct ReferencesRoot { + children: Vec, +} +impl VirtualVector<(usize, usize, ReferenceLocation)> for ReferencesRoot { + fn total_len(&self) -> usize { + self.total() + } + + fn slice( + &mut self, + range: std::ops::Range, + ) -> impl Iterator { + let min = range.start; + let max = range.end; + let children = self.get_children(&mut 0, min, max, 0); + children.into_iter() + } +} + +impl ReferencesRoot { + pub fn total(&self) -> usize { + let mut total = 0; + for child in &self.children { + total += child.total_len() + } + total + } + + fn get_children( + &self, + next: &mut usize, + min: usize, + max: usize, + level: usize, + ) -> Vec<(usize, usize, ReferenceLocation)> { + let mut children = Vec::new(); + for child in &self.children { + let child_children = child.get_children(next, min, max, level + 1); + if !child_children.is_empty() { + children.extend(child_children); + } + if *next > max { + break; + } + } + children + } +} + +#[derive(Clone)] +enum Reference { + File { + location: ReferenceLocation, + open: RwSignal, + children: Vec, + }, + Line { + location: ReferenceLocation, + }, +} + +#[derive(Clone)] +pub enum ReferenceLocation { + File { + path: PathBuf, + open: RwSignal, + view_id: ViewId, + }, + Line { + path: PathBuf, + range: Position, + view_id: ViewId, + }, +} + +impl ReferenceLocation { + pub fn view_id(&self) -> ViewId { + match self { + ReferenceLocation::File { view_id, .. } => *view_id, + ReferenceLocation::Line { view_id, .. } => *view_id, + } + } +} + +impl Reference { + pub fn location(&self) -> ReferenceLocation { + match self { + Reference::File { location, .. } => location.clone(), + Reference::Line { location } => location.clone(), + } + } + pub fn total_len(&self) -> usize { + match self { + Reference::File { children, .. } => { + let mut total = 1; + for child in children { + total += child.total_len() + } + total + } + Reference::Line { .. } => 1, + } + } + pub fn children(&self) -> Option<&Vec> { + match self { + Reference::File { children, open, .. } => { + if open.get() { + return Some(children); + } + None + } + Reference::Line { .. } => None, + } + } + + fn get_children( + &self, + next: &mut usize, + min: usize, + max: usize, + level: usize, + ) -> Vec<(usize, usize, ReferenceLocation)> { + let mut children = Vec::new(); + if *next >= min && *next < max { + children.push((*next, level, self.location())); + } else if *next >= max { + return children; + } + next.add_assign(1); + if let Some(children_tmp) = self.children() { + for child in children_tmp { + let child_children = child.get_children(next, min, max, level + 1); + if !child_children.is_empty() { + children.extend(child_children); + } + if *next > max { + break; + } + } + } + children + } +} +// +// fn file_view( +// workspace: Arc, +// path: PathBuf, +// diagnostic_data: DiagnosticData, +// severity: DiagnosticSeverity, +// internal_command: Listener, +// config: ReadSignal>, +// ) -> impl View { +// let collpased = create_rw_signal(false); +// +// let diagnostics = create_rw_signal(im::Vector::new()); +// create_effect(move |_| { +// let span = diagnostic_data.diagnostics_span.get(); +// let d = if !span.is_empty() { +// span.iter() +// .filter_map(|(iv, diag)| { +// if diag.severity == Some(severity) { +// Some(EditorDiagnostic { +// range: Some((iv.start, iv.end)), +// diagnostic: diag.to_owned(), +// }) +// } else { +// None +// } +// }) +// .collect::>() +// } else { +// let diagnostics = diagnostic_data.diagnostics.get(); +// let diagnostics: im::Vector = diagnostics +// .into_iter() +// .filter_map(|d| { +// if d.severity == Some(severity) { +// Some(EditorDiagnostic { +// range: None, +// diagnostic: d, +// }) +// } else { +// None +// } +// }) +// .collect(); +// diagnostics +// }; +// diagnostics.set(d); +// }); +// +// let full_path = path.clone(); +// let path = if let Some(workspace_path) = workspace.path.as_ref() { +// path.strip_prefix(workspace_path) +// .unwrap_or(&full_path) +// .to_path_buf() +// } else { +// path +// }; +// let style_path = path.clone(); +// +// let icon = match severity { +// DiagnosticSeverity::ERROR => LapceIcons::ERROR, +// _ => LapceIcons::WARNING, +// }; +// let icon_color = move || { +// let config = config.get(); +// match severity { +// DiagnosticSeverity::ERROR => config.color(LapceColor::LAPCE_ERROR), +// _ => config.color(LapceColor::LAPCE_WARN), +// } +// }; +// +// let file_name = path +// .file_name() +// .and_then(|s| s.to_str()) +// .unwrap_or("") +// .to_string(); +// +// let folder = path +// .parent() +// .and_then(|s| s.to_str()) +// .unwrap_or("") +// .to_string(); +// +// stack(( +// stack(( +// container( +// stack(( +// label(move || file_name.clone()).style(|s| { +// s.margin_right(6.0) +// .max_width_pct(100.0) +// .text_ellipsis() +// .selectable(false) +// }), +// label(move || folder.clone()).style(move |s| { +// s.color(config.get().color(LapceColor::EDITOR_DIM)) +// .min_width(0.0) +// .text_ellipsis() +// .selectable(false) +// }), +// )) +// .style(move |s| s.width_pct(100.0).min_width(0.0)), +// ) +// .on_click_stop(move |_| { +// collpased.update(|collpased| *collpased = !*collpased); +// }) +// .style(move |s| { +// let config = config.get(); +// s.width_pct(100.0) +// .min_width(0.0) +// .padding_left(10.0 + (config.ui.icon_size() as f32 + 6.0) * 2.0) +// .padding_right(10.0) +// .hover(|s| { +// s.cursor(CursorStyle::Pointer).background( +// config.color(LapceColor::PANEL_HOVERED_BACKGROUND), +// ) +// }) +// }), +// stack(( +// svg(move || { +// config.get().ui_svg(if collpased.get() { +// LapceIcons::ITEM_CLOSED +// } else { +// LapceIcons::ITEM_OPENED +// }) +// }) +// .style(move |s| { +// let config = config.get(); +// let size = config.ui.icon_size() as f32; +// s.margin_right(6.0) +// .size(size, size) +// .color(config.color(LapceColor::LAPCE_ICON_ACTIVE)) +// }), +// svg(move || config.get().file_svg(&path).0).style(move |s| { +// let config = config.get(); +// let size = config.ui.icon_size() as f32; +// let color = config.file_svg(&style_path).1; +// s.min_width(size) +// .size(size, size) +// .apply_opt(color, Style::color) +// }), +// label(|| " ".to_string()).style(move |s| s.selectable(false)), +// )) +// .style(|s| s.absolute().items_center().margin_left(10.0)), +// )) +// .style(move |s| s.width_pct(100.0).min_width(0.0)), +// dyn_stack( +// move || { +// if collpased.get() { +// im::Vector::new() +// } else { +// diagnostics.get() +// } +// }, +// |d| (d.range, d.diagnostic.range), +// move |d| { +// item_view( +// full_path.clone(), +// d, +// icon, +// icon_color, +// internal_command, +// config, +// ) +// }, +// ) +// .style(|s| s.flex_col().width_pct(100.0).min_width_pct(0.0)), +// )) +// .style(move |s| { +// s.width_pct(100.0) +// .items_start() +// .flex_col() +// .apply_if(diagnostics.with(|d| d.is_empty()), |s| s.hide()) +// }) +// } +// +// fn item_view( +// path: PathBuf, +// d: EditorDiagnostic, +// icon: &'static str, +// icon_color: impl Fn() -> Color + 'static, +// internal_command: Listener, +// config: ReadSignal>, +// ) -> impl View { +// let related = d.diagnostic.related_information.unwrap_or_default(); +// let position = if let Some((start, _)) = d.range { +// EditorPosition::Offset(start) +// } else { +// EditorPosition::Position(d.diagnostic.range.start) +// }; +// let location = EditorLocation { +// path, +// position: Some(position), +// scroll_offset: None, +// ignore_unconfirmed: false, +// same_editor_tab: false, +// }; +// stack(( +// container({ +// stack(( +// label(move || d.diagnostic.message.clone()).style(move |s| { +// s.width_pct(100.0) +// .min_width(0.0) +// .padding_left( +// 10.0 + (config.get().ui.icon_size() as f32 + 6.0) * 3.0, +// ) +// .padding_right(10.0) +// }), +// stack(( +// svg(move || config.get().ui_svg(icon)).style(move |s| { +// let config = config.get(); +// let size = config.ui.icon_size() as f32; +// s.size(size, size).color(icon_color()) +// }), +// label(|| " ".to_string()).style(move |s| s.selectable(false)), +// )) +// .style(move |s| { +// s.absolute().items_center().margin_left( +// 10.0 + (config.get().ui.icon_size() as f32 + 6.0) * 2.0, +// ) +// }), +// )) +// .style(move |s| { +// s.width_pct(100.0).min_width(0.0).hover(|s| { +// s.cursor(CursorStyle::Pointer).background( +// config.get().color(LapceColor::PANEL_HOVERED_BACKGROUND), +// ) +// }) +// }) +// }) +// .on_click_stop(move |_| { +// internal_command.send(InternalCommand::JumpToLocation { +// location: location.clone(), +// }); +// }) +// .style(|s| s.width_pct(100.0).min_width_pct(0.0)), +// related_view(related, internal_command, config), +// )) +// .style(|s| s.width_pct(100.0).min_width_pct(0.0).flex_col()) +// } +// +// fn related_view( +// related: Vec, +// internal_command: Listener, +// config: ReadSignal>, +// ) -> impl View { +// let is_empty = related.is_empty(); +// stack(( +// dyn_stack( +// move || related.clone(), +// |_| 0, +// move |related| { +// let full_path = path_from_url(&related.location.uri); +// let path = full_path +// .file_name() +// .and_then(|f| f.to_str()) +// .map(|f| { +// format!( +// "{f} [{}, {}]: ", +// related.location.range.start.line, +// related.location.range.start.character +// ) +// }) +// .unwrap_or_default(); +// let location = EditorLocation { +// path: full_path, +// position: Some(EditorPosition::Position( +// related.location.range.start, +// )), +// scroll_offset: None, +// ignore_unconfirmed: false, +// same_editor_tab: false, +// }; +// let message = format!("{path}{}", related.message); +// container( +// label(move || message.clone()) +// .style(move |s| s.width_pct(100.0).min_width(0.0)), +// ) +// .on_click_stop(move |_| { +// internal_command.send(InternalCommand::JumpToLocation { +// location: location.clone(), +// }); +// }) +// .style(move |s| { +// let config = config.get(); +// s.padding_left(10.0 + (config.ui.icon_size() as f32 + 6.0) * 4.0) +// .padding_right(10.0) +// .width_pct(100.0) +// .min_width(0.0) +// .hover(|s| { +// s.cursor(CursorStyle::Pointer).background( +// config.color(LapceColor::PANEL_HOVERED_BACKGROUND), +// ) +// }) +// }) +// }, +// ) +// .style(|s| s.width_pct(100.0).min_width(0.0).flex_col()), +// stack(( +// svg(move || config.get().ui_svg(LapceIcons::LINK)).style(move |s| { +// let config = config.get(); +// let size = config.ui.icon_size() as f32; +// s.size(size, size) +// .color(config.color(LapceColor::EDITOR_DIM)) +// }), +// label(|| " ".to_string()).style(move |s| s.selectable(false)), +// )) +// .style(move |s| { +// s.absolute() +// .items_center() +// .margin_left(10.0 + (config.get().ui.icon_size() as f32 + 6.0) * 3.0) +// }), +// )) +// .style(move |s| { +// s.width_pct(100.0) +// .min_width(0.0) +// .items_start() +// .color(config.get().color(LapceColor::EDITOR_DIM)) +// .apply_if(is_empty, |s| s.hide()) +// }) +// } diff --git a/lapce-app/src/panel/view.rs b/lapce-app/src/panel/view.rs index 050f29b113..8283b4ab97 100644 --- a/lapce-app/src/panel/view.rs +++ b/lapce-app/src/panel/view.rs @@ -32,6 +32,7 @@ use crate::{ file_explorer::view::file_explorer_panel, panel::{ call_hierarchy_view::show_hierarchy_panel, document_symbol::symbol_panel, + references_view::references_panel, }, window_tab::{DragContent, WindowTabData}, }; @@ -496,6 +497,9 @@ fn panel_view( PanelKind::DocumentSymbol => { symbol_panel(window_tab_data.clone(), position).into_any() } + PanelKind::References => { + references_panel(window_tab_data.clone(), position).into_any() + } }; view.style(|s| s.size_pct(100.0, 100.0)) }, @@ -550,6 +554,7 @@ fn panel_picker( PanelKind::Debug => "Debug", PanelKind::CallHierarchy => "Call Hierarchy", PanelKind::DocumentSymbol => "Document Symbol", + PanelKind::References => "References", }; let icon = p.svg_name(); let is_active = { diff --git a/lapce-app/src/window_tab.rs b/lapce-app/src/window_tab.rs index 7fa70598e3..250f5cb943 100644 --- a/lapce-app/src/window_tab.rs +++ b/lapce-app/src/window_tab.rs @@ -1452,6 +1452,13 @@ impl WindowTabData { editor_data.call_hierarchy(self.clone()); } } + FindReferences => { + if let Some(editor_data) = + self.main_split.active_editor.get_untracked() + { + editor_data.find_refenrence(self.clone()); + } + } RunInTerminal => { if let Some(editor_data) = self.main_split.active_editor.get_untracked() @@ -2537,7 +2544,8 @@ impl WindowTabData { | PanelKind::Problem | PanelKind::Debug | PanelKind::CallHierarchy - | PanelKind::DocumentSymbol => { + | PanelKind::DocumentSymbol + | PanelKind::References => { // Some panels don't accept focus (yet). Fall back to visibility check // in those cases. self.panel.is_panel_visible(&kind) From 29e7c3e1f0a0d8a6fa6f31211a852a2b0856f168 Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Tue, 10 Sep 2024 22:40:06 +0800 Subject: [PATCH 50/69] 1. Add a default position. (#3486) 2. Adjust some logs. --- lapce-app/src/db.rs | 5 +++-- lapce-app/src/editor.rs | 1 - lapce-app/src/panel/data.rs | 3 ++- lapce-app/src/panel/kind.rs | 15 +++++++++++++++ lapce-app/src/panel/references_view.rs | 5 +---- 5 files changed, 21 insertions(+), 8 deletions(-) diff --git a/lapce-app/src/db.rs b/lapce-app/src/db.rs index db8750e052..74531187f5 100644 --- a/lapce-app/src/db.rs +++ b/lapce-app/src/db.rs @@ -14,7 +14,7 @@ use sha2::{Digest, Sha256}; use crate::{ app::{AppData, AppInfo}, doc::DocInfo, - panel::{data::PanelOrder, kind::PanelKind, position::PanelPosition}, + panel::{data::PanelOrder, kind::PanelKind}, window::{WindowData, WindowInfo}, window_tab::WindowTabData, workspace::{LapceWorkspace, WorkspaceInfo}, @@ -368,7 +368,8 @@ impl LapceDb { use strum::IntoEnumIterator; for kind in PanelKind::iter() { if kind.position(&panel_orders).is_none() { - let panels = panel_orders.entry(PanelPosition::LeftTop).or_default(); + let panels = + panel_orders.entry(kind.default_position()).or_default(); panels.push_back(kind); } } diff --git a/lapce-app/src/editor.rs b/lapce-app/src/editor.rs index 6db8b0201d..e48c2654fc 100644 --- a/lapce-app/src/editor.rs +++ b/lapce-app/src/editor.rs @@ -1448,7 +1448,6 @@ impl EditorData { if let Ok(ProxyResponse::GetReferencesResponse { references }) = result { - tracing::debug!("GetReferencesResponse {}", references.len()); window_tab_data .main_split .references diff --git a/lapce-app/src/panel/data.rs b/lapce-app/src/panel/data.rs index f984856909..325280ed49 100644 --- a/lapce-app/src/panel/data.rs +++ b/lapce-app/src/panel/data.rs @@ -37,7 +37,8 @@ pub fn default_panel_order() -> PanelOrder { PanelKind::Terminal, PanelKind::Search, PanelKind::Problem, - PanelKind::CallHierarchy + PanelKind::CallHierarchy, + PanelKind::References ], ); order.insert( diff --git a/lapce-app/src/panel/kind.rs b/lapce-app/src/panel/kind.rs index 6d440cd73e..3337eac726 100644 --- a/lapce-app/src/panel/kind.rs +++ b/lapce-app/src/panel/kind.rs @@ -45,4 +45,19 @@ impl PanelKind { } None } + + pub fn default_position(&self) -> PanelPosition { + match self { + PanelKind::Terminal => PanelPosition::BottomLeft, + PanelKind::FileExplorer => PanelPosition::LeftTop, + PanelKind::SourceControl => PanelPosition::LeftTop, + PanelKind::Plugin => PanelPosition::LeftTop, + PanelKind::Search => PanelPosition::BottomLeft, + PanelKind::Problem => PanelPosition::BottomLeft, + PanelKind::Debug => PanelPosition::LeftTop, + PanelKind::CallHierarchy => PanelPosition::BottomLeft, + PanelKind::DocumentSymbol => PanelPosition::RightTop, + PanelKind::References => PanelPosition::BottomLeft, + } + } } diff --git a/lapce-app/src/panel/references_view.rs b/lapce-app/src/panel/references_view.rs index 137d2dcef3..e6d502583b 100644 --- a/lapce-app/src/panel/references_view.rs +++ b/lapce-app/src/panel/references_view.rs @@ -55,7 +55,6 @@ pub fn references_panel( .style(|s| s.padding(4.0).margin_left(6.0).margin_right(2.0)) .on_click_stop({ move |_x| { - tracing::debug!("open = {:?} {}", SignalGet::id(&open), open.get_untracked()); open.update(|x| { *x = !*x; }); @@ -129,7 +128,6 @@ pub fn references_panel( move |_| { let range = range; - tracing::info!("go to location: {:?}", range); window_tab_data .common .internal_command @@ -164,11 +162,10 @@ pub fn references_panel( .style(|s| s.flex_col().absolute().min_width_full()), ) .style(|s| s.absolute().size_full()) - .debug_name("references_section") + .debug_name("references panel") } pub fn init_references_root(items: Vec, scope: Scope) -> ReferencesRoot { - tracing::debug!("get_items {}", items.len()); let mut refs_map = HashMap::new(); for item in items { if let Ok(path) = item.uri.to_file_path() { From debfbc4d2285b263eb5e86ee91004d5161b35a77 Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Wed, 11 Sep 2024 16:37:56 +0800 Subject: [PATCH 51/69] 1. Add the editor setting completion_item_show_detail. (#3489) 2. Add some LSP logs. --- defaults/settings.toml | 1 + lapce-app/src/app.rs | 11 ++++++++++- lapce-app/src/config/editor.rs | 4 ++++ lapce-proxy/src/plugin/lsp.rs | 5 +++++ 4 files changed, 20 insertions(+), 1 deletion(-) diff --git a/defaults/settings.toml b/defaults/settings.toml index 99da8916f3..5bcde98c19 100644 --- a/defaults/settings.toml +++ b/defaults/settings.toml @@ -22,6 +22,7 @@ wrap-column = 80 wrap-width = 600 # px sticky-header = true completion-show-documentation = true +completion-item-show-detail = false show-signature = true signature-label-code-block = true auto-closing-matching-pairs = true diff --git a/lapce-app/src/app.rs b/lapce-app/src/app.rs index cd231c0208..ce88f8b527 100644 --- a/lapce-app/src/app.rs +++ b/lapce-app/src/app.rs @@ -3012,7 +3012,16 @@ fn completion(window_tab_data: Rc) -> impl View { ) }), focus_text( - move || item.item.label.clone(), + move || { + if config.get().editor.completion_item_show_detail { + item.item + .detail + .clone() + .unwrap_or(item.item.label.clone()) + } else { + item.item.label.clone() + } + }, move || item.indices.clone(), move || config.get().color(LapceColor::EDITOR_FOCUS), ) diff --git a/lapce-app/src/config/editor.rs b/lapce-app/src/config/editor.rs index 68ac74438b..81d62fac20 100644 --- a/lapce-app/src/config/editor.rs +++ b/lapce-app/src/config/editor.rs @@ -100,6 +100,10 @@ pub struct EditorConfig { desc = "If the editor should show the documentation of the current completion item" )] pub completion_show_documentation: bool, + #[field_names( + desc = "Should the completion item use the `detail` field to replace the label `field`?" + )] + pub completion_item_show_detail: bool, #[field_names( desc = "If the editor should show the signature of the function as the parameters are being typed" )] diff --git a/lapce-proxy/src/plugin/lsp.rs b/lapce-proxy/src/plugin/lsp.rs index 13ca50e460..fd62aa23b6 100644 --- a/lapce-proxy/src/plugin/lsp.rs +++ b/lapce-proxy/src/plugin/lsp.rs @@ -223,6 +223,7 @@ impl LspClient { break; } if let Ok(msg) = serde_json::to_string(&msg) { + tracing::debug!("write to lsp: {}", msg); let msg = format!("Content-Length: {}\r\n\r\n{}", msg.len(), msg); if let Err(err) = writer.write(msg.as_bytes()) { @@ -244,6 +245,9 @@ impl LspClient { loop { match read_message(&mut reader) { Ok(message_str) => { + if !message_str.contains("$/progress") { + tracing::debug!("read from lsp: {}", message_str); + } if let Some(resp) = handle_plugin_server_message( &local_server_rpc, &message_str, @@ -358,6 +362,7 @@ impl LspClient { .workspace .clone() .map(|p| Url::from_directory_path(p).unwrap()); + tracing::debug!("initialization_options {:?}", self.options); #[allow(deprecated)] let params = InitializeParams { process_id: Some(process::id()), From 690339fe5e95a39b954efd8b0a1d70f025826e04 Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Wed, 11 Sep 2024 16:39:50 +0800 Subject: [PATCH 52/69] 1. Preliminary implementation of the "Go to Implementation" panel (#3490) --- lapce-app/src/command.rs | 4 ++++ lapce-app/src/config/icon.rs | 3 +++ lapce-app/src/editor.rs | 41 ++++++++++++++++++++++++++++++++++++ lapce-app/src/panel/data.rs | 3 ++- lapce-app/src/panel/kind.rs | 3 +++ lapce-app/src/panel/view.rs | 2 ++ lapce-app/src/window_tab.rs | 10 ++++++++- 7 files changed, 64 insertions(+), 2 deletions(-) diff --git a/lapce-app/src/command.rs b/lapce-app/src/command.rs index 74b8b2e37f..c23c3b9c6f 100644 --- a/lapce-app/src/command.rs +++ b/lapce-app/src/command.rs @@ -191,6 +191,10 @@ pub enum LapceWorkbenchCommand { #[strum(message = "Find References")] FindReferences, + #[strum(serialize = "go_to_implementation")] + #[strum(message = "Go to Implementation")] + GoToImplementation, + #[strum(serialize = "reveal_in_panel")] #[strum(message = "Reveal in Panel")] RevealInPanel, diff --git a/lapce-app/src/config/icon.rs b/lapce-app/src/config/icon.rs index 0b9b89e38b..bce4e47bdf 100644 --- a/lapce-app/src/config/icon.rs +++ b/lapce-app/src/config/icon.rs @@ -112,6 +112,9 @@ impl LapceIcons { pub const DOCUMENT_SYMBOL: &'static str = "document_symbol"; pub const REFERENCES: &'static str = "document_symbol"; + + pub const IMPLEMENTATION: &'static str = "document_symbol"; + pub const SYMBOL_KIND_ARRAY: &'static str = "symbol_kind.array"; pub const SYMBOL_KIND_BOOLEAN: &'static str = "symbol_kind.boolean"; pub const SYMBOL_KIND_CLASS: &'static str = "symbol_kind.class"; diff --git a/lapce-app/src/editor.rs b/lapce-app/src/editor.rs index e48c2654fc..ca61c15ab5 100644 --- a/lapce-app/src/editor.rs +++ b/lapce-app/src/editor.rs @@ -1458,6 +1458,44 @@ impl EditorData { ); } + pub fn go_to_implementation(&self, window_tab_data: WindowTabData) { + let doc = self.doc(); + let path = match if doc.loaded() { + doc.content.with_untracked(|c| c.path().cloned()) + } else { + None + } { + Some(path) => path, + None => return, + }; + + let offset = self.cursor().with_untracked(|c| c.offset()); + let (_start_position, position) = doc.buffer.with_untracked(|buffer| { + let start_offset = buffer.prev_code_boundary(offset); + let start_position = buffer.offset_to_position(start_offset); + let position = buffer.offset_to_position(offset); + (start_position, position) + }); + let _scope = window_tab_data.scope; + self.common.proxy.go_to_implementation( + path, + position, + create_ext_action(self.scope, move |result| { + if let Ok(ProxyResponse::GotoImplementationResponse { + resp, .. + }) = result + { + tracing::info!("{:?}", resp); + // window_tab_data + // .main_split + // .references + // .update(|x| *x = init_references_root(references, scope)); + window_tab_data.show_panel(PanelKind::Implementation); + } + }), + ); + } + fn scroll(&self, down: bool, count: usize, mods: Modifiers) { self.editor.scroll( self.sticky_header_height.get_untracked(), @@ -2791,6 +2829,9 @@ impl EditorData { Some(CommandKind::Workbench( LapceWorkbenchCommand::FindReferences, )), + Some(CommandKind::Workbench( + LapceWorkbenchCommand::GoToImplementation, + )), Some(CommandKind::Focus(FocusCommand::Rename)), Some(CommandKind::Workbench(LapceWorkbenchCommand::RunInTerminal)), None, diff --git a/lapce-app/src/panel/data.rs b/lapce-app/src/panel/data.rs index 325280ed49..4957510de0 100644 --- a/lapce-app/src/panel/data.rs +++ b/lapce-app/src/panel/data.rs @@ -38,7 +38,8 @@ pub fn default_panel_order() -> PanelOrder { PanelKind::Search, PanelKind::Problem, PanelKind::CallHierarchy, - PanelKind::References + PanelKind::References, + PanelKind::Implementation ], ); order.insert( diff --git a/lapce-app/src/panel/kind.rs b/lapce-app/src/panel/kind.rs index 3337eac726..695990e07c 100644 --- a/lapce-app/src/panel/kind.rs +++ b/lapce-app/src/panel/kind.rs @@ -18,6 +18,7 @@ pub enum PanelKind { CallHierarchy, DocumentSymbol, References, + Implementation, } impl PanelKind { @@ -33,6 +34,7 @@ impl PanelKind { PanelKind::CallHierarchy => LapceIcons::TYPE_HIERARCHY, PanelKind::DocumentSymbol => LapceIcons::DOCUMENT_SYMBOL, PanelKind::References => LapceIcons::REFERENCES, + PanelKind::Implementation => LapceIcons::IMPLEMENTATION, } } @@ -58,6 +60,7 @@ impl PanelKind { PanelKind::CallHierarchy => PanelPosition::BottomLeft, PanelKind::DocumentSymbol => PanelPosition::RightTop, PanelKind::References => PanelPosition::BottomLeft, + PanelKind::Implementation => PanelPosition::BottomLeft, } } } diff --git a/lapce-app/src/panel/view.rs b/lapce-app/src/panel/view.rs index 8283b4ab97..8a4127d018 100644 --- a/lapce-app/src/panel/view.rs +++ b/lapce-app/src/panel/view.rs @@ -500,6 +500,7 @@ fn panel_view( PanelKind::References => { references_panel(window_tab_data.clone(), position).into_any() } + PanelKind::Implementation => text("Implementation").into_any(), }; view.style(|s| s.size_pct(100.0, 100.0)) }, @@ -555,6 +556,7 @@ fn panel_picker( PanelKind::CallHierarchy => "Call Hierarchy", PanelKind::DocumentSymbol => "Document Symbol", PanelKind::References => "References", + PanelKind::Implementation => "Implementation", }; let icon = p.svg_name(); let is_active = { diff --git a/lapce-app/src/window_tab.rs b/lapce-app/src/window_tab.rs index 250f5cb943..13dce47012 100644 --- a/lapce-app/src/window_tab.rs +++ b/lapce-app/src/window_tab.rs @@ -1459,6 +1459,13 @@ impl WindowTabData { editor_data.find_refenrence(self.clone()); } } + GoToImplementation => { + if let Some(editor_data) = + self.main_split.active_editor.get_untracked() + { + editor_data.go_to_implementation(self.clone()); + } + } RunInTerminal => { if let Some(editor_data) = self.main_split.active_editor.get_untracked() @@ -2545,7 +2552,8 @@ impl WindowTabData { | PanelKind::Debug | PanelKind::CallHierarchy | PanelKind::DocumentSymbol - | PanelKind::References => { + | PanelKind::References + | PanelKind::Implementation => { // Some panels don't accept focus (yet). Fall back to visibility check // in those cases. self.panel.is_panel_visible(&kind) From a2869a4916f206cd968a7da939e3760a5712be0d Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Wed, 11 Sep 2024 20:31:25 +0800 Subject: [PATCH 53/69] 1. Add the editor setting completion_width. (#3491) --- defaults/settings.toml | 1 + lapce-app/src/app.rs | 2 +- lapce-app/src/config/editor.rs | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/defaults/settings.toml b/defaults/settings.toml index 5bcde98c19..7c3cf17124 100644 --- a/defaults/settings.toml +++ b/defaults/settings.toml @@ -21,6 +21,7 @@ wrap-style = "editor-width" wrap-column = 80 wrap-width = 600 # px sticky-header = true +completion-width = 600 completion-show-documentation = true completion-item-show-detail = false show-signature = true diff --git a/lapce-app/src/app.rs b/lapce-app/src/app.rs index ce88f8b527..30d75c10fa 100644 --- a/lapce-app/src/app.rs +++ b/lapce-app/src/app.rs @@ -3085,7 +3085,7 @@ fn completion(window_tab_data: Rc) -> impl View { let config = config.get(); let origin = window_tab_data.completion_origin(); s.position(Position::Absolute) - .width(400.0) + .width(config.editor.completion_width as i32) .max_height(400.0) .margin_left(origin.x as f32) .margin_top(origin.y as f32) diff --git a/lapce-app/src/config/editor.rs b/lapce-app/src/config/editor.rs index 81d62fac20..506edac4f4 100644 --- a/lapce-app/src/config/editor.rs +++ b/lapce-app/src/config/editor.rs @@ -96,6 +96,8 @@ pub struct EditorConfig { desc = "Show code context like functions and classes at the top of editor when scroll" )] pub sticky_header: bool, + #[field_names(desc = "The number of pixels to show completion")] + pub completion_width: usize, #[field_names( desc = "If the editor should show the documentation of the current completion item" )] From 001d766a39ff2dfed87c68cf12fb61fe296f07f2 Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Wed, 11 Sep 2024 23:10:17 +0800 Subject: [PATCH 54/69] 1. Preliminary implementation of the "Go to Implementation" panel (#3492) --- lapce-app/src/editor.rs | 13 +- lapce-app/src/main_split.rs | 3 + lapce-app/src/panel/implementation_view.rs | 236 +++++++++++++++++++++ lapce-app/src/panel/mod.rs | 1 + lapce-app/src/panel/references_view.rs | 4 +- lapce-app/src/panel/view.rs | 6 +- 6 files changed, 254 insertions(+), 9 deletions(-) create mode 100644 lapce-app/src/panel/implementation_view.rs diff --git a/lapce-app/src/editor.rs b/lapce-app/src/editor.rs index ca61c15ab5..e478e71ba7 100644 --- a/lapce-app/src/editor.rs +++ b/lapce-app/src/editor.rs @@ -77,7 +77,8 @@ use crate::{ from_marked_string, from_plaintext, parse_markdown, MarkdownContent, }, panel::{ - call_hierarchy_view::CallHierarchyItemData, kind::PanelKind, + call_hierarchy_view::CallHierarchyItemData, + implementation_view::init_implementation_root, kind::PanelKind, references_view::init_references_root, }, snippet::Snippet, @@ -1476,7 +1477,7 @@ impl EditorData { let position = buffer.offset_to_position(offset); (start_position, position) }); - let _scope = window_tab_data.scope; + let scope = window_tab_data.scope; self.common.proxy.go_to_implementation( path, position, @@ -1486,10 +1487,10 @@ impl EditorData { }) = result { tracing::info!("{:?}", resp); - // window_tab_data - // .main_split - // .references - // .update(|x| *x = init_references_root(references, scope)); + window_tab_data + .main_split + .implementations + .update(|x| *x = init_implementation_root(resp, scope)); window_tab_data.show_panel(PanelKind::Implementation); } }), diff --git a/lapce-app/src/main_split.rs b/lapce-app/src/main_split.rs index 1d9a174f59..e1481326af 100644 --- a/lapce-app/src/main_split.rs +++ b/lapce-app/src/main_split.rs @@ -383,6 +383,7 @@ pub struct MainSplitData { pub scratch_docs: RwSignal>>, pub diagnostics: RwSignal>, pub references: RwSignal, + pub implementations: RwSignal, pub active_editor: Memo>, pub find_editor: EditorData, pub replace_editor: EditorData, @@ -416,6 +417,7 @@ impl MainSplitData { let scratch_docs = cx.create_rw_signal(im::HashMap::new()); let locations = cx.create_rw_signal(im::Vector::new()); let references = cx.create_rw_signal(ReferencesRoot::default()); + let implementations = cx.create_rw_signal(ReferencesRoot::default()); let current_location = cx.create_rw_signal(0); let diagnostics = cx.create_rw_signal(im::HashMap::new()); let find_editor = editors.make_local(cx, common.clone()); @@ -476,6 +478,7 @@ impl MainSplitData { code_lens: cx.create_rw_signal(CodeLensData::new(common.clone())), common, references, + implementations, } } diff --git a/lapce-app/src/panel/implementation_view.rs b/lapce-app/src/panel/implementation_view.rs new file mode 100644 index 0000000000..b843e25401 --- /dev/null +++ b/lapce-app/src/panel/implementation_view.rs @@ -0,0 +1,236 @@ +use std::rc::Rc; + +use floem::{ + reactive::{Scope, SignalGet, SignalUpdate}, + style::CursorStyle, + views::{ + container, label, scroll, stack, svg, virtual_stack, Decorators, + VirtualDirection, VirtualItemSize, + }, + IntoView, View, ViewId, +}; +use im::HashMap; +use lsp_types::{request::GotoImplementationResponse, SymbolKind}; + +use super::position::PanelPosition; +use crate::{ + command::InternalCommand, + config::{color::LapceColor, icon::LapceIcons}, + editor::location::EditorLocation, + panel::references_view::{Reference, ReferenceLocation, ReferencesRoot}, + window_tab::WindowTabData, +}; + +pub fn implementation_panel( + window_tab_data: Rc, + _position: PanelPosition, +) -> impl View { + let main_split = window_tab_data.main_split.clone(); + let config = window_tab_data.common.config; + let ui_line_height = window_tab_data.common.ui_line_height; + scroll( + virtual_stack( + VirtualDirection::Vertical, + VirtualItemSize::Fixed(Box::new(move || ui_line_height.get())), + move || main_split.implementations.get(), + move |(_, _, data)| data.view_id(), + move |(_, level, rw_data)| { + match rw_data { + ReferenceLocation::File { path, open, .. } => { + stack(( + container(svg(move || { + let config = config.get(); + let svg_str = match open.get() { + true => LapceIcons::ITEM_OPENED, + false => LapceIcons::ITEM_CLOSED, + }; + config.ui_svg(svg_str) + }) + .style(move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + s.size(size, size) + .color(config.color(LapceColor::LAPCE_ICON_ACTIVE)) + }) + ) + .style(|s| s.padding(4.0).margin_left(6.0).margin_right(2.0)) + .on_click_stop({ + move |_x| { + open.update(|x| { + *x = !*x; + }); + } + }), + svg(move || { + let config = config.get(); + config + .symbol_svg(&SymbolKind::FILE) + .unwrap_or_else(|| config.ui_svg(LapceIcons::FILE)) + }).style(move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + s.min_width(size) + .size(size, size) + .margin_right(5.0) + .color(config.symbol_color(&SymbolKind::FILE).unwrap_or_else(|| { + config.color(LapceColor::LAPCE_ICON_ACTIVE) + })) + }), + label(move || { + format!("{:?}", path) + }).style(move |s| s.margin_left(6.0) + .color(config.get().color(LapceColor::EDITOR_DIM)) + ).into_any() + )) + .style(move |s| { + s.padding_right(5.0) + .height(ui_line_height.get()) + .padding_left((level * 10) as f32) + .items_center() + .hover(|s| { + s.background( + config + .get() + .color(LapceColor::PANEL_HOVERED_BACKGROUND), + ) + .cursor(CursorStyle::Pointer) + }) + }) + } + ReferenceLocation::Line { path, range, .. } => { + stack( + ( + container( + label( + move || { + format!("{}", range.line + 1) + }) + .style(move |s| s.margin_left(6.0) + .color(config.get().color(LapceColor::EDITOR_DIM)) + ).into_any() + ) + .style(move |s| { + s.padding_right(5.0) + .height(ui_line_height.get()) + .padding_left((level * 20) as f32) + .items_center() + .hover(|s| { + s.background( + config + .get() + .color(LapceColor::PANEL_HOVERED_BACKGROUND), + ) + .cursor(CursorStyle::Pointer) + }) + }), + ) + ).on_click_stop({ + let window_tab_data = window_tab_data.clone(); + move |_| + { + let range = range; + window_tab_data + .common + .internal_command + .send(InternalCommand::GoToLocation { + location: EditorLocation { + path: path.clone(), + position: Some(crate::editor::location::EditorPosition::Position(range)), + scroll_offset: None, + ignore_unconfirmed: false, + same_editor_tab: false, + } + }); + } + }) + } + }.style(move |s| { + s.padding_right(5.0) + .height(ui_line_height.get()) + .padding_left((level * 10) as f32) + .items_center() + .hover(|s| { + s.background( + config + .get() + .color(LapceColor::PANEL_HOVERED_BACKGROUND), + ) + .cursor(CursorStyle::Pointer) + }) + }) + }, + ) + .style(|s| s.flex_col().absolute().min_width_full()), + ) + .style(|s| s.absolute().size_full()) + .debug_name("references panel") +} + +pub fn init_implementation_root( + resp: Option, + scope: Scope, +) -> ReferencesRoot { + let Some(resp) = resp else { + return ReferencesRoot::default(); + }; + let mut refs_map = HashMap::new(); + match resp { + GotoImplementationResponse::Scalar(local) => { + if let Ok(path) = local.uri.to_file_path() { + let entry = refs_map.entry(path.clone()).or_insert(Vec::new()); + (*entry).push(Reference::Line { + location: ReferenceLocation::Line { + view_id: ViewId::new(), + path, + range: local.range.start, + }, + }) + } + } + GotoImplementationResponse::Array(items) => { + for item in items { + if let Ok(path) = item.uri.to_file_path() { + let entry = refs_map.entry(path.clone()).or_insert(Vec::new()); + (*entry).push(Reference::Line { + location: ReferenceLocation::Line { + view_id: ViewId::new(), + path, + range: item.range.start, + }, + }) + } + } + } + GotoImplementationResponse::Link(items) => { + for item in items { + if let Ok(path) = item.target_uri.to_file_path() { + let entry = refs_map.entry(path.clone()).or_insert(Vec::new()); + (*entry).push(Reference::Line { + location: ReferenceLocation::Line { + view_id: ViewId::new(), + path, + range: item.target_range.start, + }, + }) + } + } + } + } + + let mut refs = Vec::new(); + for (path, items) in refs_map { + let open = scope.create_rw_signal(true); + let ref_item = Reference::File { + location: ReferenceLocation::File { + open, + path, + view_id: ViewId::new(), + }, + children: items, + open, + }; + refs.push(ref_item); + } + tracing::debug!("children {}", refs.len()); + ReferencesRoot { children: refs } +} diff --git a/lapce-app/src/panel/mod.rs b/lapce-app/src/panel/mod.rs index db69c05cdf..016192ef88 100644 --- a/lapce-app/src/panel/mod.rs +++ b/lapce-app/src/panel/mod.rs @@ -3,6 +3,7 @@ pub mod data; pub mod debug_view; pub mod document_symbol; pub mod global_search_view; +pub mod implementation_view; pub mod kind; pub mod plugin_view; pub mod position; diff --git a/lapce-app/src/panel/references_view.rs b/lapce-app/src/panel/references_view.rs index e6d502583b..c8604daca4 100644 --- a/lapce-app/src/panel/references_view.rs +++ b/lapce-app/src/panel/references_view.rs @@ -198,7 +198,7 @@ pub fn init_references_root(items: Vec, scope: Scope) -> ReferencesRoo #[derive(Clone, Default)] pub struct ReferencesRoot { - children: Vec, + pub(crate) children: Vec, } impl VirtualVector<(usize, usize, ReferenceLocation)> for ReferencesRoot { fn total_len(&self) -> usize { @@ -247,7 +247,7 @@ impl ReferencesRoot { } #[derive(Clone)] -enum Reference { +pub enum Reference { File { location: ReferenceLocation, open: RwSignal, diff --git a/lapce-app/src/panel/view.rs b/lapce-app/src/panel/view.rs index 8a4127d018..54544fae57 100644 --- a/lapce-app/src/panel/view.rs +++ b/lapce-app/src/panel/view.rs @@ -32,6 +32,7 @@ use crate::{ file_explorer::view::file_explorer_panel, panel::{ call_hierarchy_view::show_hierarchy_panel, document_symbol::symbol_panel, + implementation_view::implementation_panel, references_view::references_panel, }, window_tab::{DragContent, WindowTabData}, @@ -500,7 +501,10 @@ fn panel_view( PanelKind::References => { references_panel(window_tab_data.clone(), position).into_any() } - PanelKind::Implementation => text("Implementation").into_any(), + PanelKind::Implementation => { + implementation_panel(window_tab_data.clone(), position) + .into_any() + } }; view.style(|s| s.size_pct(100.0, 100.0)) }, From b8772caefc82ecad54aab7c5895108634572b752 Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Thu, 12 Sep 2024 16:37:18 +0800 Subject: [PATCH 55/69] 1. show message "Debugger not found. Please install the appropriate plugin." (#3493) --- lapce-proxy/src/plugin/catalog.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/lapce-proxy/src/plugin/catalog.rs b/lapce-proxy/src/plugin/catalog.rs index 841aa63662..b17913e973 100644 --- a/lapce-proxy/src/plugin/catalog.rs +++ b/lapce-proxy/src/plugin/catalog.rs @@ -19,8 +19,8 @@ use lapce_rpc::{ use lapce_xi_rope::{Rope, RopeDelta}; use lsp_types::{ notification::DidOpenTextDocument, request::Request, DidOpenTextDocumentParams, - SemanticTokens, TextDocumentIdentifier, TextDocumentItem, - VersionedTextDocumentIdentifier, + MessageType, SemanticTokens, ShowMessageParams, TextDocumentIdentifier, + TextDocumentItem, VersionedTextDocumentIdentifier, }; use parking_lot::Mutex; use psp_types::Notification; @@ -623,6 +623,14 @@ impl PluginCatalog { } } }); + } else { + self.plugin_rpc.core_rpc.show_message( + "debug fail".to_owned(), + ShowMessageParams { + typ: MessageType::ERROR, + message: "Debugger not found. Please install the appropriate plugin.".to_owned(), + }, + ) } } DapProcessId { From b09ed0af0184d893d94120c6dc076f9e0002435c Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Thu, 12 Sep 2024 22:07:34 +0800 Subject: [PATCH 56/69] optimize some logs (#3497) --- lapce-app/src/app.rs | 6 ++++-- lapce-core/src/language.rs | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lapce-app/src/app.rs b/lapce-app/src/app.rs index 30d75c10fa..1b028b54b2 100644 --- a/lapce-app/src/app.rs +++ b/lapce-app/src/app.rs @@ -4034,8 +4034,10 @@ pub fn try_open_in_existing_process( fn listen_local_socket(tx: Sender) -> Result<()> { let local_socket = Directory::local_socket() .ok_or_else(|| anyhow!("can't get local socket folder"))?; - if let Err(err) = std::fs::remove_file(&local_socket) { - tracing::error!("{:?}", err); + if local_socket.exists() { + if let Err(err) = std::fs::remove_file(&local_socket) { + tracing::error!("{:?}", err); + } } let socket = interprocess::local_socket::LocalSocketListener::bind(local_socket)?; diff --git a/lapce-core/src/language.rs b/lapce-core/src/language.rs index c2979253e0..9d0c95d2b4 100644 --- a/lapce-core/src/language.rs +++ b/lapce-core/src/language.rs @@ -1771,7 +1771,9 @@ impl LapceLanguage { return Some(grammar); } Err(err) => { - tracing::error!("{:?}", err); + if self != &LapceLanguage::PlainText { + tracing::error!("{:?} {:?}", self, err); + } } } }; From 513be4377d54f6ae9c1ebbc7746bd50199d99daa Mon Sep 17 00:00:00 2001 From: Paolo Melchiorre Date: Fri, 13 Sep 2024 12:07:25 +0200 Subject: [PATCH 57/69] Update release.yml (#3495) Activate Ubuntu 24.04 LTS (noble) build --- .github/workflows/release.yml | 4 ++-- CHANGELOG.md | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index eef6b9e393..39a7cc45b4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -166,8 +166,8 @@ jobs: os-version: lunar - os-name: ubuntu os-version: mantic - # - os-name: ubuntu - # os-version: noble + - os-name: ubuntu + os-version: noble steps: - uses: actions/checkout@v4 diff --git a/CHANGELOG.md b/CHANGELOG.md index e265fe071c..2d770c0584 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ ### Features/Changes +- Add Ubuntu 24.04 LTS (noble) build + ### Bug Fixes ## 0.4.2 From eafaa138b1c1a65c33ccc2b501852121618f42c5 Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Fri, 13 Sep 2024 18:17:45 +0800 Subject: [PATCH 58/69] Fix loading the shell environment in Windows. (#3499) --- lapce-app/src/app.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lapce-app/src/app.rs b/lapce-app/src/app.rs index 1b028b54b2..22037ddcd9 100644 --- a/lapce-app/src/app.rs +++ b/lapce-app/src/app.rs @@ -3942,7 +3942,7 @@ pub fn launch() { } /// Uses a login shell to load the correct shell environment for the current user. -fn load_shell_env() { +pub fn load_shell_env() { use std::process::Command; use tracing::warn; @@ -3969,7 +3969,10 @@ fn load_shell_env() { command.args(["--login", "-c", "printenv"]); #[cfg(windows)] - command.args(["{ ls env: | foreach { '{0}={1}' -f $_.Name, $_.Value } }"]); + command.args(&[ + "-Command", + "Get-ChildItem env: | ForEach-Object { \"{0}={1}\" -f $_.Name, $_.Value }", + ]); let env = match command.output() { Ok(output) => String::from_utf8(output.stdout).unwrap_or_default(), @@ -3985,7 +3988,8 @@ fn load_shell_env() { env.split('\n') .filter_map(|line| line.split_once('=')) - .for_each(|(key, value)| { + .for_each(|(key, value)| unsafe { + let value = value.trim_matches('\r'); if let Ok(v) = std::env::var(key) { if v != value { warn!("Overwriting '{key}', previous value: '{v}', new value '{value}'"); From 351cfa6cbcc922a6ae93acefd8a640528dd6056d Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Fri, 13 Sep 2024 18:18:55 +0800 Subject: [PATCH 59/69] 1. Add the field 'config_source' to 'RunDebugConfig' to indicate where the configuration is from. (#3500) 2. Add the field 'main_split' to'TerminalPanelData' --- lapce-app/src/code_lens.rs | 3 ++- lapce-app/src/terminal/panel.rs | 4 ++++ lapce-app/src/window_tab.rs | 4 +++- lapce-rpc/src/dap_types.rs | 15 +++++++++++++++ 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/lapce-app/src/code_lens.rs b/lapce-app/src/code_lens.rs index 2d6f25fe2a..960f9385b7 100644 --- a/lapce-app/src/code_lens.rs +++ b/lapce-app/src/code_lens.rs @@ -1,6 +1,6 @@ use std::rc::Rc; -use lapce_rpc::dap_types::RunDebugConfig; +use lapce_rpc::dap_types::{ConfigSource, RunDebugConfig}; use serde::{Deserialize, Serialize}; use serde_json::Value; @@ -90,6 +90,7 @@ impl CodeLensData { debug_command: None, dap_id: Default::default(), tracing_output: mode == RunDebugMode::Debug, + config_source: ConfigSource::CodeLens, }) } else { tracing::error!("no args"); diff --git a/lapce-app/src/terminal/panel.rs b/lapce-app/src/terminal/panel.rs index 097455fc44..a580ccda04 100644 --- a/lapce-app/src/terminal/panel.rs +++ b/lapce-app/src/terminal/panel.rs @@ -21,6 +21,7 @@ use crate::{ }, id::TerminalTabId, keypress::{EventRef, KeyPressData, KeyPressFocus, KeyPressHandle}, + main_split::MainSplitData, panel::kind::PanelKind, window_tab::{CommonData, Focus}, workspace::LapceWorkspace, @@ -39,6 +40,7 @@ pub struct TerminalPanelData { pub debug: RunDebugData, pub breakline: Memo>, pub common: Rc, + pub main_split: MainSplitData, } impl TerminalPanelData { @@ -46,6 +48,7 @@ impl TerminalPanelData { workspace: Arc, profile: Option, common: Rc, + main_split: MainSplitData, ) -> Self { let terminal_tab = TerminalTabData::new(workspace.clone(), profile, common.clone()); @@ -108,6 +111,7 @@ impl TerminalPanelData { debug, breakline, common, + main_split, } } diff --git a/lapce-app/src/window_tab.rs b/lapce-app/src/window_tab.rs index 13dce47012..10aa610c60 100644 --- a/lapce-app/src/window_tab.rs +++ b/lapce-app/src/window_tab.rs @@ -32,7 +32,7 @@ use lapce_core::{ }; use lapce_rpc::{ core::CoreNotification, - dap_types::RunDebugConfig, + dap_types::{ConfigSource, RunDebugConfig}, file::{Naming, PathObject}, plugin::PluginId, proxy::{ProxyResponse, ProxyRpcHandler, ProxyStatus}, @@ -482,6 +482,7 @@ impl WindowTabData { workspace.clone(), common.config.get_untracked().terminal.get_default_profile(), common.clone(), + main_split.clone(), ); if let Some(workspace_info) = workspace_info.as_ref() { terminal.debug.breakpoints.set( @@ -1492,6 +1493,7 @@ impl WindowTabData { debug_command: None, dap_id: Default::default(), tracing_output: false, + config_source: ConfigSource::RunInTerminal, }; self.common .internal_command diff --git a/lapce-rpc/src/dap_types.rs b/lapce-rpc/src/dap_types.rs index d2ee6a4a3c..c4e4670707 100644 --- a/lapce-rpc/src/dap_types.rs +++ b/lapce-rpc/src/dap_types.rs @@ -59,6 +59,21 @@ pub struct RunDebugConfig { pub dap_id: DapId, #[serde(default)] pub tracing_output: bool, + #[serde(default)] + pub config_source: ConfigSource, +} + +#[derive(Deserialize, Serialize, Debug, Clone, Default, PartialEq, Eq)] +pub enum ConfigSource { + #[default] + Palette, + RunInTerminal, + CodeLens, +} +impl ConfigSource { + pub fn from_palette(&self) -> bool { + *self == Self::Palette + } } pub trait Request { From 2b8bc95a6e8fd11c0c6e8450301d67db32c2b6ce Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Mon, 16 Sep 2024 17:33:10 +0800 Subject: [PATCH 60/69] =?UTF-8?q?1.=20Add=20the=20editor=20setting=20disab?= =?UTF-8?q?le=5Fsingle=5Fclick:=20Disable=20single-click=20=E2=80=A6=20(#3?= =?UTF-8?q?494)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 1. Add the editor setting disable_single_click: Disable single-click to open files. * rename --- defaults/settings.toml | 1 + lapce-app/src/command.rs | 3 +++ lapce-app/src/config/core.rs | 4 ++++ lapce-app/src/file_explorer/data.rs | 21 +++++++++++++++++---- lapce-app/src/file_explorer/view.rs | 14 ++++++++++---- lapce-app/src/window_tab.rs | 15 +++++++++++++++ 6 files changed, 50 insertions(+), 8 deletions(-) diff --git a/defaults/settings.toml b/defaults/settings.toml index 7c3cf17124..845b6da860 100644 --- a/defaults/settings.toml +++ b/defaults/settings.toml @@ -5,6 +5,7 @@ modal = false color-theme = "Lapce Dark" icon-theme = "Lapce Codicons" custom-titlebar = true +file-exploerer-double-click = false [editor] font-family = "monospace" diff --git a/lapce-app/src/command.rs b/lapce-app/src/command.rs index c23c3b9c6f..be43cce644 100644 --- a/lapce-app/src/command.rs +++ b/lapce-app/src/command.rs @@ -604,6 +604,9 @@ pub enum InternalCommand { OpenFile { path: PathBuf, }, + OpenAndConfirmedFile { + path: PathBuf, + }, OpenFileInNewTab { path: PathBuf, }, diff --git a/lapce-app/src/config/core.rs b/lapce-app/src/config/core.rs index fce5ddfb8f..27d128d226 100644 --- a/lapce-app/src/config/core.rs +++ b/lapce-app/src/config/core.rs @@ -14,4 +14,8 @@ pub struct CoreConfig { desc = "Enable customised titlebar and disable OS native one (Linux, BSD, Windows)" )] pub custom_titlebar: bool, + #[field_names( + desc = "Only allow double-click to open files in the file explorer" + )] + pub file_exploerer_double_click: bool, } diff --git a/lapce-app/src/file_explorer/data.rs b/lapce-app/src/file_explorer/data.rs index 2c695e387f..a931c09bf8 100644 --- a/lapce-app/src/file_explorer/data.rs +++ b/lapce-app/src/file_explorer/data.rs @@ -4,6 +4,7 @@ use std::{ ffi::OsStr, path::{Path, PathBuf}, rc::Rc, + sync::Arc, }; use floem::{ @@ -12,7 +13,7 @@ use floem::{ ext_event::create_ext_action, keyboard::Modifiers, menu::{Menu, MenuItem}, - reactive::{RwSignal, Scope, SignalGet, SignalUpdate, SignalWith}, + reactive::{ReadSignal, RwSignal, Scope, SignalGet, SignalUpdate, SignalWith}, views::editor::text::SystemClipboard, }; use globset::Glob; @@ -31,6 +32,7 @@ use lapce_rpc::{ use crate::{ command::{CommandExecuted, CommandKind, InternalCommand, LapceCommand}, + config::LapceConfig, editor::EditorData, keypress::{condition::Condition, KeyPressFocus}, main_split::Editors, @@ -394,10 +396,10 @@ impl FileExplorerData { self.naming.set(Naming::None); } - pub fn click(&self, path: &Path) { + pub fn click(&self, path: &Path, config: ReadSignal>) { if self.is_dir(path) { self.toggle_expand(path); - } else { + } else if !config.get_untracked().core.file_exploerer_double_click { self.common .internal_command .send(InternalCommand::OpenFile { @@ -459,9 +461,20 @@ impl FileExplorerData { } } - pub fn double_click(&self, path: &Path) -> EventPropagation { + pub fn double_click( + &self, + path: &Path, + config: ReadSignal>, + ) -> EventPropagation { if self.is_dir(path) { EventPropagation::Continue + } else if config.get_untracked().core.file_exploerer_double_click { + self.common.internal_command.send( + InternalCommand::OpenAndConfirmedFile { + path: path.to_path_buf(), + }, + ); + EventPropagation::Stop } else { self.common .internal_command diff --git a/lapce-app/src/file_explorer/view.rs b/lapce-app/src/file_explorer/view.rs index 5b0b77bce3..d3ab9868db 100644 --- a/lapce-app/src/file_explorer/view.rs +++ b/lapce-app/src/file_explorer/view.rs @@ -401,7 +401,8 @@ fn file_explorer_view( }, ) } - }); + }) + .debug_name("file item"); // Only handle click events if we are not naming the file node if let FileNodeViewKind::Path(path) = &kind { @@ -411,13 +412,18 @@ fn file_explorer_view( let aux_click_path = path.clone(); view.on_click_stop({ let kind = kind.clone(); + let config = config.clone(); move |_| { - click_data.click(&click_path); + click_data.click(&click_path, config); select.update(|x| *x = Some(kind.clone())); } }) - .on_double_click(move |_| { - double_click_data.double_click(&double_click_path) + .on_double_click({ + let config = config.clone(); + move |_| { + double_click_data + .double_click(&double_click_path, config) + } }) .on_secondary_click_stop(move |_| { secondary_click_data.secondary_click(&secondary_click_path); diff --git a/lapce-app/src/window_tab.rs b/lapce-app/src/window_tab.rs index 10aa610c60..9e0f74989b 100644 --- a/lapce-app/src/window_tab.rs +++ b/lapce-app/src/window_tab.rs @@ -1558,6 +1558,21 @@ impl WindowTabData { None, ); } + InternalCommand::OpenAndConfirmedFile { path } => { + self.main_split.jump_to_location( + EditorLocation { + path, + position: None, + scroll_offset: None, + ignore_unconfirmed: false, + same_editor_tab: false, + }, + None, + ); + if let Some(editor) = self.main_split.active_editor.get_untracked() { + editor.confirmed.set(true); + } + } InternalCommand::OpenFileInNewTab { path } => { self.main_split.jump_to_location( EditorLocation { From ce154cedf4cf99fee85921e50c1177f437655ecd Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Mon, 16 Sep 2024 17:33:57 +0800 Subject: [PATCH 61/69] Right click (#3496) * Add a right-click command "Add Run Debug Config" to quickly add a configuration to the run.toml file * Add a right-click command "Add Run Debug Config" to quickly add a configuration to the run.toml file * add some commands --- lapce-app/src/command.rs | 4 ++ lapce-app/src/editor.rs | 105 +++++++++++++++++++++++++----------- lapce-app/src/palette.rs | 2 +- lapce-app/src/window_tab.rs | 9 +++- 4 files changed, 86 insertions(+), 34 deletions(-) diff --git a/lapce-app/src/command.rs b/lapce-app/src/command.rs index be43cce644..20352612e9 100644 --- a/lapce-app/src/command.rs +++ b/lapce-app/src/command.rs @@ -596,6 +596,10 @@ pub enum LapceWorkbenchCommand { #[strum(serialize = "go_to_location")] #[strum(message = "Go to Location")] GoToLocation, + + #[strum(serialize = "add_run_debug_config")] + #[strum(message = "Add Run Debug Config")] + AddRunDebugConfig, } #[derive(Clone, Debug)] diff --git a/lapce-app/src/editor.rs b/lapce-app/src/editor.rs index e478e71ba7..a9307900ca 100644 --- a/lapce-app/src/editor.rs +++ b/lapce-app/src/editor.rs @@ -2818,40 +2818,81 @@ impl EditorData { self.single_click(pointer_event); } - let is_file = doc.content.with_untracked(|content| content.is_file()); + let (path, is_file) = doc.content.with_untracked(|content| match content { + DocContent::File { path, .. } => { + (Some(path.to_path_buf()), path.is_file()) + } + DocContent::Local + | DocContent::History(_) + | DocContent::Scratch { .. } => (None, false), + }); let mut menu = Menu::new(""); let mut cmds = if is_file { - vec![ - Some(CommandKind::Focus(FocusCommand::GotoDefinition)), - Some(CommandKind::Focus(FocusCommand::GotoTypeDefinition)), - Some(CommandKind::Workbench( - LapceWorkbenchCommand::ShowCallHierarchy, - )), - Some(CommandKind::Workbench( - LapceWorkbenchCommand::FindReferences, - )), - Some(CommandKind::Workbench( - LapceWorkbenchCommand::GoToImplementation, - )), - Some(CommandKind::Focus(FocusCommand::Rename)), - Some(CommandKind::Workbench(LapceWorkbenchCommand::RunInTerminal)), - None, - Some(CommandKind::Workbench(LapceWorkbenchCommand::RevealInPanel)), - Some(CommandKind::Workbench( - LapceWorkbenchCommand::RevealInFileExplorer, - )), - Some(CommandKind::Workbench( - LapceWorkbenchCommand::SourceControlOpenActiveFileRemoteUrl, - )), - None, - Some(CommandKind::Edit(EditCommand::ClipboardCut)), - Some(CommandKind::Edit(EditCommand::ClipboardCopy)), - Some(CommandKind::Edit(EditCommand::ClipboardPaste)), - None, - Some(CommandKind::Workbench( - LapceWorkbenchCommand::PaletteCommand, - )), - ] + if path + .as_ref() + .and_then(|x| x.file_name().and_then(|x| x.to_str())) + .map(|x| x == "run.toml") + .unwrap_or_default() + { + vec![ + Some(CommandKind::Workbench( + LapceWorkbenchCommand::RevealInPanel, + )), + Some(CommandKind::Workbench( + LapceWorkbenchCommand::RevealInFileExplorer, + )), + Some(CommandKind::Workbench( + LapceWorkbenchCommand::SourceControlOpenActiveFileRemoteUrl, + )), + None, + Some(CommandKind::Edit(EditCommand::ClipboardCut)), + Some(CommandKind::Edit(EditCommand::ClipboardCopy)), + Some(CommandKind::Edit(EditCommand::ClipboardPaste)), + Some(CommandKind::Workbench( + LapceWorkbenchCommand::AddRunDebugConfig, + )), + None, + Some(CommandKind::Workbench( + LapceWorkbenchCommand::PaletteCommand, + )), + ] + } else { + vec![ + Some(CommandKind::Focus(FocusCommand::GotoDefinition)), + Some(CommandKind::Focus(FocusCommand::GotoTypeDefinition)), + Some(CommandKind::Workbench( + LapceWorkbenchCommand::ShowCallHierarchy, + )), + Some(CommandKind::Workbench( + LapceWorkbenchCommand::FindReferences, + )), + Some(CommandKind::Workbench( + LapceWorkbenchCommand::GoToImplementation, + )), + Some(CommandKind::Focus(FocusCommand::Rename)), + Some(CommandKind::Workbench( + LapceWorkbenchCommand::RunInTerminal, + )), + None, + Some(CommandKind::Workbench( + LapceWorkbenchCommand::RevealInPanel, + )), + Some(CommandKind::Workbench( + LapceWorkbenchCommand::RevealInFileExplorer, + )), + Some(CommandKind::Workbench( + LapceWorkbenchCommand::SourceControlOpenActiveFileRemoteUrl, + )), + None, + Some(CommandKind::Edit(EditCommand::ClipboardCut)), + Some(CommandKind::Edit(EditCommand::ClipboardCopy)), + Some(CommandKind::Edit(EditCommand::ClipboardPaste)), + None, + Some(CommandKind::Workbench( + LapceWorkbenchCommand::PaletteCommand, + )), + ] + } } else { vec![ Some(CommandKind::Edit(EditCommand::ClipboardCut)), diff --git a/lapce-app/src/palette.rs b/lapce-app/src/palette.rs index 2a2445241e..2fdc31fc4c 100644 --- a/lapce-app/src/palette.rs +++ b/lapce-app/src/palette.rs @@ -59,7 +59,7 @@ use crate::{ pub mod item; pub mod kind; -const DEFAULT_RUN_TOML: &str = include_str!("../../defaults/run.toml"); +pub const DEFAULT_RUN_TOML: &str = include_str!("../../defaults/run.toml"); #[derive(Clone, PartialEq, Eq)] pub enum PaletteStatus { diff --git a/lapce-app/src/window_tab.rs b/lapce-app/src/window_tab.rs index 9e0f74989b..486484db3d 100644 --- a/lapce-app/src/window_tab.rs +++ b/lapce-app/src/window_tab.rs @@ -72,7 +72,7 @@ use crate::{ listener::Listener, lsp::path_from_url, main_split::{MainSplitData, SplitData, SplitDirection, SplitMoveDirection}, - palette::{kind::PaletteKind, PaletteData, PaletteStatus}, + palette::{kind::PaletteKind, PaletteData, PaletteStatus, DEFAULT_RUN_TOML}, panel::{ call_hierarchy_view::{CallHierarchyData, CallHierarchyItemData}, data::{default_panel_order, PanelData, PanelSection}, @@ -1527,6 +1527,13 @@ impl WindowTabData { } }); } } + AddRunDebugConfig => { + if let Some(editor_data) = + self.main_split.active_editor.get_untracked() + { + editor_data.receive_char(DEFAULT_RUN_TOML); + } + } } } From a84ea98837c51811b4bfd98bf7a09f6859b3434d Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Mon, 16 Sep 2024 17:34:38 +0800 Subject: [PATCH 62/69] 1. reload the configuration when restarting a task from palette (#3501) --- lapce-app/src/terminal/panel.rs | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/lapce-app/src/terminal/panel.rs b/lapce-app/src/terminal/panel.rs index a580ccda04..81455b2d74 100644 --- a/lapce-app/src/terminal/panel.rs +++ b/lapce-app/src/terminal/panel.rs @@ -16,8 +16,8 @@ use lapce_rpc::{ use super::{data::TerminalData, tab::TerminalTabData}; use crate::{ debug::{ - DapData, DapVariable, RunDebugData, RunDebugMode, RunDebugProcess, - ScopeOrVar, + DapData, DapVariable, RunDebugConfigs, RunDebugData, RunDebugMode, + RunDebugProcess, ScopeOrVar, }, id::TerminalTabId, keypress::{EventRef, KeyPressData, KeyPressFocus, KeyPressHandle}, @@ -468,7 +468,14 @@ impl TerminalPanelData { pub fn restart_run_debug(&self, term_id: TermId) -> Option { let (_, terminal_tab, index, terminal) = self.get_terminal_in_tab(&term_id)?; - let run_debug = terminal.run_debug.get_untracked()?; + let mut run_debug = terminal.run_debug.get_untracked()?; + if run_debug.config.config_source.from_palette() { + if let Some(new_config) = + self.get_run_config_by_name(&run_debug.config.name) + { + run_debug.config = new_config; + } + } let mut is_debug = false; let new_term_id = match run_debug.mode { RunDebugMode::Run => { @@ -509,6 +516,26 @@ impl TerminalPanelData { Some(is_debug) } + fn get_run_config_by_name(&self, name: &str) -> Option { + if let Some(workspace) = self.common.workspace.path.as_deref() { + let run_toml = workspace.join(".lapce").join("run.toml"); + let (doc, new_doc) = self.main_split.get_doc(run_toml.clone(), None); + if !new_doc { + let content = doc.buffer.with_untracked(|b| b.to_string()); + match toml::from_str::(&content) { + Ok(configs) => { + return configs.configs.into_iter().find(|x| x.name == name); + } + Err(err) => { + // todo show message window + tracing::error!("deser fail {:?}", err); + } + } + } + } + None + } + pub fn focus_terminal(&self, term_id: TermId) { if let Some((tab_index, terminal_tab, index, _terminal)) = self.get_terminal_in_tab(&term_id) From 2773c5c9ff45634dceb788ba1ac953a8efa4a25c Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Mon, 16 Sep 2024 17:38:54 +0800 Subject: [PATCH 63/69] Fix the issue where commands without a keymap would disappear. (#3504) --- lapce-app/src/keypress.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lapce-app/src/keypress.rs b/lapce-app/src/keypress.rs index 78a6753cdf..a22b46042d 100644 --- a/lapce-app/src/keypress.rs +++ b/lapce-app/src/keypress.rs @@ -192,7 +192,12 @@ impl KeyPressData { } for (_, cmd) in self.commands.iter() { - if !self.command_keymaps.contains_key(cmd.kind.str()) { + if self + .command_keymaps + .get(cmd.kind.str()) + .map(|x| x.is_empty()) + .unwrap_or(true) + { commands_without_keymap.push(cmd.clone()); } } From 0115151aa2b71b4b52e02d7948e429890ad93636 Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Mon, 16 Sep 2024 17:48:34 +0800 Subject: [PATCH 64/69] Reimplement the functionality to capture terminal output. (#3506) --- lapce-app/src/terminal/data.rs | 6 --- lapce-app/src/terminal/raw.rs | 70 +++++++++++++++++++--------------- 2 files changed, 40 insertions(+), 36 deletions(-) diff --git a/lapce-app/src/terminal/data.rs b/lapce-app/src/terminal/data.rs index c007cf2304..2471ef8c9b 100644 --- a/lapce-app/src/terminal/data.rs +++ b/lapce-app/src/terminal/data.rs @@ -367,16 +367,10 @@ impl TerminalData { common: Rc, launch_error: RwSignal>, ) -> Arc> { - let tracing_output = run_debug - .as_ref() - .map(|run_debug| run_debug.config.tracing_output) - .unwrap_or_default(); - let raw = Arc::new(RwLock::new(RawTerminal::new( term_id, common.proxy.clone(), common.term_notification_tx.clone(), - tracing_output, ))); let mut profile = profile.unwrap_or_default(); diff --git a/lapce-app/src/terminal/raw.rs b/lapce-app/src/terminal/raw.rs index 30039b674f..2837c65ccf 100644 --- a/lapce-app/src/terminal/raw.rs +++ b/lapce-app/src/terminal/raw.rs @@ -3,6 +3,7 @@ use alacritty_terminal::{ grid::Dimensions, index::{Column, Direction, Line, Point}, term::{ + cell::{Flags, LineLength}, search::{Match, RegexIter, RegexSearch}, test::TermSize, }, @@ -49,37 +50,10 @@ impl EventListener for EventProxy { } } -pub enum TerminalOutPut { - Ingore, - Output(Vec), -} - -impl TerminalOutPut { - pub fn new(tracing_output: bool) -> Self { - if !tracing_output { - TerminalOutPut::Ingore - } else { - TerminalOutPut::Output(Vec::new()) - } - } - pub fn update(&mut self, output: &[u8]) { - if let Self::Output(content) = self { - content.extend(output) - } - } - pub fn output(&self) -> Option<&[u8]> { - match self { - TerminalOutPut::Ingore => None, - TerminalOutPut::Output(content) => Some(content), - } - } -} - pub struct RawTerminal { pub parser: ansi::Processor, pub term: Term, pub scroll_delta: f64, - pub output: TerminalOutPut, } impl RawTerminal { @@ -87,7 +61,6 @@ impl RawTerminal { term_id: TermId, proxy: ProxyRpcHandler, term_notification_tx: Sender, - tracing_output: bool, ) -> Self { let config = alacritty_terminal::term::Config { semantic_escape_chars: ",│`|\"' ()[]{}<>\t".to_string(), @@ -107,16 +80,53 @@ impl RawTerminal { parser, term, scroll_delta: 0.0, - output: TerminalOutPut::new(tracing_output), } } pub fn update_content(&mut self, content: Vec) { - self.output.update(&content); for byte in content { self.parser.advance(&mut self.term, byte); } } + + pub fn output(&self, line_num: usize) -> Vec { + let grid = self.term.grid(); + let mut lines = Vec::with_capacity(5); + let mut rows = Vec::new(); + for line in (grid.topmost_line().0..=grid.bottommost_line().0) + .map(Line) + .rev() + { + let row_cell = &grid[line]; + if row_cell[Column(row_cell.len() - 1)] + .flags + .contains(Flags::WRAPLINE) + { + rows.push(row_cell); + } else { + if !rows.is_empty() { + let mut new_line = Vec::new(); + std::mem::swap(&mut rows, &mut new_line); + let line_str: String = new_line + .into_iter() + .rev() + .flat_map(|x| { + x.into_iter().take(x.line_length().0).map(|x| x.c) + }) + .collect(); + lines.push(line_str); + if lines.len() >= line_num { + break; + } + } + rows.push(row_cell); + } + } + for line in &lines { + tracing::info!("{}", line); + } + lines + } } pub fn visible_regex_match_iter<'a, EventProxy>( From e69729efa1a56df20a27bd6f27af66d277e06276 Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Mon, 16 Sep 2024 17:52:28 +0800 Subject: [PATCH 65/69] Add the 'references_resolve' method to the proxy. (#3507) --- lapce-proxy/src/buffer.rs | 9 +++++++-- lapce-proxy/src/dispatch.rs | 32 ++++++++++++++++++++++++++++++++ lapce-rpc/src/file_line.rs | 11 +++++++++++ lapce-rpc/src/lib.rs | 1 + lapce-rpc/src/proxy.rs | 15 +++++++++++++++ 5 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 lapce-rpc/src/file_line.rs diff --git a/lapce-proxy/src/buffer.rs b/lapce-proxy/src/buffer.rs index 9c2ca90708..1e95fae8e4 100644 --- a/lapce-proxy/src/buffer.rs +++ b/lapce-proxy/src/buffer.rs @@ -131,8 +131,8 @@ impl Buffer { self.rope.to_string() } - pub fn offset_of_line(&self, offset: usize) -> usize { - self.rope.offset_of_line(offset) + pub fn offset_of_line(&self, line: usize) -> usize { + self.rope.offset_of_line(line) } pub fn line_of_offset(&self, offset: usize) -> usize { @@ -163,6 +163,11 @@ impl Buffer { self.rope.slice_to_cow(range) } + pub fn line_to_cow(&self, line: usize) -> Cow { + self.rope + .slice_to_cow(self.offset_of_line(line)..self.offset_of_line(line + 1)) + } + /// Iterate over (utf8_offset, char) values in the given range /// This uses `iter_chunks` and so does not allocate, compared to `slice_to_cow` which can pub fn char_indices_iter( diff --git a/lapce-proxy/src/dispatch.rs b/lapce-proxy/src/dispatch.rs index 511b774002..4fe0fe90e5 100644 --- a/lapce-proxy/src/dispatch.rs +++ b/lapce-proxy/src/dispatch.rs @@ -21,8 +21,10 @@ use grep_regex::RegexMatcherBuilder; use grep_searcher::{sinks::UTF8, SearcherBuilder}; use indexmap::IndexMap; use lapce_rpc::{ + buffer::BufferId, core::{CoreNotification, CoreRpcHandler}, file::FileNodeItem, + file_line::FileLine, proxy::{ ProxyHandler, ProxyNotification, ProxyRequest, ProxyResponse, ProxyRpcHandler, SearchMatch, @@ -1138,6 +1140,30 @@ impl ProxyHandler for Dispatcher { }, ); } + ReferencesResolve { items } => { + let items: Vec = items + .into_iter() + .filter_map(|location| { + let Ok(path) = location.uri.to_file_path() else { + tracing::error!( + "get file path fail: {:?}", + location.uri + ); + return None; + }; + let buffer = self.get_buffer_or_insert(path.clone()); + let line_num = location.range.start.line as usize; + let content = buffer.line_to_cow(line_num).to_string(); + Some(FileLine { + path, + position: location.range.start, + content, + }) + }) + .collect(); + let resp = ProxyResponse::ReferencesResolveResponse { items }; + self.proxy_rpc.handle_response(id, Ok(resp)); + } } } } @@ -1165,6 +1191,12 @@ impl Dispatcher { fn respond_rpc(&self, id: RequestId, result: Result) { self.proxy_rpc.handle_response(id, result); } + + fn get_buffer_or_insert(&mut self, path: PathBuf) -> &mut Buffer { + self.buffers + .entry(path.clone()) + .or_insert(Buffer::new(BufferId::next(), path)) + } } struct FileWatchNotifier { diff --git a/lapce-rpc/src/file_line.rs b/lapce-rpc/src/file_line.rs new file mode 100644 index 0000000000..5b52734596 --- /dev/null +++ b/lapce-rpc/src/file_line.rs @@ -0,0 +1,11 @@ +use std::path::PathBuf; + +use lsp_types::Position; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct FileLine { + pub path: PathBuf, + pub position: Position, + pub content: String, +} diff --git a/lapce-rpc/src/lib.rs b/lapce-rpc/src/lib.rs index 8a4c1acaa3..89c8f510f5 100644 --- a/lapce-rpc/src/lib.rs +++ b/lapce-rpc/src/lib.rs @@ -5,6 +5,7 @@ pub mod core; pub mod counter; pub mod dap_types; pub mod file; +pub mod file_line; mod parse; pub mod plugin; pub mod proxy; diff --git a/lapce-rpc/src/proxy.rs b/lapce-rpc/src/proxy.rs index f9d55bcb7f..237d640ee4 100644 --- a/lapce-rpc/src/proxy.rs +++ b/lapce-rpc/src/proxy.rs @@ -26,6 +26,7 @@ use crate::{ buffer::BufferId, dap_types::{self, DapId, RunDebugConfig, SourceBreakpoint, ThreadId}, file::{FileNodeItem, PathObject}, + file_line::FileLine, plugin::{PluginId, VoltInfo, VoltMetadata}, source_control::FileDiff, style::SemanticStyles, @@ -213,6 +214,9 @@ pub enum ProxyRequest { dap_id: DapId, frame_id: usize, }, + ReferencesResolve { + items: Vec, + }, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -451,6 +455,9 @@ pub enum ProxyResponse { }, Success {}, SaveResponse {}, + ReferencesResolveResponse { + items: Vec, + }, } pub type ProxyMessage = RpcMessage; @@ -927,6 +934,14 @@ impl ProxyRpcHandler { self.request_async(ProxyRequest::GetReferences { path, position }, f); } + pub fn references_resolve( + &self, + items: Vec, + f: impl ProxyCallback + 'static, + ) { + self.request_async(ProxyRequest::ReferencesResolve { items }, f); + } + pub fn go_to_implementation( &self, path: PathBuf, From b0ea4481b18273ecb2451bb2c89c968857a655c4 Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Wed, 18 Sep 2024 16:43:57 +0800 Subject: [PATCH 66/69] Optimize the display of implementations (#3509) --- lapce-app/src/editor.rs | 42 +- lapce-app/src/file_explorer/view.rs | 1 - lapce-app/src/main_split.rs | 6 +- lapce-app/src/panel/implementation_view.rs | 424 ++++++++++++++------- 4 files changed, 315 insertions(+), 158 deletions(-) diff --git a/lapce-app/src/editor.rs b/lapce-app/src/editor.rs index a9307900ca..628bb81407 100644 --- a/lapce-app/src/editor.rs +++ b/lapce-app/src/editor.rs @@ -78,7 +78,8 @@ use crate::{ }, panel::{ call_hierarchy_view::CallHierarchyItemData, - implementation_view::init_implementation_root, kind::PanelKind, + implementation_view::{init_implementation_root, map_to_location}, + kind::PanelKind, references_view::init_references_root, }, snippet::Snippet, @@ -1478,21 +1479,42 @@ impl EditorData { (start_position, position) }); let scope = window_tab_data.scope; - self.common.proxy.go_to_implementation( - path, - position, - create_ext_action(self.scope, move |result| { - if let Ok(ProxyResponse::GotoImplementationResponse { - resp, .. - }) = result + let update_implementation = create_ext_action(self.scope, { + let window_tab_data = window_tab_data.clone(); + move |result| { + if let Ok(ProxyResponse::ReferencesResolveResponse { items }) = + result { - tracing::info!("{:?}", resp); window_tab_data .main_split .implementations - .update(|x| *x = init_implementation_root(resp, scope)); + .update(|x| *x = init_implementation_root(items, scope)); window_tab_data.show_panel(PanelKind::Implementation); } + } + }); + let proxy = self.common.proxy.clone(); + self.common.proxy.go_to_implementation( + path, + position, + create_ext_action(self.scope, { + move |result| { + if let Ok(ProxyResponse::GotoImplementationResponse { + resp, + .. + }) = result + { + let locations = map_to_location(resp); + if !locations.is_empty() { + proxy.references_resolve( + locations, + update_implementation, + ); + } else { + window_tab_data.show_panel(PanelKind::Implementation); + } + } + } }), ); } diff --git a/lapce-app/src/file_explorer/view.rs b/lapce-app/src/file_explorer/view.rs index d3ab9868db..7af5a95fa5 100644 --- a/lapce-app/src/file_explorer/view.rs +++ b/lapce-app/src/file_explorer/view.rs @@ -412,7 +412,6 @@ fn file_explorer_view( let aux_click_path = path.clone(); view.on_click_stop({ let kind = kind.clone(); - let config = config.clone(); move |_| { click_data.click(&click_path, config); select.update(|x| *x = Some(kind.clone())); diff --git a/lapce-app/src/main_split.rs b/lapce-app/src/main_split.rs index e1481326af..e89c45c56b 100644 --- a/lapce-app/src/main_split.rs +++ b/lapce-app/src/main_split.rs @@ -383,7 +383,7 @@ pub struct MainSplitData { pub scratch_docs: RwSignal>>, pub diagnostics: RwSignal>, pub references: RwSignal, - pub implementations: RwSignal, + pub implementations: RwSignal, pub active_editor: Memo>, pub find_editor: EditorData, pub replace_editor: EditorData, @@ -417,7 +417,9 @@ impl MainSplitData { let scratch_docs = cx.create_rw_signal(im::HashMap::new()); let locations = cx.create_rw_signal(im::Vector::new()); let references = cx.create_rw_signal(ReferencesRoot::default()); - let implementations = cx.create_rw_signal(ReferencesRoot::default()); + let implementations = cx.create_rw_signal( + crate::panel::implementation_view::ReferencesRoot::default(), + ); let current_location = cx.create_rw_signal(0); let diagnostics = cx.create_rw_signal(im::HashMap::new()); let find_editor = editors.make_local(cx, common.clone()); diff --git a/lapce-app/src/panel/implementation_view.rs b/lapce-app/src/panel/implementation_view.rs index b843e25401..cd0a88bb88 100644 --- a/lapce-app/src/panel/implementation_view.rs +++ b/lapce-app/src/panel/implementation_view.rs @@ -1,23 +1,23 @@ -use std::rc::Rc; +use std::{ops::AddAssign, path::PathBuf, rc::Rc}; use floem::{ - reactive::{Scope, SignalGet, SignalUpdate}, + reactive::{RwSignal, Scope, SignalGet, SignalUpdate}, style::CursorStyle, views::{ container, label, scroll, stack, svg, virtual_stack, Decorators, - VirtualDirection, VirtualItemSize, + VirtualDirection, VirtualItemSize, VirtualVector, }, IntoView, View, ViewId, }; use im::HashMap; -use lsp_types::{request::GotoImplementationResponse, SymbolKind}; +use lapce_rpc::file_line::FileLine; +use lsp_types::{request::GotoImplementationResponse, Location, SymbolKind}; use super::position::PanelPosition; use crate::{ command::InternalCommand, config::{color::LapceColor, icon::LapceIcons}, editor::location::EditorLocation, - panel::references_view::{Reference, ReferenceLocation, ReferencesRoot}, window_tab::WindowTabData, }; @@ -36,115 +36,121 @@ pub fn implementation_panel( move |(_, _, data)| data.view_id(), move |(_, level, rw_data)| { match rw_data { - ReferenceLocation::File { path, open, .. } => { - stack(( - container(svg(move || { - let config = config.get(); - let svg_str = match open.get() { - true => LapceIcons::ITEM_OPENED, - false => LapceIcons::ITEM_CLOSED, - }; - config.ui_svg(svg_str) - }) - .style(move |s| { - let config = config.get(); - let size = config.ui.icon_size() as f32; - s.size(size, size) - .color(config.color(LapceColor::LAPCE_ICON_ACTIVE)) - }) - ) - .style(|s| s.padding(4.0).margin_left(6.0).margin_right(2.0)) - .on_click_stop({ - move |_x| { - open.update(|x| { - *x = !*x; - }); - } - }), + ReferenceLocation::File { path, open, .. } => stack(( + container( svg(move || { let config = config.get(); - config - .symbol_svg(&SymbolKind::FILE) - .unwrap_or_else(|| config.ui_svg(LapceIcons::FILE)) - }).style(move |s| { + let svg_str = match open.get() { + true => LapceIcons::ITEM_OPENED, + false => LapceIcons::ITEM_CLOSED, + }; + config.ui_svg(svg_str) + }) + .style(move |s| { let config = config.get(); let size = config.ui.icon_size() as f32; - s.min_width(size) - .size(size, size) - .margin_right(5.0) - .color(config.symbol_color(&SymbolKind::FILE).unwrap_or_else(|| { - config.color(LapceColor::LAPCE_ICON_ACTIVE) - })) + s.size(size, size).color( + config.color(LapceColor::LAPCE_ICON_ACTIVE), + ) }), - label(move || { - format!("{:?}", path) - }).style(move |s| s.margin_left(6.0) - .color(config.get().color(LapceColor::EDITOR_DIM)) - ).into_any() - )) - .style(move |s| { - s.padding_right(5.0) - .height(ui_line_height.get()) - .padding_left((level * 10) as f32) - .items_center() - .hover(|s| { - s.background( + ) + .style(|s| s.padding(4.0).margin_left(6.0).margin_right(2.0)) + .on_click_stop({ + move |_x| { + open.update(|x| { + *x = !*x; + }); + } + }), + svg(move || { + let config = config.get(); + config + .symbol_svg(&SymbolKind::FILE) + .unwrap_or_else(|| config.ui_svg(LapceIcons::FILE)) + }) + .style(move |s| { + let config = config.get(); + let size = config.ui.icon_size() as f32; + s.min_width(size) + .size(size, size) + .margin_right(5.0) + .color( + config + .symbol_color(&SymbolKind::FILE) + .unwrap_or_else(|| { config - .get() - .color(LapceColor::PANEL_HOVERED_BACKGROUND), - ) - .cursor(CursorStyle::Pointer) - }) + .color(LapceColor::LAPCE_ICON_ACTIVE) + }), + ) + }), + label(move || format!("{:?}", path)) + .style(move |s| { + s.margin_left(6.0).color( + config.get().color(LapceColor::EDITOR_DIM), + ) }) - } - ReferenceLocation::Line { path, range, .. } => { - stack( - ( - container( - label( - move || { - format!("{}", range.line + 1) - }) - .style(move |s| s.margin_left(6.0) - .color(config.get().color(LapceColor::EDITOR_DIM)) - ).into_any() - ) + .into_any(), + )) + .style(move |s| { + s.padding_right(5.0) + .height(ui_line_height.get()) + .padding_left((level * 10) as f32) + .items_center() + .hover(|s| { + s.background( + config + .get() + .color(LapceColor::PANEL_HOVERED_BACKGROUND), + ) + .cursor(CursorStyle::Pointer) + }) + }), + ReferenceLocation::Line { file_line, .. } => stack((container( + label(move || format!("{} {}", file_line.position.line + 1, file_line.content)) .style(move |s| { - s.padding_right(5.0) - .height(ui_line_height.get()) - .padding_left((level * 20) as f32) - .items_center() - .hover(|s| { - s.background( - config - .get() - .color(LapceColor::PANEL_HOVERED_BACKGROUND), - ) - .cursor(CursorStyle::Pointer) - }) - }), - ) - ).on_click_stop({ + s.margin_left(6.0).color( + config.get().color(LapceColor::EDITOR_DIM), + ) + }) + .into_any(), + ) + .style(move |s| { + s.padding_right(5.0) + .height(ui_line_height.get()) + .padding_left((level * 20) as f32) + .items_center() + .hover(|s| { + s.background( + config + .get() + .color(LapceColor::PANEL_HOVERED_BACKGROUND), + ) + .cursor(CursorStyle::Pointer) + }) + }),)) + .on_click_stop({ let window_tab_data = window_tab_data.clone(); - move |_| - { - let range = range; - window_tab_data - .common - .internal_command - .send(InternalCommand::GoToLocation { + let position = file_line.position; + move |_| { + window_tab_data.common.internal_command.send( + InternalCommand::GoToLocation { location: EditorLocation { - path: path.clone(), - position: Some(crate::editor::location::EditorPosition::Position(range)), + path: file_line.path.clone(), + position: Some( + crate::editor::location::EditorPosition::Position( + position, + ), + ), scroll_offset: None, ignore_unconfirmed: false, same_editor_tab: false, - } - }); + }, + }, + ); } - }) - } - }.style(move |s| { + }), + } + .style(move |s| { s.padding_right(5.0) .height(ui_line_height.get()) .padding_left((level * 10) as f32) @@ -155,7 +161,7 @@ pub fn implementation_panel( .get() .color(LapceColor::PANEL_HOVERED_BACKGROUND), ) - .cursor(CursorStyle::Pointer) + .cursor(CursorStyle::Pointer) }) }) }, @@ -166,55 +172,38 @@ pub fn implementation_panel( .debug_name("references panel") } -pub fn init_implementation_root( - resp: Option, - scope: Scope, -) -> ReferencesRoot { +pub fn map_to_location(resp: Option) -> Vec { let Some(resp) = resp else { - return ReferencesRoot::default(); + return Vec::new(); }; - let mut refs_map = HashMap::new(); match resp { GotoImplementationResponse::Scalar(local) => { - if let Ok(path) = local.uri.to_file_path() { - let entry = refs_map.entry(path.clone()).or_insert(Vec::new()); - (*entry).push(Reference::Line { - location: ReferenceLocation::Line { - view_id: ViewId::new(), - path, - range: local.range.start, - }, - }) - } - } - GotoImplementationResponse::Array(items) => { - for item in items { - if let Ok(path) = item.uri.to_file_path() { - let entry = refs_map.entry(path.clone()).or_insert(Vec::new()); - (*entry).push(Reference::Line { - location: ReferenceLocation::Line { - view_id: ViewId::new(), - path, - range: item.range.start, - }, - }) - } - } - } - GotoImplementationResponse::Link(items) => { - for item in items { - if let Ok(path) = item.target_uri.to_file_path() { - let entry = refs_map.entry(path.clone()).or_insert(Vec::new()); - (*entry).push(Reference::Line { - location: ReferenceLocation::Line { - view_id: ViewId::new(), - path, - range: item.target_range.start, - }, - }) - } - } + vec![local] } + GotoImplementationResponse::Array(items) => items, + GotoImplementationResponse::Link(items) => items + .into_iter() + .map(|x| Location { + uri: x.target_uri, + range: x.target_range, + }) + .collect(), + } +} + +pub fn init_implementation_root( + items: Vec, + scope: Scope, +) -> ReferencesRoot { + let mut refs_map = HashMap::new(); + for item in items { + let entry = refs_map.entry(item.path.clone()).or_insert(Vec::new()); + (*entry).push(Reference::Line { + location: ReferenceLocation::Line { + file_line: item, + view_id: ViewId::new(), + }, + }) } let mut refs = Vec::new(); @@ -234,3 +223,148 @@ pub fn init_implementation_root( tracing::debug!("children {}", refs.len()); ReferencesRoot { children: refs } } + +#[derive(Clone, Default)] +pub struct ReferencesRoot { + pub(crate) children: Vec, +} + +impl ReferencesRoot { + pub fn total(&self) -> usize { + let mut total = 0; + for child in &self.children { + total += child.total_len() + } + total + } + + fn get_children( + &self, + next: &mut usize, + min: usize, + max: usize, + level: usize, + ) -> Vec<(usize, usize, ReferenceLocation)> { + let mut children = Vec::new(); + for child in &self.children { + let child_children = child.get_children(next, min, max, level + 1); + if !child_children.is_empty() { + children.extend(child_children); + } + if *next > max { + break; + } + } + children + } +} + +impl VirtualVector<(usize, usize, ReferenceLocation)> for ReferencesRoot { + fn total_len(&self) -> usize { + self.total() + } + + fn slice( + &mut self, + range: std::ops::Range, + ) -> impl Iterator { + let min = range.start; + let max = range.end; + let children = self.get_children(&mut 0, min, max, 0); + children.into_iter() + } +} + +#[derive(Clone)] +pub enum Reference { + File { + location: ReferenceLocation, + open: RwSignal, + children: Vec, + }, + Line { + location: ReferenceLocation, + }, +} + +#[derive(Clone)] +pub enum ReferenceLocation { + File { + path: PathBuf, + open: RwSignal, + view_id: ViewId, + }, + Line { + file_line: FileLine, + view_id: ViewId, + }, +} + +impl ReferenceLocation { + pub fn view_id(&self) -> ViewId { + match self { + ReferenceLocation::File { view_id, .. } => *view_id, + ReferenceLocation::Line { view_id, .. } => *view_id, + } + } +} + +impl Reference { + pub fn location(&self) -> ReferenceLocation { + match self { + Reference::File { location, .. } => location.clone(), + Reference::Line { location } => location.clone(), + } + } + pub fn total_len(&self) -> usize { + match self { + Reference::File { children, .. } => { + let mut total = 1; + for child in children { + total += child.total_len() + } + total + } + Reference::Line { .. } => 1, + } + } + pub fn children(&self) -> Option<&Vec> { + match self { + Reference::File { children, open, .. } => { + if open.get() { + return Some(children); + } + None + } + Reference::Line { .. } => None, + } + } + + fn get_children( + &self, + next: &mut usize, + min: usize, + max: usize, + level: usize, + ) -> Vec<(usize, usize, ReferenceLocation)> { + let mut children = Vec::new(); + if *next >= min && *next < max { + children.push((*next, level, self.location())); + } else if *next >= max { + return children; + } + next.add_assign(1); + if let Some(children_tmp) = self.children() { + for child in children_tmp { + let child_children = child.get_children(next, min, max, level + 1); + if !child_children.is_empty() { + children.extend(child_children); + } + if *next > max { + break; + } + } + } + children + } +} From cfb7d204da346a346a79fb3958c03f5beb04d6b0 Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Wed, 18 Sep 2024 16:46:24 +0800 Subject: [PATCH 67/69] Add thread names for easier tracking and troubleshooting. (#3510) --- lapce-app/src/app.rs | 94 +++++++++++++++------------ lapce-app/src/db.rs | 80 ++++++++++++----------- lapce-app/src/palette.rs | 9 ++- lapce-app/src/plugin.rs | 31 +++++---- lapce-app/src/proxy.rs | 112 +++++++++++++++++--------------- lapce-app/src/proxy/remote.rs | 118 ++++++++++++++++++---------------- lapce-app/src/window_tab.rs | 13 ++-- 7 files changed, 249 insertions(+), 208 deletions(-) diff --git a/lapce-app/src/app.rs b/lapce-app/src/app.rs index 22037ddcd9..c7d3fe7623 100644 --- a/lapce-app/src/app.rs +++ b/lapce-app/src/app.rs @@ -3844,38 +3844,44 @@ pub fn launch() { } } }); - std::thread::spawn(move || { - use self::grammars::*; - let updated = match find_grammar_release() { - Ok(release) => { - let mut updated = false; - match fetch_grammars(&release) { - Err(e) => { - trace!( - TraceLevel::ERROR, - "failed to fetch grammars: {e}" - ); + std::thread::Builder::new() + .name("FindGrammar".to_owned()) + .spawn(move || { + use self::grammars::*; + let updated = match find_grammar_release() { + Ok(release) => { + let mut updated = false; + match fetch_grammars(&release) { + Err(e) => { + trace!( + TraceLevel::ERROR, + "failed to fetch grammars: {e}" + ); + } + Ok(u) => updated |= u, } - Ok(u) => updated |= u, - } - match fetch_queries(&release) { - Err(e) => { - trace!( - TraceLevel::ERROR, - "failed to fetch grammars: {e}" - ); + match fetch_queries(&release) { + Err(e) => { + trace!( + TraceLevel::ERROR, + "failed to fetch grammars: {e}" + ); + } + Ok(u) => updated |= u, } - Ok(u) => updated |= u, + updated } - updated - } - Err(e) => { - trace!(TraceLevel::ERROR, "failed to obtain release info: {e}"); - false - } - }; - send(updated); - }); + Err(e) => { + trace!( + TraceLevel::ERROR, + "failed to obtain release info: {e}" + ); + false + } + }; + send(updated); + }) + .unwrap(); } #[cfg(feature = "updater")] @@ -3888,14 +3894,17 @@ pub fn launch() { latest_release.set(Arc::new(Some(release))); } }); - std::thread::spawn(move || loop { - if let Ok(release) = crate::update::get_latest_release() { - if let Err(err) = tx.send(release) { - tracing::error!("{:?}", err); + std::thread::Builder::new() + .name("LapceUpdater".to_owned()) + .spawn(move || loop { + if let Ok(release) = crate::update::get_latest_release() { + if let Err(err) = tx.send(release) { + tracing::error!("{:?}", err); + } } - } - std::thread::sleep(std::time::Duration::from_secs(60 * 60)); - }); + std::thread::sleep(std::time::Duration::from_secs(60 * 60)); + }) + .unwrap(); } { @@ -3909,11 +3918,14 @@ pub fn launch() { } } }); - std::thread::spawn(move || { - if let Err(err) = listen_local_socket(tx) { - tracing::error!("{:?}", err); - } - }); + std::thread::Builder::new() + .name("ListenLocalSocket".to_owned()) + .spawn(move || { + if let Err(err) = listen_local_socket(tx) { + tracing::error!("{:?}", err); + } + }) + .unwrap(); } { diff --git a/lapce-app/src/db.rs b/lapce-app/src/db.rs index 74531187f5..a017deec48 100644 --- a/lapce-app/src/db.rs +++ b/lapce-app/src/db.rs @@ -63,53 +63,57 @@ impl LapceDb { folder, }; let local_db = db.clone(); - std::thread::spawn(move || -> Result<()> { - loop { - let event = save_rx.recv()?; - match event { - SaveEvent::App(info) => { - if let Err(err) = local_db.insert_app_info(info) { - tracing::error!("{:?}", err); + std::thread::Builder::new() + .name("SaveEventHandler".to_owned()) + .spawn(move || -> Result<()> { + loop { + let event = save_rx.recv()?; + match event { + SaveEvent::App(info) => { + if let Err(err) = local_db.insert_app_info(info) { + tracing::error!("{:?}", err); + } } - } - SaveEvent::Workspace(workspace, info) => { - if let Err(err) = - local_db.insert_workspace(&workspace, &info) - { - tracing::error!("{:?}", err); + SaveEvent::Workspace(workspace, info) => { + if let Err(err) = + local_db.insert_workspace(&workspace, &info) + { + tracing::error!("{:?}", err); + } } - } - SaveEvent::RecentWorkspace(workspace) => { - if let Err(err) = local_db.insert_recent_workspace(workspace) - { - tracing::error!("{:?}", err); + SaveEvent::RecentWorkspace(workspace) => { + if let Err(err) = + local_db.insert_recent_workspace(workspace) + { + tracing::error!("{:?}", err); + } } - } - SaveEvent::Doc(info) => { - if let Err(err) = local_db.insert_doc(&info) { - tracing::error!("{:?}", err); + SaveEvent::Doc(info) => { + if let Err(err) = local_db.insert_doc(&info) { + tracing::error!("{:?}", err); + } } - } - SaveEvent::DisabledVolts(volts) => { - if let Err(err) = local_db.insert_disabled_volts(volts) { - tracing::error!("{:?}", err); + SaveEvent::DisabledVolts(volts) => { + if let Err(err) = local_db.insert_disabled_volts(volts) { + tracing::error!("{:?}", err); + } } - } - SaveEvent::WorkspaceDisabledVolts(workspace, volts) => { - if let Err(err) = local_db - .insert_workspace_disabled_volts(workspace, volts) - { - tracing::error!("{:?}", err); + SaveEvent::WorkspaceDisabledVolts(workspace, volts) => { + if let Err(err) = local_db + .insert_workspace_disabled_volts(workspace, volts) + { + tracing::error!("{:?}", err); + } } - } - SaveEvent::PanelOrder(order) => { - if let Err(err) = local_db.insert_panel_orders(&order) { - tracing::error!("{:?}", err); + SaveEvent::PanelOrder(order) => { + if let Err(err) = local_db.insert_panel_orders(&order) { + tracing::error!("{:?}", err); + } } } } - } - }); + }) + .unwrap(); Ok(db) } diff --git a/lapce-app/src/palette.rs b/lapce-app/src/palette.rs index 2fdc31fc4c..6af5c72216 100644 --- a/lapce-app/src/palette.rs +++ b/lapce-app/src/palette.rs @@ -180,9 +180,12 @@ impl PaletteData { let (resp_tx, resp_rx) = crossbeam_channel::unbounded(); { let run_id = run_id_counter.clone(); - std::thread::spawn(move || { - Self::update_process(run_id, run_rx, resp_tx); - }); + std::thread::Builder::new() + .name("PaletteUpdateProcess".to_owned()) + .spawn(move || { + Self::update_process(run_id, run_rx, resp_tx); + }) + .unwrap(); } let (filtered_items, set_filtered_items) = cx.create_signal(im::Vector::new()); diff --git a/lapce-app/src/plugin.rs b/lapce-app/src/plugin.rs index d659cef297..f57fb59aec 100644 --- a/lapce-app/src/plugin.rs +++ b/lapce-app/src/plugin.rs @@ -198,20 +198,23 @@ impl PluginData { } }, ); - std::thread::spawn(move || { - let volts = find_all_volts(&extra_plugin_paths); - let volts = volts - .into_iter() - .filter_map(|meta| { - if meta.wasm.is_none() { - Some((volt_icon(&meta), meta)) - } else { - None - } - }) - .collect::>(); - send(volts); - }); + std::thread::Builder::new() + .name("FindAllVolts".to_owned()) + .spawn(move || { + let volts = find_all_volts(&extra_plugin_paths); + let volts = volts + .into_iter() + .filter_map(|meta| { + if meta.wasm.is_none() { + Some((volt_icon(&meta), meta)) + } else { + None + } + }) + .collect::>(); + send(volts); + }) + .unwrap(); } { diff --git a/lapce-app/src/proxy.rs b/lapce-app/src/proxy.rs index 28503a0c67..61efd7c47e 100644 --- a/lapce-app/src/proxy.rs +++ b/lapce-app/src/proxy.rs @@ -54,66 +54,76 @@ pub fn new_proxy( { let core_rpc = core_rpc.clone(); let proxy_rpc = proxy_rpc.clone(); - std::thread::spawn(move || { - core_rpc.notification(CoreNotification::ProxyStatus { - status: ProxyStatus::Connecting, - }); - proxy_rpc.initialize( - workspace.path.clone(), - disabled_volts, - extra_plugin_paths, - plugin_configurations, - 1, - 1, - ); + std::thread::Builder::new() + .name("ProxyRpcHandler".to_owned()) + .spawn(move || { + core_rpc.notification(CoreNotification::ProxyStatus { + status: ProxyStatus::Connecting, + }); + proxy_rpc.initialize( + workspace.path.clone(), + disabled_volts, + extra_plugin_paths, + plugin_configurations, + 1, + 1, + ); - match &workspace.kind { - LapceWorkspaceType::Local => { - let core_rpc = core_rpc.clone(); - let proxy_rpc = proxy_rpc.clone(); - std::thread::spawn(move || { - let mut dispatcher = Dispatcher::new(core_rpc, proxy_rpc); - let proxy_rpc = dispatcher.proxy_rpc.clone(); - proxy_rpc.mainloop(&mut dispatcher); - }); - } - LapceWorkspaceType::RemoteSSH(remote) => { - if let Err(e) = start_remote( - SshRemote { - ssh: remote.clone(), - }, - core_rpc.clone(), - proxy_rpc.clone(), - ) { - error!("Failed to start SSH remote: {e}"); + match &workspace.kind { + LapceWorkspaceType::Local => { + let core_rpc = core_rpc.clone(); + let proxy_rpc = proxy_rpc.clone(); + std::thread::Builder::new() + .name("Dispatcher".to_owned()) + .spawn(move || { + let mut dispatcher = + Dispatcher::new(core_rpc, proxy_rpc); + let proxy_rpc = dispatcher.proxy_rpc.clone(); + proxy_rpc.mainloop(&mut dispatcher); + }) + .unwrap(); } - } - #[cfg(windows)] - LapceWorkspaceType::RemoteWSL(remote) => { - if let Err(e) = start_remote( - wsl::WslRemote { - wsl: remote.clone(), - }, - core_rpc.clone(), - proxy_rpc.clone(), - ) { - error!("Failed to start SSH remote: {e}"); + LapceWorkspaceType::RemoteSSH(remote) => { + if let Err(e) = start_remote( + SshRemote { + ssh: remote.clone(), + }, + core_rpc.clone(), + proxy_rpc.clone(), + ) { + error!("Failed to start SSH remote: {e}"); + } + } + #[cfg(windows)] + LapceWorkspaceType::RemoteWSL(remote) => { + if let Err(e) = start_remote( + wsl::WslRemote { + wsl: remote.clone(), + }, + core_rpc.clone(), + proxy_rpc.clone(), + ) { + error!("Failed to start SSH remote: {e}"); + } } } - } - }); + }) + .unwrap(); } let (tx, rx) = crossbeam_channel::unbounded(); { let core_rpc = core_rpc.clone(); - std::thread::spawn(move || { - let mut proxy = Proxy { tx, term_tx }; - core_rpc.mainloop(&mut proxy); - core_rpc.notification(CoreNotification::ProxyStatus { - status: ProxyStatus::Connected, - }); - }) + std::thread::Builder::new() + .name("CoreRpcHandler".to_owned()) + .spawn(move || { + let mut proxy = Proxy { tx, term_tx }; + core_rpc.mainloop(&mut proxy); + core_rpc.notification(CoreNotification::ProxyStatus { + status: ProxyStatus::Connected, + }); + }) + .unwrap() }; let notification = create_signal_from_channel(rx); diff --git a/lapce-app/src/proxy/remote.rs b/lapce-app/src/proxy/remote.rs index e4aa7e066e..7a216fca98 100644 --- a/lapce-app/src/proxy/remote.rs +++ b/lapce-app/src/proxy/remote.rs @@ -177,71 +177,77 @@ pub fn start_remote( let local_proxy_rpc = proxy_rpc.clone(); let local_writer_tx = writer_tx.clone(); - std::thread::spawn(move || { - for msg in local_proxy_rpc.rx() { - match msg { - ProxyRpc::Request(id, rpc) => { - if let Err(err) = - local_writer_tx.send(RpcMessage::Request(id, rpc)) - { - tracing::error!("{:?}", err); - } - } - ProxyRpc::Notification(rpc) => { - if let Err(err) = - local_writer_tx.send(RpcMessage::Notification(rpc)) - { - tracing::error!("{:?}", err); + std::thread::Builder::new() + .name("ProxyRpcHandler".to_owned()) + .spawn(move || { + for msg in local_proxy_rpc.rx() { + match msg { + ProxyRpc::Request(id, rpc) => { + if let Err(err) = + local_writer_tx.send(RpcMessage::Request(id, rpc)) + { + tracing::error!("{:?}", err); + } } - } - ProxyRpc::Shutdown => { - if let Err(err) = child.kill() { - tracing::error!("{:?}", err); + ProxyRpc::Notification(rpc) => { + if let Err(err) = + local_writer_tx.send(RpcMessage::Notification(rpc)) + { + tracing::error!("{:?}", err); + } } - if let Err(err) = child.wait() { - tracing::error!("{:?}", err); + ProxyRpc::Shutdown => { + if let Err(err) = child.kill() { + tracing::error!("{:?}", err); + } + if let Err(err) = child.wait() { + tracing::error!("{:?}", err); + } + return; } - return; } } - } - }); - - std::thread::spawn(move || { - for msg in reader_rx { - match msg { - RpcMessage::Request(id, req) => { - let writer_tx = writer_tx.clone(); - let core_rpc = core_rpc.clone(); - std::thread::spawn(move || match core_rpc.request(req) { - Ok(resp) => { - if let Err(err) = - writer_tx.send(RpcMessage::Response(id, resp)) - { - tracing::error!("{:?}", err); + }) + .unwrap(); + + std::thread::Builder::new() + .name("RpcMessageHandler".to_owned()) + .spawn(move || { + for msg in reader_rx { + match msg { + RpcMessage::Request(id, req) => { + let writer_tx = writer_tx.clone(); + let core_rpc = core_rpc.clone(); + std::thread::spawn(move || match core_rpc.request(req) { + Ok(resp) => { + if let Err(err) = + writer_tx.send(RpcMessage::Response(id, resp)) + { + tracing::error!("{:?}", err); + } } - } - Err(e) => { - if let Err(err) = - writer_tx.send(RpcMessage::Error(id, e)) - { - tracing::error!("{:?}", err); + Err(e) => { + if let Err(err) = + writer_tx.send(RpcMessage::Error(id, e)) + { + tracing::error!("{:?}", err); + } } - } - }); - } - RpcMessage::Notification(n) => { - core_rpc.notification(n); - } - RpcMessage::Response(id, resp) => { - proxy_rpc.handle_response(id, Ok(resp)); - } - RpcMessage::Error(id, err) => { - proxy_rpc.handle_response(id, Err(err)); + }); + } + RpcMessage::Notification(n) => { + core_rpc.notification(n); + } + RpcMessage::Response(id, resp) => { + proxy_rpc.handle_response(id, Ok(resp)); + } + RpcMessage::Error(id, err) => { + proxy_rpc.handle_response(id, Err(err)); + } } } - } - }); + }) + .unwrap(); Ok(()) } diff --git a/lapce-app/src/window_tab.rs b/lapce-app/src/window_tab.rs index 486484db3d..7662693482 100644 --- a/lapce-app/src/window_tab.rs +++ b/lapce-app/src/window_tab.rs @@ -318,9 +318,12 @@ impl WindowTabData { crossbeam_channel::unbounded(); { let term_notification_tx = term_notification_tx.clone(); - std::thread::spawn(move || { - terminal_update_process(term_rx, term_notification_tx); - }); + std::thread::Builder::new() + .name("terminal update process".to_owned()) + .spawn(move || { + terminal_update_process(term_rx, term_notification_tx); + }) + .unwrap(); } let proxy = new_proxy( @@ -1326,7 +1329,7 @@ impl WindowTabData { update_in_progress.set(false); }, ); - std::thread::spawn(move || { + std::thread::Builder::new().name("RestartToUpdate".to_owned()).spawn(move || { let do_update = || -> anyhow::Result<()> { let src = crate::update::download_release(&release)?; @@ -1344,7 +1347,7 @@ impl WindowTabData { } send(false); - }); + }).unwrap(); } } } From 18b1a70d02fb37fdf52f1cd51b8858ab51b2f1a8 Mon Sep 17 00:00:00 2001 From: ifengqi <362254883@qq.com> Date: Wed, 18 Sep 2024 16:47:13 +0800 Subject: [PATCH 68/69] 1. Sending the 'UpdatePluginConfigs' proxy notification when the plugin's configuration changes. (#3516) 2. add some logs --- lapce-app/src/app.rs | 1 + lapce-app/src/window_tab.rs | 5 +++++ lapce-proxy/src/plugin/catalog.rs | 7 +++++++ 3 files changed, 13 insertions(+) diff --git a/lapce-app/src/app.rs b/lapce-app/src/app.rs index c7d3fe7623..507ab0e21b 100644 --- a/lapce-app/src/app.rs +++ b/lapce-app/src/app.rs @@ -3817,6 +3817,7 @@ pub fn launch() { let notification = create_signal_from_channel(rx); create_effect(move |_| { if notification.get().is_some() { + tracing::debug!("notification reload_config"); app_data.reload_config(); } }); diff --git a/lapce-app/src/window_tab.rs b/lapce-app/src/window_tab.rs index 7662693482..fac2a9034b 100644 --- a/lapce-app/src/window_tab.rs +++ b/lapce-app/src/window_tab.rs @@ -644,6 +644,11 @@ impl WindowTabData { self.common.keypress.update(|keypress| { keypress.update_keymaps(&config); }); + if self.common.config.get_untracked().plugins != config.plugins { + self.common + .proxy + .update_plugin_configs(config.plugins.clone()); + } self.set_config.set(Arc::new(config)); } diff --git a/lapce-proxy/src/plugin/catalog.rs b/lapce-proxy/src/plugin/catalog.rs index b17913e973..83e38bf781 100644 --- a/lapce-proxy/src/plugin/catalog.rs +++ b/lapce-proxy/src/plugin/catalog.rs @@ -207,6 +207,7 @@ impl PluginCatalog { if let Some(meta) = self.unactivated_volts.remove(id) { let configurations = self.plugin_configurations.get(&meta.name).cloned(); + tracing::debug!("{:?} {:?}", id, configurations); let plugin_rpc = self.plugin_rpc.clone(); thread::spawn(move || { if let Err(err) = @@ -480,6 +481,7 @@ impl PluginCatalog { use PluginCatalogNotification::*; match notification { UnactivatedVolts(volts) => { + tracing::debug!("UnactivatedVolts {:?}", volts); for volt in volts { let id = volt.id(); self.unactivated_volts.insert(id, volt); @@ -487,6 +489,7 @@ impl PluginCatalog { self.check_unactivated_volts(); } UpdatePluginConfigs(configs) => { + tracing::debug!("UpdatePluginConfigs {:?}", configs); self.plugin_configurations = configs; } PluginServerLoaded(plugin) => { @@ -529,6 +532,7 @@ impl PluginCatalog { } } InstallVolt(volt) => { + tracing::debug!("InstallVolt {:?}", volt); let workspace = self.workspace.clone(); let configurations = self.plugin_configurations.get(&volt.name).cloned(); @@ -543,6 +547,7 @@ impl PluginCatalog { }); } ReloadVolt(volt) => { + tracing::debug!("ReloadVolt {:?}", volt); let volt_id = volt.id(); let ids: Vec = self.plugins.keys().cloned().collect(); for id in ids { @@ -556,6 +561,7 @@ impl PluginCatalog { } } StopVolt(volt) => { + tracing::debug!("StopVolt {:?}", volt); let volt_id = volt.id(); let ids: Vec = self.plugins.keys().cloned().collect(); for id in ids { @@ -566,6 +572,7 @@ impl PluginCatalog { } } EnableVolt(volt) => { + tracing::debug!("EnableVolt {:?}", volt); let volt_id = volt.id(); for (_, volt) in self.plugins.iter() { if volt.volt_id == volt_id { From 57a4c4b55ee8c8f69f99663184ec0112380521e9 Mon Sep 17 00:00:00 2001 From: fengqi <362254883@qq.com> Date: Wed, 18 Sep 2024 22:59:31 +0800 Subject: [PATCH 69/69] Implement the LSP $/cancelRequest notification --- lapce-proxy/src/dispatch.rs | 16 +++++++++++++++- lapce-proxy/src/plugin/psp.rs | 9 +++++++-- lapce-rpc/src/core.rs | 11 +++++++++-- lapce-rpc/src/proxy.rs | 7 +++++++ 4 files changed, 38 insertions(+), 5 deletions(-) diff --git a/lapce-proxy/src/dispatch.rs b/lapce-proxy/src/dispatch.rs index 4fe0fe90e5..6a06d50fa2 100644 --- a/lapce-proxy/src/dispatch.rs +++ b/lapce-proxy/src/dispatch.rs @@ -36,7 +36,9 @@ use lapce_rpc::{ }; use lapce_xi_rope::Rope; use lsp_types::{ - MessageType, Position, Range, ShowMessageParams, TextDocumentItem, Url, + notification::{Cancel, Notification}, + CancelParams, MessageType, NumberOrString, Position, Range, ShowMessageParams, + TextDocumentItem, Url, }; use parking_lot::Mutex; @@ -373,6 +375,18 @@ impl ProxyHandler for Dispatcher { } } } + LspCancel { id } => { + self.catalog_rpc.send_notification( + None, + Cancel::METHOD, + CancelParams { + id: NumberOrString::Number(id), + }, + None, + None, + false, + ); + } } } diff --git a/lapce-proxy/src/plugin/psp.rs b/lapce-proxy/src/plugin/psp.rs index 205aa72f48..4c385e4f01 100644 --- a/lapce-proxy/src/plugin/psp.rs +++ b/lapce-proxy/src/plugin/psp.rs @@ -24,7 +24,7 @@ use lapce_rpc::{ use lapce_xi_rope::{Rope, RopeDelta}; use lsp_types::{ notification::{ - DidChangeTextDocument, DidOpenTextDocument, DidSaveTextDocument, + Cancel, DidChangeTextDocument, DidOpenTextDocument, DidSaveTextDocument, Initialized, LogMessage, Notification, Progress, PublishDiagnostics, ShowMessage, }, @@ -38,7 +38,7 @@ use lsp_types::{ SemanticTokensFullRequest, SignatureHelpRequest, WorkDoneProgressCreate, WorkspaceSymbolRequest, }, - CodeActionProviderCapability, DidChangeTextDocumentParams, + CancelParams, CodeActionProviderCapability, DidChangeTextDocumentParams, DidSaveTextDocumentParams, DocumentSelector, HoverProviderCapability, ImplementationProviderCapability, InitializeResult, LogMessageParams, MessageType, OneOf, ProgressParams, PublishDiagnosticsParams, Range, @@ -1139,6 +1139,11 @@ impl PluginHostHandler { ), ); } + Cancel::METHOD => { + let params: CancelParams = + serde_json::from_value(serde_json::to_value(params)?)?; + self.catalog_rpc.core_rpc.cancel(params); + } "experimental/serverStatus" => { let param: ServerStatusParams = serde_json::from_value(serde_json::to_value(params)?)?; diff --git a/lapce-rpc/src/core.rs b/lapce-rpc/src/core.rs index 8c8f206f50..7710c8df75 100644 --- a/lapce-rpc/src/core.rs +++ b/lapce-rpc/src/core.rs @@ -9,8 +9,8 @@ use std::{ use crossbeam_channel::{Receiver, Sender}; use lsp_types::{ - CompletionResponse, LogMessageParams, ProgressParams, PublishDiagnosticsParams, - ShowMessageParams, SignatureHelp, + CancelParams, CompletionResponse, LogMessageParams, ProgressParams, + PublishDiagnosticsParams, ShowMessageParams, SignatureHelp, }; use parking_lot::Mutex; use serde::{Deserialize, Serialize}; @@ -76,6 +76,9 @@ pub enum CoreNotification { message: LogMessageParams, target: String, }, + LspCancel { + params: CancelParams, + }, HomeDir { path: PathBuf, }, @@ -331,6 +334,10 @@ impl CoreRpcHandler { self.notification(CoreNotification::LogMessage { message, target }); } + pub fn cancel(&self, params: CancelParams) { + self.notification(CoreNotification::LspCancel { params }); + } + pub fn terminal_process_id(&self, term_id: TermId, process_id: Option) { self.notification(CoreNotification::TerminalProcessId { term_id, diff --git a/lapce-rpc/src/proxy.rs b/lapce-rpc/src/proxy.rs index 237d640ee4..0b756daab7 100644 --- a/lapce-rpc/src/proxy.rs +++ b/lapce-rpc/src/proxy.rs @@ -289,6 +289,9 @@ pub enum ProxyNotification { }, GitDiscardWorkspaceChanges {}, GitInit {}, + LspCancel { + id: i32, + }, TerminalWrite { term_id: TermId, content: String, @@ -583,6 +586,10 @@ impl ProxyRpcHandler { } } + pub fn lsp_cancel(&self, id: i32) { + self.notification(ProxyNotification::LspCancel { id }); + } + pub fn git_init(&self) { self.notification(ProxyNotification::GitInit {}); }