diff --git a/confutils.nim b/confutils.nim index 494d477..1e0b8ea 100644 --- a/confutils.nim +++ b/confutils.nim @@ -273,11 +273,13 @@ proc completeCmdArg*(T: type[InputFile|InputDir], val: TaintedString): seq[strin type(T) is InputDir and kind in {pcDir, pcLinkToDir}: # Note, no normalization is needed here if path.startsWith(tail): - if type(T) is InputDir: + let match = if kind in {pcDir, pcLinkToDir}: # Add a trailing slash so that completions can be chained - result.add(dir_path / path & '/') + dir_path & DirSep & path & DirSep else: - result.add(dir_path / path) + dir_path & DirSep & path + + result.add(shellPathEscape(match)) proc completeCmdArg*(T: type[OutFile|OutDir|OutPath], val: TaintedString): seq[string] = return @[] diff --git a/confutils/shell_completion.nim b/confutils/shell_completion.nim index 1365e7a..67b3829 100644 --- a/confutils/shell_completion.nim +++ b/confutils/shell_completion.nim @@ -140,7 +140,7 @@ proc splitCompletionLine*(): seq[string] = break result.add(token.get()) -proc quoteWord*(word: string): string = +proc shellQuote*(word: string): string = if len(word) == 0: return "''" @@ -154,6 +154,15 @@ proc quoteWord*(word: string): string = result.add('\'') +proc shellPathEscape*(path: string): string = + if allCharsInSet(path, SAFE_CHARS): + return path + + for ch in path: + if ch notin SAFE_CHARS: + result.add('\\') + result.add(ch) + # Test data lifted from python's shlex unit-tests const data = """ foo bar|foo|bar|