Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions conf.d/_tide_vscode.fish
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
status is-interactive || exit
test "$VSCODE_INJECTION" = 1 || exit

# Capture the real post-command state before VSCode's prompt hooks mutate it,
# so Tide can render accurate status and cmd_duration items on the next prompt.
function _tide_vscode_capture_postexec --on-event fish_postexec
set -g _tide_vscode_had_cmd 1
set -g _tide_vscode_status $status
set -g _tide_vscode_pipestatus $pipestatus
set -g _tide_vscode_cmd_duration $CMD_DURATION
end

# Fish's clear-screen reader function does not go through VSCode's normal
# command lifecycle hooks, so refresh VSCode's prompt markers after Ctrl+L to
# avoid sticky-command spacing glitches.
function _tide_vscode_clear_screen
commandline -f clear-screen
functions --query __vsc_update_cwd && __vsc_update_cwd
end

bind ctrl-l _tide_vscode_clear_screen

# VSCode's wrapper is installed after startup, so wait until it exists before
# replacing fish_prompt with Tide's newline-safe wrapper.
function _tide_vscode_fix_prompt --on-event fish_prompt
_tide_vscode_wrap_prompt || return
functions --erase _tide_vscode_fix_prompt
end
4 changes: 4 additions & 0 deletions functions/_tide_item_status.fish
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
function _tide_item_status
# VSCode shell integration already shows command status, so hide Tide's
# status item there by default unless the user explicitly opts back in.
test "$VSCODE_INJECTION" = 1 -a "$tide_status_show_in_vscode" != true && return

if string match -qv 0 $_tide_pipestatus # If there is a failure anywhere in the pipestatus
if test "$_tide_pipestatus" = 1 # If simple failure
contains character $_tide_left_items || tide_status_bg_color=$tide_status_bg_color_failure \
Expand Down
25 changes: 25 additions & 0 deletions functions/_tide_set_prompt_state.fish
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
function _tide_set_prompt_state
set -l tide_status $status
set -l tide_pipestatus $pipestatus
set -l tide_cmd_duration $CMD_DURATION

# VSCode shell integration can reset $status before Tide renders and emits
# a synthetic command-finished marker on empty prompts, so reuse the last
# real postexec state or fall back to a clean prompt state.
if test "$VSCODE_INJECTION" = 1
if set -q _tide_vscode_had_cmd
set -g _tide_status $_tide_vscode_status
set -g _tide_pipestatus $_tide_vscode_pipestatus
set -g _tide_cmd_duration $_tide_vscode_cmd_duration
set -e _tide_vscode_had_cmd
else
set -g _tide_status 0
set -g _tide_pipestatus 0
set -g _tide_cmd_duration 0
end
else
set -g _tide_status $tide_status
set -g _tide_pipestatus $tide_pipestatus
set -g _tide_cmd_duration $tide_cmd_duration
end
end
6 changes: 5 additions & 1 deletion functions/_tide_sub_reload.fish
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
function _tide_sub_reload
source (functions --details fish_prompt)
# In VSCode shell integration, fish_prompt may be redefined from stdin by
# Tide's wrapper, so reload the prompt from Tide's file on disk instead of
# asking the live function where it came from.
source (string replace -r '[^/]+$' fish_prompt.fish (functions --details _tide_sub_reload))
_tide_vscode_wrap_prompt 2>/dev/null || true
end
15 changes: 15 additions & 0 deletions functions/_tide_vscode_wrap_prompt.fish
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
function _tide_vscode_wrap_prompt
test "$VSCODE_INJECTION" = 1 || return 1
functions --query __vsc_fish_prompt || return 1
functions --query __vsc_fish_prompt_start || return 1
functions --query __vsc_fish_cmd_start || return 1

# VSCode appends its command-start marker after fish_prompt output. Strip
# Tide's trailing newline so that marker stays on the prompt line without
# collapsing Tide's own internal newline for two-line prompts.
function fish_prompt
__vsc_fish_prompt_start
printf '%s' (__vsc_fish_prompt | string collect --allow-empty)
__vsc_fish_cmd_start
end
end
33 changes: 20 additions & 13 deletions functions/fish_prompt.fish
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,13 @@ if contains newline $_tide_left_items # two line prompt initialization
if test "$tide_prompt_transient_enabled" = true
eval "
function fish_prompt
_tide_status=\$status _tide_pipestatus=\$pipestatus if not set -e _tide_repaint
_tide_set_prompt_state
if not set -e _tide_repaint
jobs -q && jobs -p | count | read -lx _tide_jobs
$fish_path -c \"set _tide_pipestatus \$_tide_pipestatus
$fish_path -c \"set _tide_status \$_tide_status
set _tide_pipestatus \$_tide_pipestatus
set _tide_parent_dirs \$_tide_parent_dirs
PATH=\$(string escape \"\$PATH\") CMD_DURATION=\$CMD_DURATION fish_bind_mode=\$fish_bind_mode set $prompt_var (_tide_2_line_prompt)\" &
PATH=\$(string escape \"\$PATH\") CMD_DURATION=\$_tide_cmd_duration fish_bind_mode=\$fish_bind_mode set $prompt_var (_tide_2_line_prompt)\" &
builtin disown

command kill \$_tide_last_pid 2>/dev/null
Expand All @@ -65,11 +67,13 @@ end"
else
eval "
function fish_prompt
_tide_status=\$status _tide_pipestatus=\$pipestatus if not set -e _tide_repaint
_tide_set_prompt_state
if not set -e _tide_repaint
jobs -q && jobs -p | count | read -lx _tide_jobs
$fish_path -c \"set _tide_pipestatus \$_tide_pipestatus
$fish_path -c \"set _tide_status \$_tide_status
set _tide_pipestatus \$_tide_pipestatus
set _tide_parent_dirs \$_tide_parent_dirs
PATH=\$(string escape \"\$PATH\") CMD_DURATION=\$CMD_DURATION fish_bind_mode=\$fish_bind_mode set $prompt_var (_tide_2_line_prompt)\" &
PATH=\$(string escape \"\$PATH\") CMD_DURATION=\$_tide_cmd_duration fish_bind_mode=\$fish_bind_mode set $prompt_var (_tide_2_line_prompt)\" &
builtin disown

command kill \$_tide_last_pid 2>/dev/null
Expand All @@ -96,12 +100,13 @@ else # one line prompt initialization
if test "$tide_prompt_transient_enabled" = true
eval "
function fish_prompt
set -lx _tide_status \$status
_tide_pipestatus=\$pipestatus if not set -e _tide_repaint
_tide_set_prompt_state
if not set -e _tide_repaint
jobs -q && jobs -p | count | read -lx _tide_jobs
$fish_path -c \"set _tide_pipestatus \$_tide_pipestatus
$fish_path -c \"set _tide_status \$_tide_status
set _tide_pipestatus \$_tide_pipestatus
set _tide_parent_dirs \$_tide_parent_dirs
PATH=\$(string escape \"\$PATH\") CMD_DURATION=\$CMD_DURATION fish_bind_mode=\$fish_bind_mode set $prompt_var (_tide_1_line_prompt)\" &
PATH=\$(string escape \"\$PATH\") CMD_DURATION=\$_tide_cmd_duration fish_bind_mode=\$fish_bind_mode set $prompt_var (_tide_1_line_prompt)\" &
builtin disown

command kill \$_tide_last_pid 2>/dev/null
Expand All @@ -124,11 +129,13 @@ end"
else
eval "
function fish_prompt
_tide_status=\$status _tide_pipestatus=\$pipestatus if not set -e _tide_repaint
_tide_set_prompt_state
if not set -e _tide_repaint
jobs -q && jobs -p | count | read -lx _tide_jobs
$fish_path -c \"set _tide_pipestatus \$_tide_pipestatus
$fish_path -c \"set _tide_status \$_tide_status
set _tide_pipestatus \$_tide_pipestatus
set _tide_parent_dirs \$_tide_parent_dirs
PATH=\$(string escape \"\$PATH\") CMD_DURATION=\$CMD_DURATION fish_bind_mode=\$fish_bind_mode set $prompt_var (_tide_1_line_prompt)\" &
PATH=\$(string escape \"\$PATH\") CMD_DURATION=\$_tide_cmd_duration fish_bind_mode=\$fish_bind_mode set $prompt_var (_tide_1_line_prompt)\" &
builtin disown

command kill \$_tide_last_pid 2>/dev/null
Expand Down
2 changes: 2 additions & 0 deletions tests/_tide_item_status.test.fish
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# RUN: %fish %s
_tide_parent_dirs

set -e VSCODE_INJECTION tide_status_show_in_vscode

function _status
set -lx _tide_status $status
set -lx _tide_pipestatus $pipestatus
Expand Down
27 changes: 27 additions & 0 deletions tests/_tide_item_status_vscode.test.fish
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# RUN: %fish %s
_tide_parent_dirs

function _status
set -lx _tide_status $status
set -lx _tide_pipestatus $pipestatus
_tide_decolor (_tide_item_status)
end

set -lx tide_status_icon ✔
set -lx tide_status_icon_failure ✘
set -lx _tide_left_items
set -lx VSCODE_INJECTION 1
set -e tide_status_show_in_vscode

# Hidden by default in VSCode shell integration.
false
_status # CHECK:

# Setting tide_status_show_in_vscode restores the usual Tide status item.
set -lx tide_status_show_in_vscode true

false
_status # CHECK: ✘ 1

true
_status # CHECK: ✔
24 changes: 24 additions & 0 deletions tests/_tide_set_prompt_state.test.fish
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# RUN: %fish %s

function _show_prompt_state
_tide_set_prompt_state
echo $_tide_status\|(string join , $_tide_pipestatus)\|$_tide_cmd_duration
end

set -e VSCODE_INJECTION _tide_vscode_had_cmd _tide_vscode_status _tide_vscode_pipestatus _tide_vscode_cmd_duration

set -gx CMD_DURATION 123
false
_show_prompt_state # CHECK: 1|1|123

set -gx CMD_DURATION 456
true | false
_show_prompt_state # CHECK: 1|0,1|456

set -gx VSCODE_INJECTION 1
set -g _tide_vscode_had_cmd 1
set -g _tide_vscode_status 7
set -g _tide_vscode_pipestatus 0 7
set -g _tide_vscode_cmd_duration 789
_show_prompt_state # CHECK: 7|0,7|789
_show_prompt_state # CHECK: 0|0|0
19 changes: 19 additions & 0 deletions tests/_tide_vscode_wrap_prompt.test.fish
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# RUN: %fish %s

set -gx VSCODE_INJECTION 1

function __vsc_fish_prompt_start
printf A
end

function __vsc_fish_prompt
printf 'left\nright\n'
end

function __vsc_fish_cmd_start
printf B
end

_tide_vscode_wrap_prompt
fish_prompt | od -An -t x1 | string replace -ra '\s+' ' ' | string trim
# CHECK: 41 6c 65 66 74 0a 72 69 67 68 74 42