Skip to content

Commit

Permalink
Reorganize split-highlight feature gating logic
Browse files Browse the repository at this point in the history
  • Loading branch information
zao111222333 committed Sep 19, 2024
1 parent e42bda3 commit 94a5899
Show file tree
Hide file tree
Showing 9 changed files with 265 additions and 158 deletions.
8 changes: 6 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ members = ["rustyline-derive"]
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 }
syntect = { version = "5.2.0", optional = true }
bitflags = "2.6"
cfg-if = "1.0"
# For file completion
Expand Down Expand Up @@ -71,7 +72,7 @@ with-sqlite-history = ["rusqlite"]
with-fuzzy = ["skim"]
case_insensitive_history_search = ["regex"]
# For continuation prompt, indentation, scrolling
split-highlight = []
split-highlight = ["ansi-str", "anstyle", "syntect"]
continuation-prompt = ["split-highlight"]
[[example]]
name = "custom_key_bindings"
Expand All @@ -87,7 +88,10 @@ name = "input_multiline"
required-features = ["custom-bindings", "derive"]
[[example]]
name = "continuation_prompt"
required-features = ["custom-bindings", "derive", "continuation-prompt", "anstyle"]
required-features = ["custom-bindings", "derive", "continuation-prompt"]
[[example]]
name = "highlight_python"
required-features = ["custom-bindings", "derive", "continuation-prompt"]
[[example]]
name = "input_validation"
required-features = ["derive"]
Expand Down
11 changes: 2 additions & 9 deletions examples/continuation_prompt.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use rustyline::highlight::{AnsiStyle, StyledBlock};
use rustyline::highlight::StyledBlock;
use rustyline::{Cmd, Editor, EventHandler, KeyCode, KeyEvent, Modifiers, Result};
use rustyline::{Completer, Helper, Hinter, Validator};
use std::borrow::Cow;
#[derive(Completer, Helper, Hinter, Validator)]
struct InputHelper;

impl rustyline::highlight::Highlighter for InputHelper {
#[cfg(feature = "continuation-prompt")]
fn continuation_prompt<'b, 's: 'b, 'p: 'b>(
&'s self,
prompt: &'p str,
Expand All @@ -18,14 +19,6 @@ impl rustyline::highlight::Highlighter for InputHelper {
Cow::Owned(prompt.replace('>', "."))
}
}
fn highlight_line<'l>(
&self,
line: &'l str,
_pos: usize,
) -> impl Iterator<Item = impl Iterator<Item = impl 'l + StyledBlock>> {
line.split('\n')
.map(|l| core::iter::once((AnsiStyle::default(), l)))
}
}
fn main() -> Result<()> {
let h = InputHelper {};
Expand Down
4 changes: 2 additions & 2 deletions examples/example.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ impl Highlighter for MyHelper {
Owned("\x1b[1m".to_owned() + hint + "\x1b[m")
}

#[cfg(any(not(feature = "split-highlight"), feature = "ansi-str"))]
#[cfg(not(feature = "split-highlight"))]
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")))]
#[cfg(all(feature = "split-highlight", not(feature = "continuation-prompt")))]
fn highlight_line<'l>(
&self,
line: &'l str,
Expand Down
66 changes: 66 additions & 0 deletions examples/highlight_python.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
use rustyline::highlight::StyledBlock;
use rustyline::{Cmd, Editor, EventHandler, KeyCode, KeyEvent, Modifiers, Result};
use rustyline::{Completer, Helper, Hinter, Validator};
use syntect::highlighting::{Theme, ThemeSet};
use syntect::parsing::SyntaxSet;

use std::borrow::Cow;
#[derive(Completer, Helper, Hinter, Validator)]
struct InputHelper {
theme: Theme,
syntax_set: SyntaxSet,
}

impl rustyline::highlight::Highlighter for InputHelper {
fn highlight_char(&self, _line: &str, _pos: usize, _forced: bool) -> bool {
true
}
#[cfg(feature = "continuation-prompt")]
fn continuation_prompt<'b, 's: 'b, 'p: 'b>(
&'s self,
_prompt: &'p str,
_default: bool,
) -> Cow<'b, str> {
Cow::Borrowed("... ")
}
#[cfg(all(feature = "split-highlight", feature = "continuation-prompt",))]
fn highlight_lines<'l>(
&self,
lines: &'l str,
_pos: usize,
) -> impl Iterator<Item = impl Iterator<Item = impl 'l + StyledBlock>> {
use syntect::easy::HighlightLines;
use syntect::highlighting::Style;
let syntax = self.syntax_set.find_syntax_by_extension("py").unwrap();
let mut highlighter = HighlightLines::new(syntax, &self.theme);
lines.split('\n').map(move |line| {
highlighter
.highlight_line(line, &self.syntax_set)
.unwrap_or(vec![(Style::default(), line)])
.into_iter()
.map(|(mut s, token)| {
s.background.a = 0;
(s, token)
})
})
}
}
fn main() -> Result<()> {
let h = InputHelper {
theme: ThemeSet::load_defaults()
.themes
.remove("base16-ocean.dark")
.unwrap(),
syntax_set: SyntaxSet::load_defaults_newlines(),
};
let mut rl = Editor::new()?;
rl.set_helper(Some(h));
rl.bind_sequence(
KeyEvent(KeyCode::Char('s'), Modifiers::CTRL),
EventHandler::Simple(Cmd::Newline),
);
let input = rl.readline("python REPL example\n>>> ")?;
println!("Input: \n{input}");

Ok(())
}
12 changes: 4 additions & 8 deletions examples/read_password.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ struct MaskingHighlighter {
}

impl Highlighter for MaskingHighlighter {
#[cfg(any(not(feature = "split-highlight"), feature = "ansi-str"))]
#[cfg(not(feature = "split-highlight"))]
fn highlight<'l>(&self, line: &'l str, _pos: usize) -> std::borrow::Cow<'l, str> {
use unicode_width::UnicodeWidthStr;
if self.masking {
Expand All @@ -19,21 +19,17 @@ impl Highlighter for MaskingHighlighter {
}
}

#[cfg(all(feature = "split-highlight", not(feature = "ansi-str")))]
#[cfg(all(feature = "split-highlight", not(feature = "continuation-prompt")))]
fn highlight_line<'l>(
&self,
line: &'l str,
_pos: usize,
) -> impl Iterator<Item = impl 'l + rustyline::highlight::StyledBlock> {
use unicode_width::UnicodeWidthStr;
if self.masking {
vec![(
rustyline::highlight::AnsiStyle::default(),
" ".repeat(line.width()),
)]
.into_iter()
vec![(anstyle::Style::default(), " ".repeat(line.width()))].into_iter()
} else {
vec![(rustyline::highlight::AnsiStyle::default(), line.to_owned())].into_iter()
vec![(anstyle::Style::default(), line.to_owned())].into_iter()
}
}

Expand Down
22 changes: 20 additions & 2 deletions rustyline-derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,12 +102,12 @@ pub fn highlighter_macro_derive(input: TokenStream) -> TokenStream {
quote! {
#[automatically_derived]
impl #impl_generics ::rustyline::highlight::Highlighter for #name #ty_generics #where_clause {
#[cfg(any(not(feature = "split-highlight"), feature = "ansi-str"))]
#[cfg(not(feature = "split-highlight"))]
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")))]
#[cfg(all(feature = "split-highlight", not(feature = "continuation-prompt")))]
fn highlight_line<'l>(
&self,
line: &'l str,
Expand All @@ -116,6 +116,24 @@ pub fn highlighter_macro_derive(input: TokenStream) -> TokenStream {
::rustyline::highlight::Highlighter::highlight_line(&self.#field_name_or_index, line, pos)
}

#[cfg(all(feature = "split-highlight", feature = "continuation-prompt"))]
fn highlight_lines<'l>(
&self,
lines: &'l str,
pos: usize,
) -> impl Iterator<Item = impl Iterator<Item = impl 'l + ::rustyline::highlight::StyledBlock>> {
::rustyline::highlight::Highlighter::highlight_lines(&self.#field_name_or_index, lines, pos)
}

#[cfg(feature = "continuation-prompt")]
fn continuation_prompt<'b, 's: 'b, 'p: 'b>(
&'s self,
prompt: &'p str,
default: bool,
) -> ::std::borrow::Cow<'b, str> {
::rustyline::highlight::Highlighter::continuation_prompt(&self.#field_name_or_index, prompt, default)
}

fn highlight_prompt<'b, 's: 'b, 'p: 'b>(
&'s self,
prompt: &'p str,
Expand Down
Loading

0 comments on commit 94a5899

Please sign in to comment.