Use COMP_WORDBREAKS for completion word breaking, fix cursor row in vi command mode, and append completion suffix instead of replacing full token
This commit is contained in:
@@ -6,6 +6,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use nix::sys::signal::Signal;
|
use nix::sys::signal::Signal;
|
||||||
|
use unicode_width::UnicodeWidthStr;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
builtin::complete::{CompFlags, CompOptFlags, CompOpts}, expand::escape_str, libsh::{error::ShResult, guards::var_ctx_guard, sys::TTY_FILENO, utils::TkVecUtils}, parse::{
|
builtin::complete::{CompFlags, CompOptFlags, CompOpts}, expand::escape_str, libsh::{error::ShResult, guards::var_ctx_guard, sys::TTY_FILENO, utils::TkVecUtils}, parse::{
|
||||||
@@ -1172,10 +1173,11 @@ impl Completer for FuzzyCompleter {
|
|||||||
log::debug!("Getting completed line for candidate: {}", _candidate);
|
log::debug!("Getting completed line for candidate: {}", _candidate);
|
||||||
|
|
||||||
let selected = self.selector.selected_candidate().unwrap_or_default();
|
let selected = self.selector.selected_candidate().unwrap_or_default();
|
||||||
let escaped = escape_str(&selected, false);
|
let (mut start, end) = self.completer.token_span;
|
||||||
log::debug!("Selected candidate: {}", selected);
|
let slice = self.completer.original_input.get(start..end).unwrap_or_default();
|
||||||
let (start, end) = self.completer.token_span;
|
start += slice.width();
|
||||||
log::debug!("Token span: ({}, {})", start, end);
|
let completion = selected.strip_prefix(slice).unwrap_or(&selected);
|
||||||
|
let escaped = escape_str(completion, false);
|
||||||
let ret = format!(
|
let ret = format!(
|
||||||
"{}{}{}",
|
"{}{}{}",
|
||||||
&self.completer.original_input[..start],
|
&self.completer.original_input[..start],
|
||||||
@@ -1432,8 +1434,11 @@ impl SimpleCompleter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let selected = &self.candidates[self.selected_idx];
|
let selected = &self.candidates[self.selected_idx];
|
||||||
let escaped = escape_str(selected, false);
|
let (mut start, end) = self.token_span;
|
||||||
let (start, end) = self.token_span;
|
let slice = self.original_input.get(start..end).unwrap_or("");
|
||||||
|
start += slice.width();
|
||||||
|
let completion = selected.strip_prefix(slice).unwrap_or(selected);
|
||||||
|
let escaped = escape_str(completion, false);
|
||||||
format!(
|
format!(
|
||||||
"{}{}{}",
|
"{}{}{}",
|
||||||
&self.original_input[..start],
|
&self.original_input[..start],
|
||||||
@@ -1596,13 +1601,13 @@ impl SimpleCompleter {
|
|||||||
.set_range(self.token_span.0..self.token_span.1);
|
.set_range(self.token_span.0..self.token_span.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If token contains '=', only complete after the '='
|
// If token contains any COMP_WORDBREAKS, break the word
|
||||||
let token_str = cur_token.span.as_str();
|
let token_str = cur_token.span.as_str();
|
||||||
if let Some(eq_pos) = token_str.rfind('=') {
|
|
||||||
self.token_span.0 = cur_token.span.range().start + eq_pos + 1;
|
let word_breaks = read_vars(|v| v.try_get_var("COMP_WORDBREAKS")).unwrap_or("=".into());
|
||||||
cur_token
|
if let Some(break_pos) = token_str.rfind(|c: char| word_breaks.contains(c)) {
|
||||||
.span
|
self.token_span.0 = cur_token.span.range().start + break_pos + 1;
|
||||||
.set_range(self.token_span.0..self.token_span.1);
|
cur_token.span.set_range(self.token_span.0..self.token_span.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
let raw_tk = cur_token.as_str().to_string();
|
let raw_tk = cur_token.as_str().to_string();
|
||||||
|
|||||||
@@ -1055,6 +1055,7 @@ impl ShedVi {
|
|||||||
let pending_seq = self.mode.pending_seq().unwrap_or_default();
|
let pending_seq = self.mode.pending_seq().unwrap_or_default();
|
||||||
write!(buf, "\n: {pending_seq}").unwrap();
|
write!(buf, "\n: {pending_seq}").unwrap();
|
||||||
new_layout.end.row += 1;
|
new_layout.end.row += 1;
|
||||||
|
new_layout.cursor.row += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
write!(buf, "{}", &self.mode.cursor_style()).unwrap();
|
write!(buf, "{}", &self.mode.cursor_style()).unwrap();
|
||||||
|
|||||||
@@ -1045,7 +1045,7 @@ impl VarTab {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
let vars = HashMap::new();
|
let vars = Self::init_sh_vars();
|
||||||
let params = Self::init_params();
|
let params = Self::init_params();
|
||||||
Self::init_env();
|
Self::init_env();
|
||||||
let mut var_tab = Self {
|
let mut var_tab = Self {
|
||||||
@@ -1064,6 +1064,11 @@ impl VarTab {
|
|||||||
params.insert(ShellParam::LastJob, "".into()); // PID of the last background job (if any)
|
params.insert(ShellParam::LastJob, "".into()); // PID of the last background job (if any)
|
||||||
params
|
params
|
||||||
}
|
}
|
||||||
|
fn init_sh_vars() -> HashMap<String,Var> {
|
||||||
|
let mut vars = HashMap::new();
|
||||||
|
vars.insert("COMP_WORDBREAKS".into(), " \t\n\"'@><=;|&(".into());
|
||||||
|
vars
|
||||||
|
}
|
||||||
fn init_env() {
|
fn init_env() {
|
||||||
let pathbuf_to_string =
|
let pathbuf_to_string =
|
||||||
|pb: Result<PathBuf, std::io::Error>| pb.unwrap_or_default().to_string_lossy().to_string();
|
|pb: Result<PathBuf, std::io::Error>| pb.unwrap_or_default().to_string_lossy().to_string();
|
||||||
|
|||||||
Reference in New Issue
Block a user