Add status get-file

This allows getting embedded files, so we can use them in functions
This commit is contained in:
Fabian Boehm
2025-02-19 16:35:37 +01:00
parent c8719fbff5
commit ca3a7f8356
4 changed files with 78 additions and 9 deletions

View File

@@ -11,7 +11,7 @@ function __fish_print_help --description "Print help message for the specified f
end
# Do nothing if the file does not exist
if not test -e "$__fish_data_dir/man/man1/$item.1" -o -e "$__fish_data_dir/man/man1/$item.1.gz"
if not test -e "$__fish_data_dir/man/man1/$item.1" -o -e "$__fish_data_dir/man/man1/$item.1.gz"; and not status get-file man/man1/$item.1 >/dev/null
return 2
end
@@ -58,6 +58,8 @@ function __fish_print_help --description "Print help message for the specified f
else
set help (gunzip -c "$__fish_data_dir/man/man1/$item.1.gz" 2>/dev/null | $format 2>/dev/null)
end
else
set help (status get-file man/man1/$item.1 | $format 2>/dev/null)
end
# The original implementation trimmed off the top 5 lines and bottom 3 lines

View File

@@ -24,7 +24,7 @@ function fish_delta
test "$vendormode" = default && set -a default_function_path $__fish_vendor_functionsdirs
set -l default_complete_path $__fish_data_dir/completions
test "$vendormode" = default && set -a default_completions_path $__fish_vendor_completionsdirs
test "$vendormode" = default && set -a default_complete_path $__fish_vendor_completionsdirs
set -l default_conf_path
test "$vendormode" = default && set -a default_conf_path $__fish_vendor_confdirs
@@ -96,6 +96,11 @@ function fish_delta
# because they are being run.
test "$vars[1]" = user_conf_path
and set all_changed 1
set -l dir
test "$vars[2]" = default_complete_path
and set dir completions
test "$vars[2]" = default_function_path
and set dir functions
set -e vars[..2]
set -l files (path filter -rf -- $user_var/$argv.fish)
set -q argv[1]
@@ -106,6 +111,7 @@ function fish_delta
for file in $files
set -l bn (path basename -- $file)
set -l def (path filter -rf -- $default_var/$bn)[1]
or set -l def (set -q dir[1] && status get-file $dir/$bn >/dev/null && echo embedded)
or begin
if test $all_changed = 0
set -ql _flag_n
@@ -120,13 +126,22 @@ function fish_delta
# We execute diff twice - once to figure out if it's changed,
# so we can get nicer output.
#
if not diff -q -- $file $def >/dev/null 2>&1
printf (_ "%sChanged%s: %s\n") $colors[3] $colors[1] $file
not set -ql _flag_d[1]
and diff -u -- $def $file
if test "$def" = embedded
if not status get-file $dir/$bn | diff -q -- $file - >/dev/null 2>&1
printf (_ "%sChanged%s: %s\n") $colors[3] $colors[1] $file
not set -ql _flag_d[1]
and status get-file $dir/$bn | diff -u -- - $file
continue
end
else
printf (_ "%sUnmodified%s: %s\n") $colors[4] $colors[1] $file
if not diff -q -- $file $def >/dev/null 2>&1
printf (_ "%sChanged%s: %s\n") $colors[3] $colors[1] $file
not set -ql _flag_d[1]
and diff -u -- $def $file
continue
end
end
printf (_ "%sUnmodified%s: %s\n") $colors[4] $colors[1] $file
else
# Without diff, we can't really tell if the contents are the same.
printf (_ "%sPossibly changed%s: %s\n") $colors[3] $colors[1] $file

View File

@@ -71,10 +71,12 @@ function funced --description 'Edit function definition'
if not functions -q -- $funcname
echo $init >$tmpname
else if functions --details -- $funcname | string match --invert --quiet --regex '^(?:-|stdin)$'
else if functions --details -- $funcname | string match --invert --quiet --regex '^(?:-|stdin|embedded:.*)$'
set writepath (functions --details -- $funcname)
# Use cat here rather than cp to avoid copying permissions
cat "$writepath" >$tmpname
else if set -l path (functions --details -- $funcname | string match -rg '^embedded:(.*)$')
status get-file $path >$tmpname
else
functions -- $funcname >$tmpname
end

View File

@@ -60,6 +60,7 @@ enum StatusCmd {
STATUS_TEST_FEATURE,
STATUS_CURRENT_COMMANDLINE,
STATUS_BUILDINFO,
STATUS_GET_FILE,
}
str_enum!(
@@ -78,6 +79,7 @@ enum StatusCmd {
(STATUS_FILENAME, "filename"),
(STATUS_FISH_PATH, "fish-path"),
(STATUS_FUNCTION, "function"),
(STATUS_GET_FILE, "get-file"),
(STATUS_IS_BLOCK, "is-block"),
(STATUS_IS_BREAKPOINT, "is-breakpoint"),
(STATUS_IS_COMMAND_SUB, "is-command-substitution"),
@@ -313,6 +315,15 @@ fn parse_cmd_opts(
return Ok(SUCCESS);
}
#[cfg(feature = "installable")]
use rust_embed::RustEmbed;
#[cfg(feature = "installable")]
#[derive(RustEmbed)]
#[folder = "target/man/man1"]
#[prefix = "man/man1/"]
struct Docs;
pub fn status(parser: &Parser, streams: &mut IoStreams, args: &mut [&wstr]) -> BuiltinResult {
let cmd = args[0];
let argc = args.len();
@@ -432,6 +443,42 @@ pub fn status(parser: &Parser, streams: &mut IoStreams, args: &mut [&wstr]) -> B
}
return Err(retval as i32);
}
c @ STATUS_GET_FILE => {
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 arg = crate::common::wcs2string(args[0]);
let arg = std::str::from_utf8(&arg).unwrap();
if let Some(emfile) = crate::autoload::Asset::get(arg) {
let src = str2wcstring(&emfile.data);
streams.out.append(src);
return Ok(SUCCESS);
} else if let Some(emfile) = Docs::get(arg) {
let src = str2wcstring(&emfile.data);
streams.out.append(src);
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!(
@@ -615,7 +662,10 @@ pub fn status(parser: &Parser, streams: &mut IoStreams, args: &mut [&wstr]) -> B
streams.out.appendln(path);
}
}
STATUS_SET_JOB_CONTROL | STATUS_FEATURES | STATUS_TEST_FEATURE => {
STATUS_SET_JOB_CONTROL
| STATUS_FEATURES
| STATUS_TEST_FEATURE
| STATUS_GET_FILE => {
unreachable!("")
}
}