1
0
mirror of https://github.com/BurntSushi/ripgrep.git synced 2025-11-23 21:54:45 +02:00

complete/zsh: improve --hyperlink-format completion

Also don't re-define helper functions if they exist.

Closes #3102
This commit is contained in:
dana
2025-07-13 01:50:38 -05:00
committed by Andrew Gallant
parent 519c1bd5cf
commit 78383de9b2
5 changed files with 121 additions and 16 deletions

View File

@@ -319,7 +319,7 @@ _rg() {
'--field-context-separator[set string to delimit fields in context lines]'
'--field-match-separator[set string to delimit fields in matching lines]'
'--hostname-bin=[executable for getting system hostname]:hostname executable:_command_names -e'
'--hyperlink-format=[specify pattern for hyperlinks]:pattern'
'--hyperlink-format=[specify pattern for hyperlinks]: :_rg_hyperlink_formats'
'--trace[show more verbose debug messages]'
'--dfa-size-limit=[specify upper size limit of generated DFA]:DFA size (bytes)'
"(1 stats)--files[show each file that would be searched (but don't search)]"
@@ -410,6 +410,7 @@ _rg() {
}
# Complete encodings
(( $+functions[_rg_encodings] )) ||
_rg_encodings() {
local -a expl
local -aU _encodings
@@ -422,6 +423,7 @@ _rg_encodings() {
}
# Complete file types
(( $+functions[_rg_types] )) ||
_rg_types() {
local -a expl
local -aU _types
@@ -435,6 +437,49 @@ _rg_types() {
fi
}
# Complete hyperlink format-string aliases
(( $+functions[_rg_hyperlink_format_aliases] )) ||
_rg_hyperlink_format_aliases() {
_describe -t format-aliases 'hyperlink format alias' '(
!HYPERLINK_ALIASES!
)'
}
# Complete custom hyperlink format strings
(( $+functions[_rg_hyperlink_format_strings] )) ||
_rg_hyperlink_format_strings() {
local op='{' ed='}'
local -a pfx sfx rmv
compquote op ed
sfx=( -S $ed )
rmv=( -r ${(q)ed[1]} )
compset -S "$op*"
compset -S "$ed*" && sfx=( -S '' )
compset -P "*$ed"
compset -p ${#PREFIX%$op*}
compset -P $op || pfx=( -P $op )
WSL_DISTRO_NAME=${WSL_DISTRO_NAME:-\$WSL_DISTRO_NAME} \
_describe -t format-variables 'hyperlink format variable' '(
path:"absolute path to file containing match (required)"
host:"system host name or output of --hostname-bin executable"
line:"line number of match"
column:"column of match (requires {line})"
wslprefix:"\"wsl$/$WSL_DISTRO_NAME\" (for WSL share)"
)' "${(@)pfx}" "${(@)sfx}" "${(@)rmv}"
}
# Complete hyperlink formats
(( $+functions[_rg_hyperlink_formats] )) ||
_rg_hyperlink_formats() {
_alternative \
'format-string-aliases: :_rg_hyperlink_format_aliases' \
'format-strings: :_rg_hyperlink_format_strings'
}
# Don't run the completion function when being sourced by itself.
#
# See https://github.com/BurntSushi/ripgrep/issues/2956

View File

@@ -19,5 +19,14 @@ long as it meets criteria 3 and 4 above.
/// Generate completions for zsh.
pub(crate) fn generate() -> String {
include_str!("rg.zsh").replace("!ENCODINGS!", super::ENCODINGS.trim_end())
let hyperlink_alias_descriptions = grep::printer::hyperlink_aliases()
.iter()
.map(|alias| {
format!(r#" {}:"{}""#, alias.name(), alias.description())
})
.collect::<Vec<String>>()
.join("\n");
include_str!("rg.zsh")
.replace("!ENCODINGS!", super::ENCODINGS.trim_end())
.replace("!HYPERLINK_ALIASES!", &hyperlink_alias_descriptions)
}

View File

@@ -4,41 +4,84 @@ use crate::hyperlink::HyperlinkAlias;
///
/// These need to be sorted by name.
pub(super) const HYPERLINK_PATTERN_ALIASES: &[HyperlinkAlias] = &[
#[cfg(not(windows))]
prioritized_alias(0, "default", "file://{host}{path}"),
#[cfg(windows)]
prioritized_alias(0, "default", "file://{path}"),
alias("file", "file://{host}{path}"),
prioritized_alias(
0,
"default",
"RFC 8089 scheme (file://) (platform-aware)",
{
#[cfg(not(windows))]
{
"file://{host}{path}"
}
#[cfg(windows)]
{
"file://{path}"
}
},
),
alias(
"file",
"RFC 8089 scheme (file://) with host",
"file://{host}{path}",
),
// https://github.com/misaki-web/grepp
alias("grep+", "grep+://{path}:{line}"),
alias("kitty", "file://{host}{path}#{line}"),
alias("grep+", "grep+ scheme (grep+://)", "grep+://{path}:{line}"),
alias(
"kitty",
"kitty-style RFC 8089 scheme (file://) with line number",
"file://{host}{path}#{line}",
),
// https://macvim.org/docs/gui_mac.txt.html#mvim%3A%2F%2F
alias(
"macvim",
"MacVim scheme (mvim://)",
"mvim://open?url=file://{path}&line={line}&column={column}",
),
prioritized_alias(1, "none", ""),
prioritized_alias(1, "none", "disable hyperlinks", ""),
// https://macromates.com/blog/2007/the-textmate-url-scheme/
alias(
"textmate",
"TextMate scheme (txmt://)",
"txmt://open?url=file://{path}&line={line}&column={column}",
),
// https://code.visualstudio.com/docs/editor/command-line#_opening-vs-code-with-urls
alias("vscode", "vscode://file{path}:{line}:{column}"),
alias("vscode-insiders", "vscode-insiders://file{path}:{line}:{column}"),
alias("vscodium", "vscodium://file{path}:{line}:{column}"),
alias(
"vscode",
"VS Code scheme (vscode://)",
"vscode://file{path}:{line}:{column}",
),
alias(
"vscode-insiders",
"VS Code Insiders scheme (vscode-insiders://)",
"vscode-insiders://file{path}:{line}:{column}",
),
alias(
"vscodium",
"VSCodium scheme (vscodium://)",
"vscodium://file{path}:{line}:{column}",
),
];
/// Creates a [`HyperlinkAlias`].
const fn alias(name: &'static str, format: &'static str) -> HyperlinkAlias {
HyperlinkAlias { name, format, display_priority: None }
const fn alias(
name: &'static str,
description: &'static str,
format: &'static str,
) -> HyperlinkAlias {
HyperlinkAlias { name, description, format, display_priority: None }
}
/// Creates a [`HyperlinkAlias`] with a display priority.
const fn prioritized_alias(
priority: i16,
name: &'static str,
description: &'static str,
format: &'static str,
) -> HyperlinkAlias {
HyperlinkAlias { name, format, display_priority: Some(priority) }
HyperlinkAlias {
name,
description,
format,
display_priority: Some(priority),
}
}

View File

@@ -190,6 +190,7 @@ impl std::fmt::Display for HyperlinkFormat {
#[derive(Clone, Debug)]
pub struct HyperlinkAlias {
name: &'static str,
description: &'static str,
format: &'static str,
display_priority: Option<i16>,
}
@@ -200,6 +201,11 @@ impl HyperlinkAlias {
self.name
}
/// Returns a very short description of this hyperlink alias.
pub const fn description(&self) -> &str {
self.description
}
/// Returns the display priority of this alias.
///
/// If no priority is set, then `None` is returned.