|
|
|
@ -21,14 +21,14 @@ use helix_core::{
|
|
|
|
|
visual_offset_from_block, Position, Range, Selection, Transaction,
|
|
|
|
|
};
|
|
|
|
|
use helix_view::{
|
|
|
|
|
document::{Mode, SCRATCH_BUFFER_NAME},
|
|
|
|
|
editor::{CompleteAction, CursorShapeConfig, ExplorerPosition},
|
|
|
|
|
document::{Mode, SavePoint, SCRATCH_BUFFER_NAME},
|
|
|
|
|
graphics::{Color, CursorKind, Modifier, Rect, Style},
|
|
|
|
|
input::{KeyEvent, MouseButton, MouseEvent, MouseEventKind},
|
|
|
|
|
keyboard::{KeyCode, KeyModifiers},
|
|
|
|
|
Document, Editor, Theme, View,
|
|
|
|
|
};
|
|
|
|
|
use std::{num::NonZeroUsize, path::PathBuf, rc::Rc};
|
|
|
|
|
use std::{mem::take, num::NonZeroUsize, path::PathBuf, rc::Rc, sync::Arc};
|
|
|
|
|
|
|
|
|
|
use tui::buffer::Buffer as Surface;
|
|
|
|
|
|
|
|
|
@ -39,7 +39,7 @@ pub struct EditorView {
|
|
|
|
|
pub keymaps: Keymaps,
|
|
|
|
|
on_next_key: Option<OnKeyCallback>,
|
|
|
|
|
pseudo_pending: Vec<KeyEvent>,
|
|
|
|
|
last_insert: (commands::MappableCommand, Vec<InsertEvent>),
|
|
|
|
|
pub(crate) last_insert: (commands::MappableCommand, Vec<InsertEvent>),
|
|
|
|
|
pub(crate) completion: Option<Completion>,
|
|
|
|
|
spinners: ProgressSpinners,
|
|
|
|
|
pub(crate) explorer: Option<Explorer>,
|
|
|
|
@ -50,6 +50,7 @@ pub enum InsertEvent {
|
|
|
|
|
Key(KeyEvent),
|
|
|
|
|
CompletionApply(CompleteAction),
|
|
|
|
|
TriggerCompletion,
|
|
|
|
|
RequestCompletion,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Default for EditorView {
|
|
|
|
@ -822,6 +823,7 @@ impl EditorView {
|
|
|
|
|
(Mode::Insert, Mode::Normal) => {
|
|
|
|
|
// if exiting insert mode, remove completion
|
|
|
|
|
self.completion = None;
|
|
|
|
|
cxt.editor.completion_request_handle = None;
|
|
|
|
|
|
|
|
|
|
// TODO: Use an on_mode_change hook to remove signature help
|
|
|
|
|
cxt.jobs.callback(async {
|
|
|
|
@ -892,6 +894,8 @@ impl EditorView {
|
|
|
|
|
for _ in 0..cxt.editor.count.map_or(1, NonZeroUsize::into) {
|
|
|
|
|
// first execute whatever put us into insert mode
|
|
|
|
|
self.last_insert.0.execute(cxt);
|
|
|
|
|
let mut last_savepoint = None;
|
|
|
|
|
let mut last_request_savepoint = None;
|
|
|
|
|
// then replay the inputs
|
|
|
|
|
for key in self.last_insert.1.clone() {
|
|
|
|
|
match key {
|
|
|
|
@ -899,7 +903,9 @@ impl EditorView {
|
|
|
|
|
InsertEvent::CompletionApply(compl) => {
|
|
|
|
|
let (view, doc) = current!(cxt.editor);
|
|
|
|
|
|
|
|
|
|
doc.restore(view);
|
|
|
|
|
if let Some(last_savepoint) = last_savepoint.as_deref() {
|
|
|
|
|
doc.restore(view, last_savepoint);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let text = doc.text().slice(..);
|
|
|
|
|
let cursor = doc.selection(view.id).primary().cursor(text);
|
|
|
|
@ -916,8 +922,11 @@ impl EditorView {
|
|
|
|
|
doc.apply(&tx, view.id);
|
|
|
|
|
}
|
|
|
|
|
InsertEvent::TriggerCompletion => {
|
|
|
|
|
let (_, doc) = current!(cxt.editor);
|
|
|
|
|
doc.savepoint();
|
|
|
|
|
last_savepoint = take(&mut last_request_savepoint);
|
|
|
|
|
}
|
|
|
|
|
InsertEvent::RequestCompletion => {
|
|
|
|
|
let (view, doc) = current!(cxt.editor);
|
|
|
|
|
last_request_savepoint = Some(doc.savepoint(view));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -942,26 +951,31 @@ impl EditorView {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[allow(clippy::too_many_arguments)]
|
|
|
|
|
pub fn set_completion(
|
|
|
|
|
&mut self,
|
|
|
|
|
editor: &mut Editor,
|
|
|
|
|
savepoint: Arc<SavePoint>,
|
|
|
|
|
items: Vec<helix_lsp::lsp::CompletionItem>,
|
|
|
|
|
offset_encoding: helix_lsp::OffsetEncoding,
|
|
|
|
|
start_offset: usize,
|
|
|
|
|
trigger_offset: usize,
|
|
|
|
|
size: Rect,
|
|
|
|
|
) {
|
|
|
|
|
let mut completion =
|
|
|
|
|
Completion::new(editor, items, offset_encoding, start_offset, trigger_offset);
|
|
|
|
|
let mut completion = Completion::new(
|
|
|
|
|
editor,
|
|
|
|
|
savepoint,
|
|
|
|
|
items,
|
|
|
|
|
offset_encoding,
|
|
|
|
|
start_offset,
|
|
|
|
|
trigger_offset,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if completion.is_empty() {
|
|
|
|
|
// skip if we got no completion results
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Immediately initialize a savepoint
|
|
|
|
|
doc_mut!(editor).savepoint();
|
|
|
|
|
|
|
|
|
|
editor.last_completion = None;
|
|
|
|
|
self.last_insert.1.push(InsertEvent::TriggerCompletion);
|
|
|
|
|
|
|
|
|
@ -974,8 +988,6 @@ impl EditorView {
|
|
|
|
|
self.completion = None;
|
|
|
|
|
|
|
|
|
|
// Clear any savepoints
|
|
|
|
|
let doc = doc_mut!(editor);
|
|
|
|
|
doc.savepoint = None;
|
|
|
|
|
editor.clear_idle_timer(); // don't retrigger
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|