From ddb72848526b5f4dca2ca4d683eee66c5579dec5 Mon Sep 17 00:00:00 2001 From: Eric Freese Date: Tue, 23 Feb 2016 20:11:56 -0700 Subject: [PATCH] Fix backslash escaping problems with `echo -E`. --- script/test.zsh | 37 +++++++++++++++++++++++++++++++++++++ src/suggestion.zsh | 14 +++++++++----- zsh-autosuggestions.zsh | 14 +++++++++----- 3 files changed, 55 insertions(+), 10 deletions(-) diff --git a/script/test.zsh b/script/test.zsh index cbabd0c..45f3dbc 100755 --- a/script/test.zsh +++ b/script/test.zsh @@ -281,6 +281,43 @@ testWidgetClear() { "stub_called _zsh_autosuggest_highlight_apply" } +testEscapeCommandPrefix() { + assertEquals \ + "Did not escape single backslash" \ + "\\\\" \ + "$(_zsh_autosuggest_escape_command_prefix "\\")" + + assertEquals \ + "Did not escape two backslashes" \ + "\\\\\\\\" \ + "$(_zsh_autosuggest_escape_command_prefix "\\\\")" + + assertEquals \ + "Did not escape parentheses" \ + "\\(\\)" \ + "$(_zsh_autosuggest_escape_command_prefix "()")" + + assertEquals \ + "Did not escape square brackets" \ + "\\[\\]" \ + "$(_zsh_autosuggest_escape_command_prefix "[]")" + + assertEquals \ + "Did not escape pipe" \ + "\\|" \ + "$(_zsh_autosuggest_escape_command_prefix "|")" + + assertEquals \ + "Did not escape star" \ + "\\*" \ + "$(_zsh_autosuggest_escape_command_prefix "*")" + + assertEquals \ + "Did not escape question mark" \ + "\\?" \ + "$(_zsh_autosuggest_escape_command_prefix "?")" +} + # For zsh compatibility setopt shwordsplit SHUNIT_PARENT=$0 diff --git a/src/suggestion.zsh b/src/suggestion.zsh index 2b8bd77..b94031e 100644 --- a/src/suggestion.zsh +++ b/src/suggestion.zsh @@ -5,15 +5,19 @@ # Get a suggestion from history that matches a given prefix _zsh_autosuggest_suggestion() { - setopt localoptions extendedglob - - # Escape the prefix (requires EXTENDED_GLOB) - local prefix="${1//(#m)[\][()|\\*?#<>~^]/\\$MATCH}" + local prefix=$(_zsh_autosuggest_escape_command_prefix "$1") # Get all history items (reversed) that match pattern $prefix* local history_matches history_matches=(${(j:\0:s:\0:)history[(R)$prefix*]}) # Echo the first item that matches - echo "$history_matches[1]" + echo -E "$history_matches[1]" +} + +_zsh_autosuggest_escape_command_prefix() { + setopt localoptions EXTENDED_GLOB + + # Escape special chars in the string (requires EXTENDED_GLOB) + echo -E "${1//(#m)[\\()\[\]|*?]/\\$MATCH}" } diff --git a/zsh-autosuggestions.zsh b/zsh-autosuggestions.zsh index 364c30c..409ea2a 100644 --- a/zsh-autosuggestions.zsh +++ b/zsh-autosuggestions.zsh @@ -291,17 +291,21 @@ zle -N autosuggest-clear _zsh_autosuggest_widget_clear # Get a suggestion from history that matches a given prefix _zsh_autosuggest_suggestion() { - setopt localoptions extendedglob - - # Escape the prefix (requires EXTENDED_GLOB) - local prefix="${1//(#m)[\][()|\\*?#<>~^]/\\$MATCH}" + local prefix=$(_zsh_autosuggest_escape_command_prefix "$1") # Get all history items (reversed) that match pattern $prefix* local history_matches history_matches=(${(j:\0:s:\0:)history[(R)$prefix*]}) # Echo the first item that matches - echo "$history_matches[1]" + echo -E "$history_matches[1]" +} + +_zsh_autosuggest_escape_command_prefix() { + setopt localoptions EXTENDED_GLOB + + # Escape special chars in the string (requires EXTENDED_GLOB) + echo -E "${1//(#m)[\\()\[\]|*?]/\\$MATCH}" } #--------------------------------------------------------------------#