diff --git a/doc_src/cmds/path.rst b/doc_src/cmds/path.rst index a940bcc99..694daf3df 100644 --- a/doc_src/cmds/path.rst +++ b/doc_src/cmds/path.rst @@ -109,9 +109,9 @@ Examples path extension [(-z | --null-in)] [(-Z | --null-out)] [(-q | --quiet)] [PATH...] -``path extension`` returns the extension of the given path. This is the part after (and excluding) the last ".", unless that "." followed a "/" or the basename is "." or "..", in which case there is no extension and nothing is printed. +``path extension`` returns the extension of the given path. This is the part after (and including) the last ".", unless that "." followed a "/" or the basename is "." or "..", in which case there is no extension and an empty line is printed. -If the filename ends in a ".", the extension is empty, so an empty line will be printed. +If the filename ends in a ".", only a "." is printed. It returns 0 if there was an extension. @@ -121,19 +121,19 @@ Examples :: >_ path extension ./foo.mp4 - mp4 + .mp4 >_ path extension ../banana - # nothing, status 1 + # an empty line, status 1 >_ path extension ~/.config - # nothing, status 1 + # an empty line, status 1 >_ path extension ~/.config.d - d + .d >_ path extension ~/.config. - # one empty line, status 0 + . .. _cmd-path-filter: @@ -281,10 +281,12 @@ Examples path change-extension [(-z | --null-in)] [(-Z | --null-out)] \ [(-q | --quiet)] EXTENSION [PATH...] -``path change-extension`` returns the given paths, with their extension changed to the given new extension. The extension is the part after (and excluding) the last ".", unless that "." followed a "/" or the basename is "." or "..", in which case there is no previous extension and the new one is simply added. +``path change-extension`` returns the given paths, with their extension changed to the given new extension. The extension is the part after (and including) the last ".", unless that "." followed a "/" or the basename is "." or "..", in which case there is no previous extension and the new one is simply added. If the extension is empty, any previous extension is stripped, along with the ".". This is, of course, the inverse of ``path extension``. +One leading dot on the extension is ignored, so ".mp3" and "mp3" are treated the same. + It returns 0 if it was given any paths. Examples @@ -295,6 +297,9 @@ Examples >_ path change-extension mp4 ./foo.wmv ./foo.mp4 + >_ path change-extension .mp4 ./foo.wmv + ./foo.mp4 + >_ path change-extension '' ../banana ../banana # but status 1, because there was no extension. diff --git a/src/builtins/path.cpp b/src/builtins/path.cpp index 078c66f68..574f3fe54 100644 --- a/src/builtins/path.cpp +++ b/src/builtins/path.cpp @@ -580,7 +580,7 @@ static int path_extension(parser_t &parser, io_streams_t &streams, int argc, con if (!pos) continue; - wcstring ext = arg->substr(*pos + 1); + wcstring ext = arg->substr(*pos); if (opts.quiet && !ext.empty()) { return STATUS_CMD_OK; } @@ -612,7 +612,9 @@ static int path_change_extension(parser_t &parser, io_streams_t &streams, int ar // Only add on the extension "." if we have something. // That way specifying an empty extension strips it. if (*opts.arg1) { - ext.push_back(L'.'); + if (opts.arg1[0] != L'.') { + ext.push_back(L'.'); + } ext.append(opts.arg1); } path_out(streams, opts, ext); diff --git a/tests/checks/path.fish b/tests/checks/path.fish index e93a153f6..f53b6c191 100644 --- a/tests/checks/path.fish +++ b/tests/checks/path.fish @@ -21,7 +21,7 @@ or echo None once more # CHECK: None once more path extension /foo.txt and echo Success -# CHECK: txt +# CHECK: .txt # CHECK: Success path extension /foo.txt/bar or echo Not even here @@ -30,7 +30,7 @@ path extension . .. or echo No extension # CHECK: No extension path extension ./foo.mp4 -# CHECK: mp4 +# CHECK: .mp4 path extension ../banana # nothing, status 1 echo $status @@ -40,15 +40,19 @@ path extension ~/.config echo $status # CHECK: 1 path extension ~/.config.d -# CHECK: d +# CHECK: .d path extension ~/.config. echo $status -# one empty line, status 0 -# CHECK: +# status 0 +# CHECK: . # CHECK: 0 path change-extension '' ./foo.mp4 # CHECK: ./foo +path change-extension wmv ./foo.mp4 +# CHECK: ./foo.wmv +path change-extension .wmv ./foo.mp4 +# CHECK: ./foo.wmv path change-extension '' ../banana # CHECK: ../banana # still status 0, because there was an argument