Print nicer "defined in" for functions defined on stdin/via source

This would tell you a function was "Defined in - @ line 1" for every
function defined via `source`.

Really, ideally we'd figure out where the *source* call was, but that'
much more complicated, so we just give a comprehensible message.
This commit is contained in:
Fabian Homborg 2020-12-11 23:05:22 +01:00
parent 952f1971ad
commit b7f47344b0
5 changed files with 38 additions and 15 deletions

View file

@ -152,16 +152,23 @@ static int report_function_metadata(const wchar_t *funcname, bool verbose, io_st
}
if (metadata_as_comments) {
if (std::wcscmp(path, L"stdin") != 0) {
wcstring comment;
// "stdin" means it was defined interactively, "-" means it was defined via `source`.
// Neither is useful information.
wcstring comment;
if (!std::wcscmp(path, L"stdin")) {
append_format(comment, L"# Defined interactively\n");
} else if (!std::wcscmp(path, L"-")) {
append_format(comment, L"# Defined via `source`\n");
} else {
append_format(comment, L"# Defined in %ls @ line %d\n", path, line_number);
if (!streams.out_is_redirected && isatty(STDOUT_FILENO)) {
std::vector<highlight_spec_t> colors;
highlight_shell(comment, colors, parser.context());
streams.out.append(str2wcstring(colorize(comment, colors, parser.vars())));
} else {
streams.out.append(comment);
}
}
if (!streams.out_is_redirected && isatty(STDOUT_FILENO)) {
std::vector<highlight_spec_t> colors;
highlight_shell(comment, colors, parser.context());
streams.out.append(str2wcstring(colorize(comment, colors, parser.vars())));
} else {
streams.out.append(comment);
}
} else {
streams.out.append_format(L"%ls\n", path);

View file

@ -147,7 +147,15 @@ maybe_t<int> builtin_type(parser_t &parser, io_streams_t &streams, wchar_t **arg
if (path) {
int line_number = function_get_definition_lineno(name);
wcstring comment;
append_format(comment, L"# Defined in %ls @ line %d\n", path, line_number);
if (std::wcscmp(path, L"-") != 0) {
append_format(comment, L"# Defined in %ls @ line %d\n", path, line_number);
} else {
append_format(comment, L"# Defined via `source`\n");
}
def = comment.append(def);
} else {
wcstring comment;
append_format(comment, L"# Defined interactively");
def = comment.append(def);
}
if (!streams.out_is_redirected && isatty(STDOUT_FILENO)) {

View file

@ -27,7 +27,7 @@ alias l. "ls -d .*"
alias d "'/mnt/c/Program Files (x86)/devenv.exe' /Edit"
functions d
# CHECK: # Defined in - @ line 1
# CHECK: # Defined via `source`
# CHECK: function d --wraps=\'/mnt/c/Program\ Files\ \(x86\)/devenv.exe\'\ /Edit --description alias\ d\ \'/mnt/c/Program\ Files\ \(x86\)/devenv.exe\'\ /Edit
# CHECK: '/mnt/c/Program Files (x86)/devenv.exe' /Edit $argv;
# CHECK: end
@ -35,7 +35,7 @@ functions d
# Use "command" to prevent recusion, and don't add --wraps to avoid accidental recursion in completion.
alias e 'e --option=value'
functions e
# CHECK: # Defined in - @ line 1
# CHECK: # Defined via `source`
# CHECK: function e --description 'alias e e --option=value'
# CHECK: command e --option=value $argv;
# CHECK: end
@ -43,7 +43,7 @@ functions e
# Don't add --wraps if it looks like a wrapper command to avoid accidental recursion in completion.
alias f 'wrapper around f'
functions f
# CHECK: # Defined in - @ line 1
# CHECK: # Defined via `source`
# CHECK: function f --description 'alias f wrapper around f'
# CHECK: wrapper around f $argv;
# CHECK: end

View file

@ -100,9 +100,9 @@ set -l name1a (functions name1a)
set -l name3 (functions name3)
set -l name3a (functions name3a)
# First line for the non-copied function is "# Defined in checks/function.fish" - skip it to work around #6575.
test "$name1[3..-1]" = "$name1a[2..-1]"; and echo "1 = 1a"
test "$name1[3..-1]" = "$name1a[3..-1]"; and echo "1 = 1a"
#CHECK: 1 = 1a
test "$name3[3..-1]" = "$name3a[2..-1]"; and echo "3 = 3a"
test "$name3[3..-1]" = "$name3a[3..-1]"; and echo "3 = 3a"
#CHECK: 3 = 3a
function test

View file

@ -91,3 +91,11 @@ functions f1 test_func_desc
functions --erase ls
type -t ls
#CHECK: file
echo "function t; echo tttt; end" | source
functions t
# CHECK: # Defined via `source`
# CHECK: function t
# CHECK: echo tttt;
# CHECK: end