@@ -24,28 +24,40 @@ set --global VSCODE_SHELL_INTEGRATION 1
24
24
25
25
# Helper function
26
26
function __vsc_esc -d " Emit escape sequences for VS Code shell integration"
27
- builtin printf " \e]633;%s\007 " (string join " ;" $argv )
27
+ builtin printf " \e]633;%s\a " (string join " ;" $argv )
28
28
end
29
29
30
30
# Sent right before executing an interactive command.
31
31
# Marks the beginning of command output.
32
32
function __vsc_cmd_executed --on-event fish_preexec
33
33
__vsc_esc C
34
- __vsc_esc E (__vsc_escape_cmd " $argv " )
34
+ __vsc_esc E (__vsc_escape_value " $argv " )
35
35
36
36
# Creates a marker to indicate a command was run.
37
37
set --global _vsc_has_cmd
38
38
end
39
39
40
40
41
- # Escapes backslashes, newlines, and semicolons to serialize the command line.
42
- function __vsc_escape_cmd
43
- set -l commandline " $argv "
44
- # `string replace` automatically breaks its input apart on any newlines.
45
- # Then `string join` at the end will bring it all back together.
46
- string replace --all ' \\' ' \\\\ ' $commandline \
47
- | string replace --all ' ;' ' \ x3b' \
48
- | string join ' \ x0a'
41
+ # Escape a value for use in the 'P' ("Property") or 'E' ("Command Line") sequences.
42
+ # Backslashes are doubled and non-alphanumeric characters are hex encoded.
43
+ function __vsc_escape_value
44
+ # Replace all non-alnum characters with %XX hex form.
45
+ string escape --style =url " $argv " \
46
+ # The characters [-./_~] are not encoded in the builtin url escaping, despite not being alphanumeric.
47
+ # See: https://github.com/fish-shell/fish-shell/blob/f82537bcdcb32f85a530395f00e7be1aa9afc592/src/common.cpp#L738
48
+ # For consistency, also encode those characters.
49
+ | string replace --all ' -' ' %2D' \
50
+ | string replace --all ' .' ' %2E' \
51
+ | string replace --all ' /' ' %2F' \
52
+ | string replace --all ' _' ' %5F' \
53
+ | string replace --all ' ~' ' %7E' \
54
+ # Now everything is either alphanumeric [0-9A-Za-z] or %XX escapes.
55
+ # Change the hex escape representation from '%' to '\x'. (e.g. ' ' → '%20' → '\x20').
56
+ # Note that all '%' characters are escapes: literal '%' will already have been encoded.
57
+ | string replace --all ' %' ' \\ x' \
58
+ # For readability, prefer to represent literal backslashes with doubling. ('\' → '%5C' → '\x5C' → '\\').
59
+ | string replace --all --ignore-case ' %5C' ' \\\\' \
60
+ ;
49
61
end
50
62
51
63
# Sent right after an interactive command has finished executing.
63
75
# Sent whenever a new fish prompt is about to be displayed.
64
76
# Updates the current working directory.
65
77
function __vsc_update_cwd --on-event fish_prompt
66
- __vsc_esc P "Cwd=$PWD "
78
+ __vsc_esc P "Cwd=$(__vsc_escape_value " $ PWD") "
67
79
68
80
# If a command marker exists, remove it.
69
81
# Otherwise, the commandline is empty and no command was run.
0 commit comments