Skip to content

Commit 407d3ba

Browse files
A Dynamic Collection of Shell Scripts with Educational Purpose
1 parent 41c9c54 commit 407d3ba

1 file changed

Lines changed: 43 additions & 4 deletions

File tree

scripts/bash-ghost-text

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,39 @@ _ghost_notify() {
5757
_ghost_validate_command() {
5858
local cmd_line="$1"
5959

60-
# Extract the first word (command) - handle quoted strings
60+
# Extract the first word (command) - handling escaped spaces
6161
local first_word
6262

6363
# If the line has no spaces but cursor is not at the end,
6464
# the user is editing in the middle - extract only what's before the cursor
6565
if [[ "$cmd_line" != *' '* && $READLINE_POINT -lt ${#cmd_line} ]]; then
6666
first_word="${cmd_line:0:$READLINE_POINT}"
6767
else
68-
first_word="${cmd_line%% *}"
68+
# Extract first word respecting escaped spaces
69+
first_word=""
70+
local escaped=false
71+
local i
72+
for (( i=0; i<${#cmd_line}; i++ )); do
73+
local char="${cmd_line:$i:1}"
74+
75+
if $escaped; then
76+
first_word+="$char"
77+
escaped=false
78+
continue
79+
fi
80+
81+
if [[ "$char" == '\' ]]; then
82+
first_word+="$char"
83+
escaped=true
84+
continue
85+
fi
86+
87+
if [[ "$char" == ' ' ]]; then
88+
break
89+
fi
90+
91+
first_word+="$char"
92+
done
6993
fi
7094

7195
# Remove trailing semicolon (;) FIRST - before removing quotes
@@ -81,18 +105,33 @@ _ghost_validate_command() {
81105
[[ -z "$first_word" ]] && return 0
82106
[[ "$first_word" == *"="* ]] && return 0
83107

84-
# Skip validation if it's a function declaration (word followed by parentheses)
85-
# Examples: test(), my_func(), func_name()
108+
# Skip validation if it's a function declaration
86109
if [[ "$first_word" =~ ^[a-zA-Z_][a-zA-Z0-9_]*\(\)$ ]]; then
87110
return 0
88111
fi
89112

113+
# Check if the word contains escaped spaces or backslashes (file paths)
114+
local has_escapes=false
115+
[[ "$first_word" == *'\ '* || "$first_word" == *'\'* ]] && has_escapes=true
116+
90117
# Expand tilde (~) to $HOME for path validation
91118
local expanded_word="$first_word"
92119
if [[ "$first_word" == "~"* ]]; then
93120
expanded_word="${HOME}${first_word:1}"
94121
fi
95122

123+
# If the word has escapes, it's a file path - skip type/compgen validations
124+
if $has_escapes; then
125+
# Try to validate as a file path directly
126+
local eval_path
127+
eval_path=$(eval echo "$first_word" 2>/dev/null)
128+
if [[ -n "$eval_path" ]] && (test -e "$eval_path" 2>/dev/null || test -e "$expanded_word" 2>/dev/null); then
129+
return 0
130+
fi
131+
# If the file doesn't exist, it's invalid (don't check type/compgen)
132+
return 1
133+
fi
134+
96135
# 1. Check if it's a keyword/special builtin
97136
case "$first_word" in
98137
if|then|else|elif|fi|case|esac|for|while|until|do|done|in|function|select|time|coproc|declare|typeset|local|export|readonly|unset) return 0 ;;

0 commit comments

Comments
 (0)