Add status list-files

This allows us to implement fish_config using embedded files
This commit is contained in:
Fabian Boehm
2025-02-19 16:51:21 +01:00
parent ca3a7f8356
commit b56b876a98
4 changed files with 98 additions and 17 deletions

View File

@@ -70,7 +70,7 @@ function __fish_complete_man
# Fish commands are not given by apropos
if not set -ql exclude_fish_commands
set -l files $__fish_data_dir/man/man1/*.1
string replace -r '.*/([^/]+)\.1$' '$1\t1: fish command' -- $files
string replace -r '.*/([^/]+)\.1$' '$1\t1: fish command' -- $files (status list-files man/man1/ 2>/dev/null)
end
else
return 1

View File

@@ -6,4 +6,8 @@ function __fish_print_commands --description "Print a list of documented fish co
string match -rv '^fish-(?:changelog|completions|doc|tutorial|faq|for-bash-users|interactive|language|releasenotes|terminal-compatibility)$'
end
end
status list-files man/man1/ 2>/dev/null |
string replace -r '.*/' '' -- $file |
string replace -r '.1(.gz)?$' '' |
string match -rv '^fish-(?:changelog|completions|doc|tutorial|faq|for-bash-users|interactive|language|releasenotes)$'
end

View File

@@ -66,14 +66,19 @@ function fish_config --description "Launch fish's web based configuration"
case show
set -l fish (status fish-path)
set -l prompts $prompt_dir/$argv.fish
set -q prompts[1]; or set prompts $prompt_dir/*.fish
set -q prompts[1]; or set prompts $prompt_dir/*.fish (status list-files tools/web_config/sample_prompts/ 2>/dev/null)
for p in $prompts
if not test -e "$p"
continue
end
set -l promptname (string replace -r '.*/([^/]*).fish$' '$1' $p)
echo -s (set_color --underline) $promptname (set_color normal)
$fish -c 'functions -e fish_right_prompt; source $argv[1];
$fish -c 'functions -e fish_right_prompt;
if string match -q "tools/*" -- $argv[1]
status get-file $argv[1] | source
else
source $argv[1]
end
false
fish_prompt
echo (set_color normal)
@@ -83,7 +88,7 @@ function fish_config --description "Launch fish's web based configuration"
echo
end
case list ''
string replace -r '.*/([^/]*).fish$' '$1' $prompt_dir/*.fish
files=$prompt_dir/*.theme string replace -r '.*/([^/]*).fish$' '$1' $files (status list-files tools/web_config/sample_prompts/)
return
case choose
if set -q argv[2]
@@ -104,8 +109,16 @@ function fish_config --description "Launch fish's web based configuration"
end
end
if not set -q have[1]
echo "No such prompt: '$argv[1]'" >&2
return 1
if status list-files tools/web_config/sample_prompts/$argv[1].fish >/dev/null
status get-file tools/web_config/sample_prompts/$argv[1].fish | source
# HACK: `source` gives us a filename of "-", so we check manually if we had a right prompt
set have ""
status get-file tools/web_config/sample_prompts/$argv[1].fish | string match -q '*function fish_right_prompt*'
and set have -
else
echo "No such prompt: '$argv[1]'" >&2
return 1
end
end
# Erase the right prompt if it didn't have any.
@@ -139,8 +152,12 @@ function fish_config --description "Launch fish's web based configuration"
end
end
if not set -q have[1]
echo "No such prompt: '$argv[1]'" >&2
return 1
if status list-files tools/web_config/sample_prompts/$argv[1].fish >/dev/null
status get-file tools/web_config/sample_prompts/$argv[1].fish | source
else
echo "No such prompt: '$argv[1]'" >&2
return 1
end
end
end
@@ -170,7 +187,7 @@ function fish_config --description "Launch fish's web based configuration"
switch $cmd
case list ''
string replace -r '.*/([^/]*).theme$' '$1' $dirs/*.theme
files=$dirs/*.theme string replace -r '.*/([^/]*).theme$' '$1' $files (status list-files tools/web_config/themes/)
return
case demo
echo -ns (set_color $fish_color_command || set_color $fish_color_normal) /bright/vixens
@@ -198,8 +215,8 @@ function fish_config --description "Launch fish's web based configuration"
echo
case show
set -l fish (status fish-path)
set -l themes $dirs/$argv.theme
set -q themes[1]; or set themes $dirs/*.theme
set -l themes $dirs/$argv.theme (status list-files tools/web_config/themes/ | string match -- "*/"$argv.theme)
set -q themes[1]; or set themes $dirs/*.theme (status list-files tools/web_config/themes/)
set -l used_themes
echo -s (set_color normal; set_color --underline) Current (set_color normal)
@@ -268,12 +285,23 @@ function fish_config --description "Launch fish's web based configuration"
end
if not set -q file[1]
echo "No such theme: $argv[1]" >&2
echo "Searched directories: $dirs" >&2
return 1
if status list-files tools/web_config/themes/$argv[1].theme >/dev/null
set file tools/web_config/themes/$argv[1].theme
else
echo "No such theme: $argv[1]" >&2
echo "Searched directories: $dirs" >&2
return 1
end
end
while read -lat toks
set -l content
if string match -qr '^tools/' -- $file
set content (status get-file $file)
else
read -az content < $file
end
printf %s\n $content | while read -lat toks
# The whitelist allows only color variables.
# Not the specific list, but something named *like* a color variable.
# This also takes care of empty lines and comment lines.
@@ -287,7 +315,7 @@ function fish_config --description "Launch fish's web based configuration"
end
set $scope $toks
set -a have_colors $toks[1]
end <$file
end
# Set all colors that aren't mentioned to empty
for c in $known_colors

View File

@@ -61,6 +61,7 @@ enum StatusCmd {
STATUS_CURRENT_COMMANDLINE,
STATUS_BUILDINFO,
STATUS_GET_FILE,
STATUS_LIST_FILES,
}
str_enum!(
@@ -80,6 +81,7 @@ enum StatusCmd {
(STATUS_FISH_PATH, "fish-path"),
(STATUS_FUNCTION, "function"),
(STATUS_GET_FILE, "get-file"),
(STATUS_LIST_FILES, "list-files"),
(STATUS_IS_BLOCK, "is-block"),
(STATUS_IS_BREAKPOINT, "is-breakpoint"),
(STATUS_IS_COMMAND_SUB, "is-command-substitution"),
@@ -479,6 +481,52 @@ pub fn status(parser: &Parser, streams: &mut IoStreams, args: &mut [&wstr]) -> B
return Err(STATUS_CMD_ERROR);
}
}
c @ STATUS_LIST_FILES => {
if args.len() > 1 {
streams.err.append(wgettext_fmt!(
BUILTIN_ERR_ARG_COUNT2,
cmd,
c.to_wstr(),
1,
args.len()
));
return Err(STATUS_INVALID_ARGS);
}
#[cfg(feature = "installable")]
{
let mut have_file = false;
let arg = crate::common::wcs2string(args.get(0).unwrap_or(&L!("")));
let arg = std::str::from_utf8(&arg).unwrap();
for file in crate::autoload::Asset::iter() {
if arg.is_empty() || file.starts_with(arg) {
have_file = true;
let src = str2wcstring(file.as_bytes());
streams.out.appendln(src);
}
}
for file in Docs::iter() {
if arg.is_empty() || file.starts_with(arg) {
have_file = true;
let src = str2wcstring(file.as_bytes());
streams.out.appendln(src);
}
}
if have_file {
return Ok(SUCCESS);
} else {
return Err(STATUS_CMD_ERROR);
}
}
#[cfg(not(feature = "installable"))]
{
streams.err.append(wgettext_fmt!(
"%ls: fish was not built with embedded files",
cmd,
));
return Err(STATUS_CMD_ERROR);
}
}
ref s => {
if !args.is_empty() {
streams.err.append(wgettext_fmt!(
@@ -665,7 +713,8 @@ pub fn status(parser: &Parser, streams: &mut IoStreams, args: &mut [&wstr]) -> B
STATUS_SET_JOB_CONTROL
| STATUS_FEATURES
| STATUS_TEST_FEATURE
| STATUS_GET_FILE => {
| STATUS_GET_FILE
| STATUS_LIST_FILES => {
unreachable!("")
}
}