diff --git a/src/common.rs b/src/common.rs index ad10e3844..3500bf0e9 100644 --- a/src/common.rs +++ b/src/common.rs @@ -514,6 +514,7 @@ fn unescape_string_internal(input: &wstr, flags: UnescapeFlags) -> Option Option { - if unescape_special && input_position == 0 { + if unescape_special + && (input_position == 0 || Some(input_position) == potential_word_start) + { to_append_or_none = Some(HOME_DIRECTORY); } } @@ -605,6 +608,7 @@ fn unescape_string_internal(input: &wstr, flags: UnescapeFlags) -> Option { @@ -645,6 +649,7 @@ fn unescape_string_internal(input: &wstr, flags: UnescapeFlags) -> Option 0 { to_append_or_none = Some(BRACE_SEP); vars_or_seps.push(input_position); + potential_word_start = Some(input_position + 1); } } ' ' => { diff --git a/src/expand.rs b/src/expand.rs index 49b44f114..b54766f20 100644 --- a/src/expand.rs +++ b/src/expand.rs @@ -1130,7 +1130,9 @@ fn get_home_directory_name<'a>(input: &'a wstr, out_tail_idx: &mut usize) -> &'a /// Attempts tilde expansion of the string specified, modifying it in place. fn expand_home_directory(input: &mut WString, vars: &dyn Environment) { - if input.as_char_slice().first() != Some(&HOME_DIRECTORY) { + let starts_with_tilde = input.as_char_slice().first() == Some(&HOME_DIRECTORY); + *input = input.replace([HOME_DIRECTORY], L!("~")); + if !starts_with_tilde { return; } @@ -1171,8 +1173,6 @@ fn expand_home_directory(input: &mut WString, vars: &dyn Environment) { if let Some(home) = home { input.replace_range(..tail_idx, &normalize_path(&home, true)); - } else { - input.replace_range(0..1, L!("~")); } } diff --git a/tests/checks/expansion.fish b/tests/checks/expansion.fish index f646d1937..97546c53b 100644 --- a/tests/checks/expansion.fish +++ b/tests/checks/expansion.fish @@ -340,3 +340,10 @@ echo foo | $pager #CHECKERR: checks/expansion.fish (line 339): The expanded command is a keyword. #CHECKERR: echo foo | $pager #CHECKERR: ^~~~~^ + +echo {~,asdf} +# CHECK: /{{.*}} asdf +echo {asdf,~} +# CHECK: asdf /{{.*}} +echo {~} +# CHECK: {~}