Skip to content

Commit

Permalink
ide style completions (#696)
Browse files Browse the repository at this point in the history
* ide style completions

* descriptions

* truncate suggestion & description

* border width

* clippy & typos

* run cargo fmt

* add with_description_offset to builder

* fix empty description

* minimize description padding

* rework working details handling + fix CI

* add tests + change split function

* fix multiline prompt cursor pos
  • Loading branch information
maxomatic458 authored Jan 18, 2024
1 parent 2f3eb3e commit 31eaeeb
Show file tree
Hide file tree
Showing 10 changed files with 1,569 additions and 15 deletions.
3 changes: 3 additions & 0 deletions .typos.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,8 @@ extend-exclude = ["src/core_editor/line_buffer.rs"]
iterm = "iterm"
# For testing completion of the word build
bui = "bui"
# For testing string truncation
descriptio = "descriptio"
ot = "ot"
# for sqlite backed history
wheres = "wheres"
58 changes: 58 additions & 0 deletions examples/ide_completions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Create a reedline object with tab completions support
// cargo run --example completions
//
// "t" [Tab] will allow you to select the completions "test" and "this is the reedline crate"
// [Enter] to select the chosen alternative

use reedline::{
default_emacs_keybindings, DefaultCompleter, DefaultPrompt, Emacs, IdeMenu, KeyCode,
KeyModifiers, Keybindings, Reedline, ReedlineEvent, ReedlineMenu, Signal,
};
use std::io;

fn add_menu_keybindings(keybindings: &mut Keybindings) {
keybindings.add_binding(
KeyModifiers::NONE,
KeyCode::Tab,
ReedlineEvent::UntilFound(vec![
ReedlineEvent::Menu("completion_menu".to_string()),
ReedlineEvent::MenuNext,
]),
);
}
fn main() -> io::Result<()> {
let commands = vec![
"test".into(),
"hello world".into(),
"hello world reedline".into(),
"this is the reedline crate".into(),
];
let completer = Box::new(DefaultCompleter::new_with_wordlen(commands, 2));
// Use the interactive menu to select options from the completer
let completion_menu = Box::new(IdeMenu::default().with_name("completion_menu"));

let mut keybindings = default_emacs_keybindings();
add_menu_keybindings(&mut keybindings);

let edit_mode = Box::new(Emacs::new(keybindings));

let mut line_editor = Reedline::create()
.with_completer(completer)
.with_menu(ReedlineMenu::EngineCompleter(completion_menu))
.with_edit_mode(edit_mode);

let prompt = DefaultPrompt::default();

loop {
let sig = line_editor.read_line(&prompt)?;
match sig {
Signal::Success(buffer) => {
println!("We processed: {buffer}");
}
Signal::CtrlD | Signal::CtrlC => {
println!("\nAborted!");
break Ok(());
}
}
}
}
7 changes: 6 additions & 1 deletion src/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1688,7 +1688,7 @@ impl Reedline {
// Needs to add return carriage to newlines because when not in raw mode
// some OS don't fully return the carriage

let lines = PromptLines::new(
let mut lines = PromptLines::new(
prompt,
self.prompt_edit_mode(),
None,
Expand All @@ -1700,6 +1700,11 @@ impl Reedline {
// Updating the working details of the active menu
for menu in self.menus.iter_mut() {
if menu.is_active() {
lines.prompt_indicator = menu.indicator().to_owned().into();
// If the menu requires the cursor position, update it (ide menu)
let cursor_pos = lines.cursor_pos(self.painter.screen_width());
menu.set_cursor_pos(cursor_pos);

menu.update_working_details(
&mut self.editor,
self.completer.as_mut(),
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ pub use validator::{DefaultValidator, ValidationResult, Validator};

mod menu;
pub use menu::{
menu_functions, ColumnarMenu, ListMenu, Menu, MenuEvent, MenuTextStyle, ReedlineMenu,
menu_functions, ColumnarMenu, IdeMenu, ListMenu, Menu, MenuEvent, MenuTextStyle, ReedlineMenu,
};

mod terminal_extensions;
Expand Down
4 changes: 4 additions & 0 deletions src/menu/columnar_menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -728,6 +728,10 @@ impl Menu for ColumnarMenu {
.collect()
}
}

fn set_cursor_pos(&mut self, _pos: (u16, u16)) {
// The columnar menu does not need the cursor position
}
}

#[cfg(test)]
Expand Down
Loading

0 comments on commit 31eaeeb

Please sign in to comment.