Improve editor open URL command to open the selected portion of URL (#21825)

Closes #21718

Just like in Vim, if a URL is selected, it opens exactly that portion of
the URL. Otherwise, if only the cursor is on a URL, it opens the entire
URL.

Zed currently does the latter. This PR also adds support for the former.


https://github.com/user-attachments/assets/8bdd2952-ceec-487c-b27a-5cea4258eb03

Release Notes:

- Updated the `editor: open url` to also handle the selected portion of
a URL.
This commit is contained in:
tims 2024-12-13 11:45:21 +05:30 committed by GitHub
parent 096bbfead5
commit 5318f529de
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 86 additions and 8 deletions

View file

@ -176,7 +176,7 @@ use workspace::{
};
use workspace::{Item as WorkspaceItem, OpenInTerminal, OpenTerminal, TabBarSettings, Toast};
use crate::hover_links::find_url;
use crate::hover_links::{find_url, find_url_from_range};
use crate::signature_help::{SignatureHelpHiddenBy, SignatureHelpState};
pub const FILE_HEADER_HEIGHT: u32 = 2;
@ -9293,23 +9293,42 @@ impl Editor {
}
pub fn open_url(&mut self, _: &OpenUrl, cx: &mut ViewContext<Self>) {
let position = self.selections.newest_anchor().head();
let Some((buffer, buffer_position)) =
self.buffer.read(cx).text_anchor_for_position(position, cx)
let selection = self.selections.newest_anchor();
let head = selection.head();
let tail = selection.tail();
let Some((buffer, start_position)) =
self.buffer.read(cx).text_anchor_for_position(head, cx)
else {
return;
};
cx.spawn(|editor, mut cx| async move {
if let Some((_, url)) = find_url(&buffer, buffer_position, cx.clone()) {
let end_position = if head != tail {
let Some((_, pos)) = self.buffer.read(cx).text_anchor_for_position(tail, cx) else {
return;
};
Some(pos)
} else {
None
};
let url_finder = cx.spawn(|editor, mut cx| async move {
let url = if let Some(end_pos) = end_position {
find_url_from_range(&buffer, start_position..end_pos, cx.clone())
} else {
find_url(&buffer, start_position, cx.clone()).map(|(_, url)| url)
};
if let Some(url) = url {
editor.update(&mut cx, |_, cx| {
cx.open_url(&url);
})
} else {
Ok(())
}
})
.detach();
});
url_finder.detach();
}
pub fn open_file(&mut self, _: &OpenFile, cx: &mut ViewContext<Self>) {