fish_clipboard_paste: trim indentation when pasting multiple lines

When pasting a multiline command with indented blocks, extra indentation
from spaces, or tabs, is generally undesirable, because fish already indents
pipes and blocks. Discard the indentation unless the cursor or the pasted
part is inside quotes.

Users who copied fish_clipboard_paste need to update it because
__fish_commandline_is_singlequoted had an API change and was renamed.
This commit is contained in:
Johannes Altmanninger 2021-02-08 08:12:43 +01:00
parent 5a0aa7824f
commit 4c1173f2ae
3 changed files with 29 additions and 9 deletions

View File

@ -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.

View File

@ -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

View File

@ -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,