diff --git a/CHANGELOG.rst b/CHANGELOG.rst index f0fe9029f..3dcfc48d2 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -278,6 +278,7 @@ New or improved bindings - As mentioned above, new special input functions ``undo`` (Control+\_ or Control+Z) and ``redo`` (Alt-/) can be used to revert changes to the command line or the pager search field (:issue:`6570`). - Control-Z is now available for binding (:issue:`7152`). - Additionally, using the ``cancel`` special input function (bound to escape by default) right after fish picked an unambiguous completion will undo that (:issue:`7433`). +- ``fish_clipboard_paste`` (Control+V) trims indentation from multiline commands because fish already indents (:issue:`7662`). - Vi mode bindings now support ``dh``, ``dl``, ``c0``, ``cf``, ``ct``, ``cF``, ``cT``, ``ch``, ``cl``, ``y0``, ``ci``, ``ca``, ``yi``, ``ya``, ``di``, ``da``, ``d;``, ``d,``, ``o``, ``O`` and Control+left/right keys to navigate by word (:issue:`6648`, :issue:`6755`, :issue:`6769`, :issue:`7442`, :issue:`7516`). - Vi mode bindings support ``~`` (tilde) to toggle the case of the selected character (:issue:`6908`). - Functions ``up-or-search`` and ``down-or-search`` (up-arrow and down-arrow) can cross empty lines and don't activate search mode if the search fails which makes it easier to use them to move between lines in some situations. diff --git a/share/functions/__fish_commandline_is_singlequoted.fish b/share/functions/__fish_tokenizer_state.fish similarity index 84% rename from share/functions/__fish_commandline_is_singlequoted.fish rename to share/functions/__fish_tokenizer_state.fish index 26cb92b8e..42940f2d3 100644 --- a/share/functions/__fish_commandline_is_singlequoted.fish +++ b/share/functions/__fish_tokenizer_state.fish @@ -1,4 +1,4 @@ -function __fish_commandline_is_singlequoted --description "Return 0 if the current token has an open single-quote" +function __fish_tokenizer_state --description "Print the state of the tokenizer at the end of the given string" # Go through the token char-by-char in a state machine. # The states are: # - normal - no quoting is active (the starting state) @@ -8,8 +8,15 @@ function __fish_commandline_is_singlequoted --description "Return 0 if the curre # - single-escaped - open \\ inside single-quotes # - double-escaped - open \\ inside double-quotes + argparse --min-args 1 --max-args 1 i/initial-state= -- $argv + or return 1 + set -l state normal - for char in (commandline -ct | string split "") + if set -q _flag_initial_state + set str $_flag_initial_state + end + + for char in (string split -- "" $argv[1]) switch $char case "'" # single-quote switch $state @@ -51,10 +58,6 @@ function __fish_commandline_is_singlequoted --description "Return 0 if the curre end end end - # TODO: Should "single-escaped" also be a success? - if contains -- $state single single-escaped - return 0 - else - return 1 - end + + echo $state end diff --git a/share/functions/fish_clipboard_paste.fish b/share/functions/fish_clipboard_paste.fish index 37323b59c..3801c7eab 100644 --- a/share/functions/fish_clipboard_paste.fish +++ b/share/functions/fish_clipboard_paste.fish @@ -26,12 +26,28 @@ function fish_clipboard_paste # in order to turn it into a single literal token. # # This eases pasting non-code (e.g. markdown or git commitishes). - if __fish_commandline_is_singlequoted + set -l quote_state (__fish_tokenizer_state -- (commandline -ct)) + if contains -- $quote_state single single-escaped if status test-feature regex-easyesc set data (string replace -ra "(['\\\])" '\\\\$1' -- $data) else set data (string replace -ra "(['\\\])" '\\\\\\\$1' -- $data) end + else if not contains -- $quote_state double double-escaped + and set -q data[2] + # Leading whitespace in subsequent lines is unneded, since fish + # already indents. Also gets rid of tabs (issue #5274). + set -l tmp + for line in $data + switch $quote_state + case normal + set -a tmp (string trim -l -- $line) + case single single-escaped double double-escaped escaped + set -a tmp $line + end + set quote_state (__fish_tokenizer_state -i $quote_state -- $line) + end + set data $data[1] $tmp[2..] end if not string length -q -- (commandline -c) # If we're at the beginning of the first line, trim whitespace from the start,