From 44184f68e441aea2d4bac322a5fb2a62e40bed3f Mon Sep 17 00:00:00 2001 From: Fabian Homborg Date: Mon, 1 Jun 2020 16:46:20 +0200 Subject: [PATCH] Add `status dirname` and `status basename` convenience commands There's a terrible number of fishscripts that start with set path (dirname (status filename)) And that's really just a bit boring. So let's let it be set path (status dirname) --- doc_src/cmds/status.rst | 8 +++++++- src/builtin_status.cpp | 22 ++++++++++++++++++---- tests/checks/status-command.fish | 15 +++++++++++++++ 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/doc_src/cmds/status.rst b/doc_src/cmds/status.rst index bed320da0..67738e836 100644 --- a/doc_src/cmds/status.rst +++ b/doc_src/cmds/status.rst @@ -19,6 +19,8 @@ Synopsis status is-interactive-job-control status current-command status filename + status basename + status dirname status fish-path status function status line-number @@ -52,7 +54,11 @@ The following operations (sub-commands) are available: - ``current-command`` prints the name of the currently-running function or command, like the deprecated ``_`` variable. -- ``filename`` prints the filename of the currently running script. Also ``current-filename``, ``-f`` or ``--current-filename``. +- ``filename`` prints the filename of the currently running script. Also ``current-filename``, ``-f`` or ``--current-filename``. This depends on how the script was called - if it was called via a symlink, the symlink will be returned, and if the current script was received via ``source`` it will be ``-``. + +- ``basename`` prints just the filename of the running script, without any path-components before. + +- ``dirname`` prints just the path to the running script, without the actual filename itself. This can be relative to $PWD (including just "."), depending on how the script was called. This is the same as passing the ``filename`` to ``dirname(3)``. It's useful if you want to use other files in the current script's directory or similar. - ``fish-path`` prints the absolute path to the currently executing instance of fish. diff --git a/src/builtin_status.cpp b/src/builtin_status.cpp index 47e567789..8b2cee5e3 100644 --- a/src/builtin_status.cpp +++ b/src/builtin_status.cpp @@ -19,6 +19,8 @@ enum status_cmd_t { STATUS_CURRENT_CMD = 1, + STATUS_BASENAME, + STATUS_DIRNAME, STATUS_FEATURES, STATUS_FILENAME, STATUS_FISH_PATH, @@ -40,10 +42,14 @@ enum status_cmd_t { // Must be sorted by string, not enum or random. const enum_map status_enum_map[] = { + {STATUS_BASENAME, L"basename"}, + {STATUS_BASENAME, L"current-basename"}, {STATUS_CURRENT_CMD, L"current-command"}, + {STATUS_DIRNAME, L"current-dirname"}, {STATUS_FILENAME, L"current-filename"}, {STATUS_FUNCTION, L"current-function"}, {STATUS_LINE_NUMBER, L"current-line-number"}, + {STATUS_DIRNAME, L"dirname"}, {STATUS_FEATURES, L"features"}, {STATUS_FILENAME, L"filename"}, {STATUS_FISH_PATH, L"fish-path"}, @@ -357,12 +363,20 @@ int builtin_status(parser_t &parser, io_streams_t &streams, wchar_t **argv) { } break; } + case STATUS_BASENAME: + case STATUS_DIRNAME: case STATUS_FILENAME: { CHECK_FOR_UNEXPECTED_STATUS_ARGS(opts.status_cmd) - const wchar_t *fn = parser.current_filename(); - - if (!fn) fn = _(L"Standard input"); - streams.out.append_format(L"%ls\n", fn); + auto res = parser.current_filename(); + wcstring fn = res ? res : L""; + if (!fn.empty() && opts.status_cmd == STATUS_DIRNAME) { + fn = wdirname(fn); + } else if (!fn.empty() && opts.status_cmd == STATUS_BASENAME) { + fn = wbasename(fn); + } else if (fn.empty()) { + fn = _(L"Standard input"); + } + streams.out.append_format(L"%ls\n", fn.c_str()); break; } case STATUS_FUNCTION: { diff --git a/tests/checks/status-command.fish b/tests/checks/status-command.fish index fdd0c2d5f..8ed55f7a9 100644 --- a/tests/checks/status-command.fish +++ b/tests/checks/status-command.fish @@ -36,3 +36,18 @@ echo $status echo (status is-command-substitution; echo $status) # CHECK: 1 # CHECK: 0 + +test (status filename) = (status dirname)/(status basename) + +status basename +#CHECK: status-command.fish + +status dirname | string match -q '*checks' +echo $status +#CHECK: 0 + +echo "status dirname" | source +#CHECK: . + +$FISH_PATH -c 'status dirname' +#CHECK: Standard input