Skip to content

Commit

Permalink
Handle prompt completions with AsyncHook.
Browse files Browse the repository at this point in the history
This change updates prompt completions in the background, to avoid
blocking the UI on slow file IO such as over a networked FS. I followed
the example of how LSP completions are handled asynchronously.
  • Loading branch information
Rose Hogenson committed Sep 27, 2024
1 parent 30aa375 commit 336e41e
Show file tree
Hide file tree
Showing 7 changed files with 305 additions and 221 deletions.
2 changes: 1 addition & 1 deletion helix-term/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2182,7 +2182,7 @@ fn searcher(cx: &mut Context, direction: Direction) {
cx,
"search:".into(),
Some(reg),
move |_editor: &Editor, input: &str| {
move |input: &str| {
completions
.iter()
.filter(|comp| comp.starts_with(input))
Expand Down
126 changes: 63 additions & 63 deletions helix-term/src/commands/dap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,12 +334,8 @@ fn debug_parameter_prompt(
.to_owned();

let completer = match field_type {
"filename" => |editor: &Editor, input: &str| {
ui::completers::filename_with_git_ignore(editor, input, false)
},
"directory" => |editor: &Editor, input: &str| {
ui::completers::directory_with_git_ignore(editor, input, false)
},
"filename" => |input: &str| ui::completers::filename_with_git_ignore(input, false),
"directory" => |input: &str| ui::completers::directory_with_git_ignore(input, false),
_ => ui::completers::none,
};

Expand Down Expand Up @@ -631,35 +627,37 @@ pub fn dap_edit_condition(cx: &mut Context) {
None => return,
};
let callback = Box::pin(async move {
let call: Callback = Callback::EditorCompositor(Box::new(move |editor, compositor| {
let mut prompt = Prompt::new(
"condition:".into(),
None,
ui::completers::none,
move |cx, input: &str, event: PromptEvent| {
if event != PromptEvent::Validate {
return;
}

let breakpoints = &mut cx.editor.breakpoints.get_mut(&path).unwrap();
breakpoints[pos].condition = match input {
"" => None,
input => Some(input.to_owned()),
};

let debugger = debugger!(cx.editor);

if let Err(e) = breakpoints_changed(debugger, path.clone(), breakpoints) {
cx.editor
.set_error(format!("Failed to set breakpoints: {}", e));
}
},
);
if let Some(condition) = breakpoint.condition {
prompt.insert_str(&condition, editor)
}
compositor.push(Box::new(prompt));
}));
let call: Callback =
Callback::EditorCompositor(Box::new(move |_editor, compositor| {
let mut prompt = Prompt::new(
"condition:".into(),
None,
ui::completers::none,
move |cx, input: &str, event: PromptEvent| {
if event != PromptEvent::Validate {
return;
}

let breakpoints = &mut cx.editor.breakpoints.get_mut(&path).unwrap();
breakpoints[pos].condition = match input {
"" => None,
input => Some(input.to_owned()),
};

let debugger = debugger!(cx.editor);

if let Err(e) = breakpoints_changed(debugger, path.clone(), breakpoints)
{
cx.editor
.set_error(format!("Failed to set breakpoints: {}", e));
}
},
);
if let Some(condition) = breakpoint.condition {
prompt.insert_str(&condition)
}
compositor.push(Box::new(prompt));
}));
Ok(call)
});
cx.jobs.callback(callback);
Expand All @@ -673,34 +671,36 @@ pub fn dap_edit_log(cx: &mut Context) {
None => return,
};
let callback = Box::pin(async move {
let call: Callback = Callback::EditorCompositor(Box::new(move |editor, compositor| {
let mut prompt = Prompt::new(
"log-message:".into(),
None,
ui::completers::none,
move |cx, input: &str, event: PromptEvent| {
if event != PromptEvent::Validate {
return;
}

let breakpoints = &mut cx.editor.breakpoints.get_mut(&path).unwrap();
breakpoints[pos].log_message = match input {
"" => None,
input => Some(input.to_owned()),
};

let debugger = debugger!(cx.editor);
if let Err(e) = breakpoints_changed(debugger, path.clone(), breakpoints) {
cx.editor
.set_error(format!("Failed to set breakpoints: {}", e));
}
},
);
if let Some(log_message) = breakpoint.log_message {
prompt.insert_str(&log_message, editor);
}
compositor.push(Box::new(prompt));
}));
let call: Callback =
Callback::EditorCompositor(Box::new(move |_editor, compositor| {
let mut prompt = Prompt::new(
"log-message:".into(),
None,
ui::completers::none,
move |cx, input: &str, event: PromptEvent| {
if event != PromptEvent::Validate {
return;
}

let breakpoints = &mut cx.editor.breakpoints.get_mut(&path).unwrap();
breakpoints[pos].log_message = match input {
"" => None,
input => Some(input.to_owned()),
};

let debugger = debugger!(cx.editor);
if let Err(e) = breakpoints_changed(debugger, path.clone(), breakpoints)
{
cx.editor
.set_error(format!("Failed to set breakpoints: {}", e));
}
},
);
if let Some(log_message) = breakpoint.log_message {
prompt.insert_str(&log_message);
}
compositor.push(Box::new(prompt));
}));
Ok(call)
});
cx.jobs.callback(callback);
Expand Down
7 changes: 3 additions & 4 deletions helix-term/src/commands/lsp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1125,7 +1125,6 @@ pub fn rename_symbol(cx: &mut Context) {
}

fn create_rename_prompt(
editor: &Editor,
prefill: String,
history_register: Option<char>,
language_server_id: Option<LanguageServerId>,
Expand Down Expand Up @@ -1163,7 +1162,7 @@ pub fn rename_symbol(cx: &mut Context) {
}
},
)
.with_line(prefill, editor);
.with_line(prefill);

Box::new(prompt)
}
Expand Down Expand Up @@ -1212,14 +1211,14 @@ pub fn rename_symbol(cx: &mut Context) {
}
};

let prompt = create_rename_prompt(editor, prefill, history_register, Some(ls_id));
let prompt = create_rename_prompt(prefill, history_register, Some(ls_id));

compositor.push(prompt);
},
);
} else {
let prefill = get_prefill_from_word_boundary(cx.editor);
let prompt = create_rename_prompt(cx.editor, prefill, history_register, None);
let prompt = create_rename_prompt(prefill, history_register, None);
cx.push_layer(prompt);
}
}
Expand Down
6 changes: 3 additions & 3 deletions helix-term/src/commands/typed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3159,7 +3159,7 @@ pub(super) fn command_mode(cx: &mut Context) {
let mut prompt = Prompt::new(
":".into(),
Some(':'),
|editor: &Editor, input: &str| {
|input: &str| {
let shellwords = Shellwords::from(input);
let words = shellwords.words();

Expand Down Expand Up @@ -3187,7 +3187,7 @@ pub(super) fn command_mode(cx: &mut Context) {
.get(&words[0] as &str)
.map(|tc| tc.completer_for_argument_number(argument_number))
{
completer(editor, word)
completer(word)
.into_iter()
.map(|(range, file)| {
let file = shellwords::escape(file);
Expand Down Expand Up @@ -3247,7 +3247,7 @@ pub(super) fn command_mode(cx: &mut Context) {
});

// Calculate initial completion
prompt.recalculate_completion(cx.editor);
prompt.recalculate_completion();
cx.push_layer(Box::new(prompt));
}

Expand Down
Loading

0 comments on commit 336e41e

Please sign in to comment.