diff --git a/doc_src/functions.txt b/doc_src/functions.txt index 05c8b6028..9aae7e069 100644 --- a/doc_src/functions.txt +++ b/doc_src/functions.txt @@ -23,14 +23,15 @@ The following options are available: - `-e` or `--erase` causes the specified functions to be erased. -- `-m` or `--metadata` reports the path name where each function is defined or could be autoloaded, `stdin` if the function was defined interactively or on the command line or by reading stdin, and `n/a` if the function isn't available. If the `--verbose` option is also specified then four lines are written: +- `-m` or `--metadata` reports the path name where each function is defined or could be autoloaded, `stdin` if the function was defined interactively or on the command line or by reading stdin, and `n/a` if the function isn't available. If the `--verbose` option is also specified then five lines are written: -# the pathname as already described, -# `autoloaded`, `not-autoloaded` or `n/a`, -# the line number within the file or zero if not applicable, - -# `scope-shadowing` if the function shadows the vars in the calling function (the normal case) else `no-scope-shadowing`, or `n/a` if the function isn't defined. + -# `scope-shadowing` if the function shadows the vars in the calling function (the normal case if it wasn't defined with `--no-scope-shadowing`), else `no-scope-shadowing`, or `n/a` if the function isn't defined, + -# the function description minimally escaped so it is a single line or `n/a` if the function isn't defined. -You should not assume that only four lines will be written since we may add additional information to the output in the future. +You should not assume that only five lines will be written since we may add additional information to the output in the future. - `-n` or `--names` lists the names of all defined functions. diff --git a/src/builtin.cpp b/src/builtin.cpp index 6ee4ec986..5ee57a475 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -1042,6 +1042,7 @@ static int report_function_metadata(const wchar_t *funcname, bool verbose, io_st const wchar_t *path = L"n/a"; const wchar_t *autoloaded = L"n/a"; const wchar_t *shadows_scope = L"n/a"; + wcstring description = L"n/a"; int line_number = 0; if (function_exists(funcname)) { @@ -1054,6 +1055,8 @@ static int report_function_metadata(const wchar_t *funcname, bool verbose, io_st } shadows_scope = function_get_shadow_scope(funcname) ? L"scope-shadowing" : L"no-scope-shadowing"; + function_get_desc(funcname, &description); + description = escape_string(description, ESCAPE_NO_QUOTED); } if (metadata_as_comments) { @@ -1066,6 +1069,7 @@ static int report_function_metadata(const wchar_t *funcname, bool verbose, io_st streams.out.append_format(L"%ls\n", autoloaded); streams.out.append_format(L"%d\n", line_number); streams.out.append_format(L"%ls\n", shadows_scope); + streams.out.append_format(L"%ls\n", description.c_str()); } } diff --git a/tests/functions.in b/tests/functions.in index c51981db5..dbe934eba 100644 --- a/tests/functions.in +++ b/tests/functions.in @@ -41,10 +41,22 @@ end # Verify that `functions --verbose --metadata` works as expected when given the name of a # function that was autoloaded. set x (functions -v -m abbr) -if test (count $x) -ne 4 +if test (count $x) -ne 5 or not string match -q '*/share/functions/abbr.fish' $x[1] or test $x[2] != autoloaded or test $x[3] != 1 or test $x[4] != scope-shadowing +or test $x[5] != 'Manage abbreviations' echo "Unexpected output for 'functions -v -m abbr': $x" >&2 end + +# ========== +# Verify that `functions --verbose --metadata` properly escapes a function +# with a multiline description. +function multiline_descr -d 'line 1\n +line 2 & more; way more' +end +set x (functions -v -m multiline_descr) +if test $x[5] != 'line 1\\\\n\\nline 2 & more; way more' + echo "Unexpected output for 'functions -v -m multiline_descr': $x" >&2 +end