From 251218954de96d718935f2d12286ecb5e173f165 Mon Sep 17 00:00:00 2001 From: Thorsten Ball Date: Sun, 18 Feb 2024 18:52:50 +0100 Subject: [PATCH] Add editor::OpenUrl action and bind to `gx` in Vim mode (#7972) This adds one feature I've been missing a lot in Vim mode: `gx` to open the URL under the cursor. Technically, in Vim, `gx` opens more "paths", not just URLs, but I think this is a good start. Release Notes: - Added `gx` to Vim mode to open the URL under the cursor. Demo: https://github.com/zed-industries/zed/assets/1185253/6a19490d-b61d-40b7-93e8-4819599f6977 --- assets/keymaps/vim.json | 1 + crates/editor/src/actions.rs | 1 + crates/editor/src/editor.rs | 24 ++++++++++++++++++++++++ crates/editor/src/element.rs | 1 + crates/editor/src/hover_links.rs | 2 +- 5 files changed, 28 insertions(+), 1 deletion(-) diff --git a/assets/keymaps/vim.json b/assets/keymaps/vim.json index 14fd118771..2af71b607f 100644 --- a/assets/keymaps/vim.json +++ b/assets/keymaps/vim.json @@ -125,6 +125,7 @@ "g shift-t": "pane::ActivatePrevItem", "g d": "editor::GoToDefinition", "g shift-d": "editor::GoToTypeDefinition", + "g x": "editor::OpenUrl", "g n": "vim::SelectNext", "g shift-n": "vim::SelectPrevious", "g >": [ diff --git a/crates/editor/src/actions.rs b/crates/editor/src/actions.rs index 3c4104570a..e6c4d36984 100644 --- a/crates/editor/src/actions.rs +++ b/crates/editor/src/actions.rs @@ -165,6 +165,7 @@ gpui::actions!( GoToPrevHunk, GoToTypeDefinition, GoToTypeDefinitionSplit, + OpenUrl, HalfPageDown, HalfPageUp, Hover, diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 039d47460d..f6fc5b4de0 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -123,6 +123,8 @@ use util::{maybe, post_inc, RangeExt, ResultExt, TryFutureExt}; use workspace::Toast; use workspace::{searchable::SearchEvent, ItemNavHistory, Pane, SplitDirection, ViewId, Workspace}; +use crate::hover_links::find_url; + const CURSOR_BLINK_INTERVAL: Duration = Duration::from_millis(500); const MAX_LINE_LEN: usize = 1024; const MIN_NAVIGATION_HISTORY_ROW_DELTA: i64 = 10; @@ -7368,6 +7370,28 @@ impl Editor { .detach_and_log_err(cx); } + pub fn open_url(&mut self, _: &OpenUrl, cx: &mut ViewContext) { + let position = self.selections.newest_anchor().head(); + let Some((buffer, buffer_position)) = self + .buffer + .read(cx) + .text_anchor_for_position(position.clone(), cx) + else { + return; + }; + + cx.spawn(|editor, mut cx| async move { + if let Some((_, url)) = find_url(&buffer, buffer_position, cx.clone()) { + editor.update(&mut cx, |_, cx| { + cx.open_url(&url); + }) + } else { + Ok(()) + } + }) + .detach(); + } + pub fn navigate_to_hover_links( &mut self, mut definitions: Vec, diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index db9441a577..4431d2315e 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -262,6 +262,7 @@ impl EditorElement { register_action(view, cx, Editor::go_to_definition_split); register_action(view, cx, Editor::go_to_type_definition); register_action(view, cx, Editor::go_to_type_definition_split); + register_action(view, cx, Editor::open_url); register_action(view, cx, Editor::fold); register_action(view, cx, Editor::fold_at); register_action(view, cx, Editor::unfold_lines); diff --git a/crates/editor/src/hover_links.rs b/crates/editor/src/hover_links.rs index 5834ae5a2b..5baf6e9e96 100644 --- a/crates/editor/src/hover_links.rs +++ b/crates/editor/src/hover_links.rs @@ -569,7 +569,7 @@ pub fn show_link_definition( editor.hovered_link_state = Some(hovered_link_state); } -fn find_url( +pub(crate) fn find_url( buffer: &Model, position: text::Anchor, mut cx: AsyncWindowContext,