Skip to content

Commit

Permalink
Fix highlight_line signature
Browse files Browse the repository at this point in the history
We need to return a `Cow<str>` for `MaskingHighlighter`
  • Loading branch information
gwenn committed Aug 24, 2024
1 parent 606adc1 commit 9e5c0e1
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 15 deletions.
1 change: 1 addition & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ jobs:
cargo check --workspace --all-targets --features 'split-highlight'
cargo check --workspace --all-targets --features 'split-highlight ansi-str'
cargo check --workspace --all-targets --features 'split-highlight anstyle'
cargo check --workspace --all-targets --features 'split-highlight anstyle derive'
direct-minimal-versions:
name: Test min versions
Expand Down
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ maintenance = { status = "actively-developed" }
members = ["rustyline-derive"]

[dependencies]
# For convenience, you can highlight the whole input buffer, ansi-str helps to split
# For convenience / compatibilty, you can highlight the whole input buffer, ansi-str helps to split
ansi-str = { version = "0.8.0", optional = true }
# ansi_str::Style is immutable so we use anstyle::Style instead
anstyle = { version = "1.0.8", optional = true }
bitflags = "2.6"
cfg-if = "1.0"
Expand Down
3 changes: 3 additions & 0 deletions examples/custom_key_bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ use rustyline::{Completer, Helper, Hinter, Validator};
struct MyHelper(#[rustyline(Hinter)] HistoryHinter);

impl Highlighter for MyHelper {
#[cfg(all(feature = "split-highlight", not(feature = "ansi-str")))]
type Style = ();

fn highlight_prompt<'b, 's: 'b, 'p: 'b>(
&'s self,
prompt: &'p str,
Expand Down
13 changes: 13 additions & 0 deletions examples/example.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ struct MyHelper {
}

impl Highlighter for MyHelper {
#[cfg(all(feature = "split-highlight", not(feature = "ansi-str")))]
type Style = anstyle::Style;

fn highlight_prompt<'b, 's: 'b, 'p: 'b>(
&'s self,
prompt: &'p str,
Expand All @@ -37,10 +40,20 @@ impl Highlighter for MyHelper {
Owned("\x1b[1m".to_owned() + hint + "\x1b[m")
}

#[cfg(any(not(feature = "split-highlight"), feature = "ansi-str"))]
fn highlight<'l>(&self, line: &'l str, pos: usize) -> Cow<'l, str> {
self.highlighter.highlight(line, pos)
}

#[cfg(all(feature = "split-highlight", not(feature = "ansi-str")))]
fn highlight_line<'l>(
&self,
line: &'l str,
pos: usize,
) -> impl ExactSizeIterator<Item = (Self::Style, Cow<'l, str>)> {
self.highlighter.highlight_line(line, pos)
}

fn highlight_char(&self, line: &str, pos: usize, forced: bool) -> bool {
self.highlighter.highlight_char(line, pos, forced)
}
Expand Down
22 changes: 20 additions & 2 deletions examples/read_password.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::borrow::Cow::{self, Borrowed, Owned};
use std::borrow::Cow::{self, Owned};

use rustyline::config::Configurer;
use rustyline::highlight::Highlighter;
Expand All @@ -11,12 +11,30 @@ struct MaskingHighlighter {
}

impl Highlighter for MaskingHighlighter {
#[cfg(all(feature = "split-highlight", not(feature = "ansi-str")))]
type Style = ();

#[cfg(any(not(feature = "split-highlight"), feature = "ansi-str"))]
fn highlight<'l>(&self, line: &'l str, _pos: usize) -> Cow<'l, str> {
use unicode_width::UnicodeWidthStr;
if self.masking {
Owned(" ".repeat(line.width()))
} else {
Borrowed(line)
Cow::Borrowed(line)
}
}

#[cfg(all(feature = "split-highlight", not(feature = "ansi-str")))]
fn highlight_line<'l>(
&self,
line: &'l str,
_pos: usize,
) -> impl ExactSizeIterator<Item = (Self::Style, Cow<'l, str>)> {
use unicode_width::UnicodeWidthStr;
if self.masking {
vec![((), Owned(" ".repeat(line.width())))].into_iter()
} else {
vec![].into_iter()
}
}

Expand Down
20 changes: 20 additions & 0 deletions rustyline-derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,28 @@ pub fn highlighter_macro_derive(input: TokenStream) -> TokenStream {
quote! {
#[automatically_derived]
impl #impl_generics ::rustyline::highlight::Highlighter for #name #ty_generics #where_clause {
#[cfg(all(feature = "split-highlight", not(feature = "ansi-str"), feature = "anstyle"))]
type Style = anstyle::Style;
#[cfg(all(feature = "split-highlight", not(feature = "ansi-str"), not(feature = "anstyle")))]
type Style = ();

#[cfg(any(not(feature = "split-highlight"), feature = "ansi-str"))]
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)
}

#[cfg(all(feature = "split-highlight", not(feature = "ansi-str")))]
fn highlight_line<'l>(
&self,
line: &'l str,
pos: usize,
) -> impl ExactSizeIterator<Item = (Self::Style, ::std::borrow::Cow<'l, str>)>
where
Self: Sized,
{
::rustyline::highlight::Highlighter::highlight_line(&self.#field_name_or_index, line, pos)
}

fn highlight_prompt<'b, 's: 'b, 'p: 'b>(
&'s self,
prompt: &'p str,
Expand Down Expand Up @@ -135,6 +153,8 @@ pub fn highlighter_macro_derive(input: TokenStream) -> TokenStream {
quote! {
#[automatically_derived]
impl #impl_generics ::rustyline::highlight::Highlighter for #name #ty_generics #where_clause {
#[cfg(all(feature = "split-highlight", not(feature = "ansi-str")))]
type Style = ();
}
}
};
Expand Down
36 changes: 25 additions & 11 deletions src/highlight.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ impl Style for anstyle::Style {
}
}

/*
/// Styled text
#[cfg(feature = "split-highlight")]
#[cfg_attr(docsrs, doc(cfg(feature = "split-highlight")))]
Expand Down Expand Up @@ -91,6 +92,7 @@ impl StyledBlock for (anstyle::Style, &str) {
&self.0
}
}
*/

/// Syntax highlighter with [ANSI color](https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters).
/// Rustyline will try to handle escape sequence for ANSI color on windows
Expand Down Expand Up @@ -129,13 +131,16 @@ pub trait Highlighter {
docsrs,
doc(cfg(all(feature = "split-highlight", not(feature = "ansi-str"))))
)]
// TODO try to return an `IntoIterator` instead of a `Vec`
fn highlight_line<'l>(&self, line: &'l str, pos: usize) -> Vec<(Self::Style, &'l str)>
fn highlight_line<'l>(
&self,
line: &'l str,
pos: usize,
) -> impl ExactSizeIterator<Item = (Self::Style, Cow<'l, str>)>
where
Self: Sized,
{
let _ = (line, pos);
vec![]
std::iter::empty()
}

/// Takes the `prompt` and
Expand Down Expand Up @@ -193,7 +198,11 @@ impl<'r, H: Highlighter> Highlighter for &'r H {
}

#[cfg(all(feature = "split-highlight", not(feature = "ansi-str")))]
fn highlight_line<'l>(&self, line: &'l str, pos: usize) -> Vec<(Self::Style, &'l str)>
fn highlight_line<'l>(
&self,
line: &'l str,
pos: usize,
) -> impl ExactSizeIterator<Item = (Self::Style, Cow<'l, str>)>
where
Self: Sized,
{
Expand Down Expand Up @@ -275,20 +284,25 @@ impl Highlighter for MatchingBracketHighlighter {
}

#[cfg(all(feature = "split-highlight", not(feature = "ansi-str")))]
fn highlight_line<'l>(&self, line: &'l str, _pos: usize) -> Vec<(Self::Style, &'l str)> {
fn highlight_line<'l>(
&self,
line: &'l str,
_pos: usize,
) -> impl ExactSizeIterator<Item = (Self::Style, Cow<'l, str>)> {
if line.len() <= 1 {
return vec![];
return vec![].into_iter();
}
if let Some((bracket, pos)) = self.bracket.get() {
if let Some((_, idx)) = find_matching_bracket(line, pos, bracket) {
return vec![
(Self::Style::default(), &line[0..idx]),
(self.style, &line[idx..=idx]),
(Self::Style::default(), &line[idx + 1..]),
];
(Self::Style::default(), Borrowed(&line[0..idx])),
(self.style, Borrowed(&line[idx..=idx])),
(Self::Style::default(), Borrowed(&line[idx + 1..])),
]
.into_iter();
}
}
vec![]
vec![].into_iter()
}

fn highlight_char(&self, line: &str, pos: usize, forced: bool) -> bool {
Expand Down
2 changes: 1 addition & 1 deletion src/tty/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1013,7 +1013,7 @@ impl Renderer for PosixRenderer {
use crate::highlight::Style;
for (style, block) in highlighter.highlight_line(line, line.pos()) {
write!(self.buffer, "{}", style.start())?;
self.buffer.push_str(block);
self.buffer.push_str(&block);
write!(self.buffer, "{}", style.end())?;
}
}
Expand Down

0 comments on commit 9e5c0e1

Please sign in to comment.