Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mutable Helper in functions #809

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/custom_key_bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ struct MyHelper(#[rustyline(Hinter)] HistoryHinter);

impl Highlighter for MyHelper {
fn highlight_prompt<'b, 's: 'b, 'p: 'b>(
&'s self,
&'s mut self,
prompt: &'p str,
default: bool,
) -> Cow<'b, str> {
Expand All @@ -25,7 +25,7 @@ impl Highlighter for MyHelper {
}
}

fn highlight_hint<'h>(&self, hint: &'h str) -> Cow<'h, str> {
fn highlight_hint<'h>(&mut self, hint: &'h str) -> Cow<'h, str> {
Owned(format!("\x1b[1m{hint}\x1b[m"))
}
}
Expand Down
4 changes: 2 additions & 2 deletions examples/diy_hints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use rustyline::Context;
use rustyline::{Completer, Helper, Highlighter, Validator};
use rustyline::{Editor, Result};

#[derive(Completer, Helper, Validator, Highlighter)]
#[derive(Completer, Helper, Highlighter, Validator)]
struct DIYHinter {
// It's simple example of rustyline, for more efficient, please use ** radix trie **
hints: HashSet<CommandHint>,
Expand Down Expand Up @@ -52,7 +52,7 @@ impl CommandHint {
impl Hinter for DIYHinter {
type Hint = CommandHint;

fn hint(&self, line: &str, pos: usize, _ctx: &Context<'_>) -> Option<CommandHint> {
fn hint(&mut self, line: &str, pos: usize, _ctx: &Context<'_>) -> Option<CommandHint> {
if line.is_empty() || pos < line.len() {
return None;
}
Expand Down
10 changes: 5 additions & 5 deletions examples/example.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use rustyline::validate::MatchingBracketValidator;
use rustyline::{Cmd, CompletionType, Config, EditMode, Editor, KeyEvent};
use rustyline::{Completer, Helper, Hinter, Validator};

#[derive(Helper, Completer, Hinter, Validator)]
#[derive(Completer, Helper, Hinter, Validator)]
struct MyHelper {
#[rustyline(Completer)]
completer: FilenameCompleter,
Expand All @@ -22,7 +22,7 @@ struct MyHelper {

impl Highlighter for MyHelper {
fn highlight_prompt<'b, 's: 'b, 'p: 'b>(
&'s self,
&'s mut self,
prompt: &'p str,
default: bool,
) -> Cow<'b, str> {
Expand All @@ -33,15 +33,15 @@ impl Highlighter for MyHelper {
}
}

fn highlight_hint<'h>(&self, hint: &'h str) -> Cow<'h, str> {
fn highlight_hint<'h>(&mut self, hint: &'h str) -> Cow<'h, str> {
Owned("\x1b[1m".to_owned() + hint + "\x1b[m")
}

fn highlight<'l>(&self, line: &'l str, pos: usize) -> Cow<'l, str> {
fn highlight<'l>(&mut self, line: &'l str, pos: usize) -> Cow<'l, str> {
self.highlighter.highlight(line, pos)
}

fn highlight_char(&self, line: &str, pos: usize, forced: bool) -> bool {
fn highlight_char(&mut self, line: &str, pos: usize, forced: bool) -> bool {
self.highlighter.highlight_char(line, pos, forced)
}
}
Expand Down
2 changes: 1 addition & 1 deletion examples/input_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use rustyline::{Editor, Result};
struct InputValidator {}

impl Validator for InputValidator {
fn validate(&self, ctx: &mut ValidationContext) -> Result<ValidationResult> {
fn validate(&mut self, ctx: &mut ValidationContext) -> Result<ValidationResult> {
use ValidationResult::{Incomplete, Invalid, Valid};
let input = ctx.input();
let result = if !input.starts_with("SELECT") {
Expand Down
4 changes: 2 additions & 2 deletions examples/read_password.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ struct MaskingHighlighter {
}

impl Highlighter for MaskingHighlighter {
fn highlight<'l>(&self, line: &'l str, _pos: usize) -> Cow<'l, str> {
fn highlight<'l>(&mut self, line: &'l str, _pos: usize) -> Cow<'l, str> {
use unicode_width::UnicodeWidthStr;
if self.masking {
Owned(" ".repeat(line.width()))
Expand All @@ -20,7 +20,7 @@ impl Highlighter for MaskingHighlighter {
}
}

fn highlight_char(&self, _line: &str, _pos: usize, _forced: bool) -> bool {
fn highlight_char(&mut self, _line: &str, _pos: usize, _forced: bool) -> bool {
self.masking
}
}
Expand Down
40 changes: 20 additions & 20 deletions rustyline-derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,16 @@ pub fn completer_macro_derive(input: TokenStream) -> TokenStream {
type Candidate = <#field_type as ::rustyline::completion::Completer>::Candidate;

fn complete(
&self,
&mut self,
line: &str,
pos: usize,
ctx: &::rustyline::Context<'_>,
) -> ::rustyline::Result<(usize, ::std::vec::Vec<Self::Candidate>)> {
::rustyline::completion::Completer::complete(&self.#field_name_or_index, line, pos, ctx)
::rustyline::completion::Completer::complete(&mut self.#field_name_or_index, line, pos, ctx)
}

fn update(&self, line: &mut ::rustyline::line_buffer::LineBuffer, start: usize, elected: &str, cl: &mut ::rustyline::Changeset) {
::rustyline::completion::Completer::update(&self.#field_name_or_index, line, start, elected, cl)
fn update(&mut self, line: &mut ::rustyline::line_buffer::LineBuffer, start: usize, elected: &str, cl: &mut ::rustyline::Changeset) {
::rustyline::completion::Completer::update(&mut self.#field_name_or_index, line, start, elected, cl)
}
}
}
Expand Down Expand Up @@ -102,32 +102,32 @@ pub fn highlighter_macro_derive(input: TokenStream) -> TokenStream {
quote! {
#[automatically_derived]
impl #impl_generics ::rustyline::highlight::Highlighter for #name #ty_generics #where_clause {
fn highlight<'l>(&self, line: &'l str, pos: usize) -> ::std::borrow::Cow<'l, str> {
::rustyline::highlight::Highlighter::highlight(&self.#field_name_or_index, line, pos)
fn highlight<'l>(&mut self, line: &'l str, pos: usize) -> ::std::borrow::Cow<'l, str> {
::rustyline::highlight::Highlighter::highlight(&mut self.#field_name_or_index, line, pos)
}

fn highlight_prompt<'b, 's: 'b, 'p: 'b>(
&'s self,
&'s mut self,
prompt: &'p str,
default: bool,
) -> ::std::borrow::Cow<'b, str> {
::rustyline::highlight::Highlighter::highlight_prompt(&self.#field_name_or_index, prompt, default)
::rustyline::highlight::Highlighter::highlight_prompt(&mut self.#field_name_or_index, prompt, default)
}

fn highlight_hint<'h>(&self, hint: &'h str) -> ::std::borrow::Cow<'h, str> {
::rustyline::highlight::Highlighter::highlight_hint(&self.#field_name_or_index, hint)
fn highlight_hint<'h>(&mut self, hint: &'h str) -> ::std::borrow::Cow<'h, str> {
::rustyline::highlight::Highlighter::highlight_hint(&mut self.#field_name_or_index, hint)
}

fn highlight_candidate<'c>(
&self,
&mut self,
candidate: &'c str,
completion: ::rustyline::config::CompletionType,
) -> ::std::borrow::Cow<'c, str> {
::rustyline::highlight::Highlighter::highlight_candidate(&self.#field_name_or_index, candidate, completion)
::rustyline::highlight::Highlighter::highlight_candidate(&mut self.#field_name_or_index, candidate, completion)
}

fn highlight_char(&self, line: &str, pos: usize, forced: bool) -> bool {
::rustyline::highlight::Highlighter::highlight_char(&self.#field_name_or_index, line, pos, forced)
fn highlight_char(&mut self, line: &str, pos: usize, forced: bool) -> bool {
::rustyline::highlight::Highlighter::highlight_char(&mut self.#field_name_or_index, line, pos, forced)
}
}
}
Expand Down Expand Up @@ -156,8 +156,8 @@ pub fn hinter_macro_derive(input: TokenStream) -> TokenStream {
impl #impl_generics ::rustyline::hint::Hinter for #name #ty_generics #where_clause {
type Hint = <#field_type as ::rustyline::hint::Hinter>::Hint;

fn hint(&self, line: &str, pos: usize, ctx: &::rustyline::Context<'_>) -> ::std::option::Option<Self::Hint> {
::rustyline::hint::Hinter::hint(&self.#field_name_or_index, line, pos, ctx)
fn hint(&mut self, line: &str, pos: usize, ctx: &::rustyline::Context<'_>) -> ::std::option::Option<Self::Hint> {
::rustyline::hint::Hinter::hint(&mut self.#field_name_or_index, line, pos, ctx)
}
}
}
Expand Down Expand Up @@ -185,14 +185,14 @@ pub fn validator_macro_derive(input: TokenStream) -> TokenStream {
#[automatically_derived]
impl #impl_generics ::rustyline::validate::Validator for #name #ty_generics #where_clause {
fn validate(
&self,
&mut self,
ctx: &mut ::rustyline::validate::ValidationContext,
) -> ::rustyline::Result<::rustyline::validate::ValidationResult> {
::rustyline::validate::Validator::validate(&self.#field_name_or_index, ctx)
::rustyline::validate::Validator::validate(&mut self.#field_name_or_index, ctx)
}

fn validate_while_typing(&self) -> bool {
::rustyline::validate::Validator::validate_while_typing(&self.#field_name_or_index)
fn validate_while_typing(&mut self) -> bool {
::rustyline::validate::Validator::validate_while_typing(&mut self.#field_name_or_index)
}
}
}
Expand Down
61 changes: 48 additions & 13 deletions src/completion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ pub trait Completer {
///
/// ("ls /usr/loc", 11) => Ok((3, vec!["/usr/local/"]))
fn complete(
&self, // FIXME should be `&mut self`
&mut self,
line: &str,
pos: usize,
ctx: &Context<'_>,
Expand All @@ -99,7 +99,7 @@ pub trait Completer {
Ok((0, Vec::with_capacity(0)))
}
/// Updates the edited `line` with the `elected` candidate.
fn update(&self, line: &mut LineBuffer, start: usize, elected: &str, cl: &mut Changeset) {
fn update(&mut self, line: &mut LineBuffer, start: usize, elected: &str, cl: &mut Changeset) {
let end = line.pos();
line.replace(start..end, elected, cl);
}
Expand All @@ -108,38 +108,52 @@ pub trait Completer {
impl Completer for () {
type Candidate = String;

fn update(&self, _line: &mut LineBuffer, _start: usize, _elected: &str, _cl: &mut Changeset) {
fn update(
&mut self,
_line: &mut LineBuffer,
_start: usize,
_elected: &str,
_cl: &mut Changeset,
) {
unreachable!();
}
}

impl<'c, C: ?Sized + Completer> Completer for &'c C {
impl<'c, C: ?Sized + Completer> Completer for &'c mut C {
type Candidate = C::Candidate;

fn complete(
&self,
&mut self,
line: &str,
pos: usize,
ctx: &Context<'_>,
) -> Result<(usize, Vec<Self::Candidate>)> {
(**self).complete(line, pos, ctx)
}

fn update(&self, line: &mut LineBuffer, start: usize, elected: &str, cl: &mut Changeset) {
fn update(&mut self, line: &mut LineBuffer, start: usize, elected: &str, cl: &mut Changeset) {
(**self).update(line, start, elected, cl);
}
}
macro_rules! box_completer {
macro_rules! rc_completer {
($($id: ident)*) => {
$(
impl<C: ?Sized + Completer> Completer for $id<C> {
type Candidate = C::Candidate;

fn complete(&self, line: &str, pos: usize, ctx: &Context<'_>) -> Result<(usize, Vec<Self::Candidate>)> {
(**self).complete(line, pos, ctx)
fn complete(&mut self, line: &str, pos: usize, ctx: &Context<'_>) -> Result<(usize, Vec<Self::Candidate>)> {
if let Some(c) = $id::get_mut(self){
c.complete(line, pos, ctx)
} else {
unreachable!()
}
}
fn update(&self, line: &mut LineBuffer, start: usize, elected: &str, cl: &mut Changeset) {
(**self).update(line, start, elected, cl)
fn update(&mut self, line: &mut LineBuffer, start: usize, elected: &str, cl: &mut Changeset) {
if let Some(c) = $id::get_mut(self){
c.update(line, start, elected, cl)
} else {
unreachable!()
}
}
}
)*
Expand All @@ -149,7 +163,23 @@ macro_rules! box_completer {
use crate::undo::Changeset;
use std::rc::Rc;
use std::sync::Arc;
box_completer! { Box Rc Arc }
rc_completer! { Rc Arc }

impl<C: ?Sized + Completer> Completer for Box<C> {
type Candidate = C::Candidate;

fn complete(
&mut self,
line: &str,
pos: usize,
ctx: &Context<'_>,
) -> Result<(usize, Vec<Self::Candidate>)> {
(**self).complete(line, pos, ctx)
}
fn update(&mut self, line: &mut LineBuffer, start: usize, elected: &str, cl: &mut Changeset) {
(**self).update(line, start, elected, cl)
}
}

/// A `Completer` for file and folder names.
pub struct FilenameCompleter {
Expand Down Expand Up @@ -256,7 +286,12 @@ impl Default for FilenameCompleter {
impl Completer for FilenameCompleter {
type Candidate = Pair;

fn complete(&self, line: &str, pos: usize, _ctx: &Context<'_>) -> Result<(usize, Vec<Pair>)> {
fn complete(
&mut self,
line: &str,
pos: usize,
_ctx: &Context<'_>,
) -> Result<(usize, Vec<Pair>)> {
self.complete_path(line, pos)
}
}
Expand Down
Loading