diff --git a/doc_src/cmds/commandline.rst b/doc_src/cmds/commandline.rst index 9a7577380..55ec37a33 100644 --- a/doc_src/cmds/commandline.rst +++ b/doc_src/cmds/commandline.rst @@ -21,7 +21,7 @@ With ``CMD`` specified, the command line buffer is erased and replaced with the The following options are available: -- ``-C`` or ``--cursor`` set or get the current cursor position, not the contents of the buffer. If no argument is given, the current cursor position is printed, otherwise the argument is interpreted as the new cursor position. +- ``-C`` or ``--cursor`` set or get the current cursor position, not the contents of the buffer. If no argument is given, the current cursor position is printed, otherwise the argument is interpreted as the new cursor position. If one of the options ``-j``, ``-p`` or ``-t`` is given, the position is relative to the respective substring instead of the entire command line buffer. - ``-f`` or ``--function`` causes any additional arguments to be interpreted as input functions, and puts them into the queue, so that they will be read before any additional actual key presses are. This option cannot be combined with any other option. See :ref:`bind ` for a list of input functions. diff --git a/src/builtin_commandline.cpp b/src/builtin_commandline.cpp index 91225f248..07089da5d 100644 --- a/src/builtin_commandline.cpp +++ b/src/builtin_commandline.cpp @@ -344,7 +344,9 @@ maybe_t builtin_commandline(parser_t &parser, io_streams_t &streams, const } if ((buffer_part || tokenize || cut_at_cursor) && - (cursor_mode || line_mode || search_mode || paging_mode)) { + (cursor_mode || line_mode || search_mode || paging_mode) && + // Special case - we allow to get/set cursor position relative to the process/job/token. + !(buffer_part && cursor_mode)) { streams.err.append_format(BUILTIN_ERR_COMBO, argv[0]); builtin_print_error_trailer(parser, streams.err, cmd); return STATUS_INVALID_ARGS; @@ -414,7 +416,7 @@ maybe_t builtin_commandline(parser_t &parser, io_streams_t &streams, const if (cursor_mode) { if (argc - w.woptind) { - long new_pos = fish_wcstol(argv[w.woptind]); + long new_pos = fish_wcstol(argv[w.woptind]) + (begin - current_buffer); if (errno) { streams.err.append_format(BUILTIN_ERR_NOT_NUMBER, cmd, argv[w.woptind]); builtin_print_error_trailer(parser, streams.err, cmd); @@ -425,8 +427,8 @@ maybe_t builtin_commandline(parser_t &parser, io_streams_t &streams, const std::max(0L, std::min(new_pos, static_cast(std::wcslen(current_buffer)))); reader_set_buffer(current_buffer, static_cast(new_pos)); } else { - streams.out.append_format(L"%lu\n", - static_cast(reader_get_cursor_pos())); + size_t pos = reader_get_cursor_pos() - (begin - current_buffer); + streams.out.append_format(L"%lu\n", static_cast(pos)); } return STATUS_CMD_OK; }