zsh completion; Fix leading ~ in filenames being quoted on insertion into commandline

This commit is contained in:
Kovid Goyal 2023-01-04 11:07:56 +05:30
parent 035c3de4bb
commit c83a8b0773
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 26 additions and 2 deletions

View File

@ -89,7 +89,12 @@ func serialize(completions *Completions, f *markup.Context, screen_width int) ([
} else {
for _, mg := range completions.Groups {
cmd := strings.Builder{}
cmd.WriteString("compadd -U -J ")
escape_ourselves := mg.IsFiles // zsh quoting quotes a leading ~/ in filenames which is wrong
cmd.WriteString("compadd -U ")
if escape_ourselves {
cmd.WriteString("-Q ")
}
cmd.WriteString("-J ")
cmd.WriteString(utils.QuoteStringForSH(mg.Title))
cmd.WriteString(" -X ")
cmd.WriteString(utils.QuoteStringForSH("%B" + mg.Title + "%b"))
@ -116,7 +121,11 @@ func serialize(completions *Completions, f *markup.Context, screen_width int) ([
cmd.WriteString(" --")
for _, m := range mg.Matches {
cmd.WriteString(" ")
cmd.WriteString(utils.QuoteStringForSH(m.Word))
w := m.Word
if escape_ourselves {
w = utils.EscapeSHMetaCharacters(m.Word)
}
cmd.WriteString(utils.QuoteStringForSH(w))
}
fmt.Fprintln(&output, cmd.String(), ";")
}

View File

@ -24,3 +24,18 @@ func QuoteStringForFish(x string) string {
x = strings.ReplaceAll(x, "'", "\\'")
return "'" + x + "'"
}
// Escapes common shell meta characters
func EscapeSHMetaCharacters(x string) string {
const metachars = "\\|&;<>()$'\" \n\t"
ans := strings.Builder{}
ans.Grow(len(x) + 32)
for _, ch := range x {
switch ch {
case '\\', '|', '&', ';', '<', '>', '(', ')', '$', '\'', '"', ' ', '\n', '\t':
ans.WriteRune('\\')
}
ans.WriteRune(ch)
}
return ans.String()
}