@@ -829,14 +829,15 @@ func isSubsequence(needle, haystack string) bool {
829829// filePickerDetect checks the textarea value and cursor position and returns
830830// (active, query, atPosition). It only activates when @ is preceded by
831831// whitespace or is at the start of the line, and the cursor is within the
832- // @ token (no whitespace between @ and cursor).
832+ // @ token. An unescaped space terminates the token (dismissing the picker);
833+ // escaped spaces (backslash-space) are treated as literal spaces in the path.
833834func filePickerDetect (value string , cursorPos int ) (bool , string , int ) {
834835 runes := []rune (value )
835836 if cursorPos < 0 || cursorPos > len (runes ) {
836837 return false , "" , 0
837838 }
838839 // Walk backwards from cursor to find the @ character.
839- // Stop if we hit whitespace (no active @ mention at cursor) .
840+ // Stop if we hit an unescaped whitespace character .
840841 pos := cursorPos - 1
841842 for pos >= 0 {
842843 r := runes [pos ]
@@ -845,18 +846,35 @@ func filePickerDetect(value string, cursorPos int) (bool, string, int) {
845846 if pos > 0 && ! unicode .IsSpace (runes [pos - 1 ]) {
846847 return false , "" , 0
847848 }
848- query := string (runes [pos + 1 : cursorPos ])
849+ query := filePickerUnescapeSpaces ( string (runes [pos + 1 : cursorPos ]) )
849850 return true , query , pos
850851 }
851852 if unicode .IsSpace (r ) {
852- // Hit whitespace before finding @.
853+ // Check if this space is escaped with a preceding backslash.
854+ if pos > 0 && runes [pos - 1 ] == '\\' {
855+ pos --
856+ continue
857+ }
858+ // Unescaped whitespace — no active @ mention at cursor.
853859 return false , "" , 0
854860 }
855861 pos --
856862 }
857863 return false , "" , 0
858864}
859865
866+ // filePickerUnescapeSpaces converts escaped spaces ("\ ") to literal spaces
867+ // in a file picker query.
868+ func filePickerUnescapeSpaces (s string ) string {
869+ return strings .ReplaceAll (s , "\\ " , " " )
870+ }
871+
872+ // filePickerEscapeSpaces converts literal spaces to escaped spaces ("\ ")
873+ // for insertion into the textarea.
874+ func filePickerEscapeSpaces (s string ) string {
875+ return strings .ReplaceAll (s , " " , "\\ " )
876+ }
877+
860878// ── model ─────────────────────────────────────────────────────────────────────
861879
862880type tuiModel struct {
@@ -6810,7 +6828,7 @@ func (m *tuiModel) filePickerComplete() {
68106828 if atPos > 0 {
68116829 newVal = string (runes [:atPos ])
68126830 }
6813- insertion := "@" + selected
6831+ insertion := "@" + filePickerEscapeSpaces ( selected )
68146832 newVal += insertion
68156833 if cursorPos < len (runes ) {
68166834 newVal += string (runes [cursorPos :])
0 commit comments