Skip to content

Commit

Permalink
Fix unix impl
Browse files Browse the repository at this point in the history
  • Loading branch information
gwenn committed Aug 24, 2024
1 parent 271052d commit cb173ff
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 23 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ jobs:
run: cargo check --workspace --no-default-features
env:
RUSTFLAGS: "-D warnings"
- name: Check split-highlight feature
run: |
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'
direct-minimal-versions:
name: Test min versions
Expand Down
7 changes: 3 additions & 4 deletions src/edit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use unicode_width::UnicodeWidthChar;

use super::{Context, Helper, Result};
use crate::error::ReadlineError;
use crate::highlight::Highlighter;
use crate::hint::Hint;
use crate::history::SearchDirection;
use crate::keymap::{Anchor, At, CharSearch, Cmd, Movement, RepeatCount, Word};
Expand Down Expand Up @@ -70,9 +69,9 @@ impl<'out, 'prompt, H: Helper> State<'out, 'prompt, H> {
}
}

pub fn highlighter(&self) -> Option<&dyn Highlighter> {
pub fn highlighter(&self) -> Option<&H> {
if self.out.colors_enabled() {
self.helper.map(|h| h as &dyn Highlighter)
self.helper
} else {
None
}
Expand Down Expand Up @@ -169,7 +168,7 @@ impl<'out, 'prompt, H: Helper> State<'out, 'prompt, H> {
Info::Msg(msg) => msg,
};
let highlighter = if self.out.colors_enabled() {
self.helper.map(|h| h as &dyn Highlighter)
self.helper
} else {
None
};
Expand Down
38 changes: 33 additions & 5 deletions src/highlight.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ impl StyledBlock for (anstyle::Style, &str) {
pub trait Highlighter {
/// ANSI Style
#[cfg(all(feature = "split-highlight", not(feature = "ansi-str")))]
type Style: Style + Default
type Style: Style
where
Self: Sized;
/// Takes the currently edited `line` with the cursor `pos`ition and
Expand All @@ -122,6 +122,8 @@ pub trait Highlighter {

/// Takes the currently edited `line` with the cursor `pos`ition and
/// returns the styled blocks.
///
/// Returns an empty vec when there is no highlighting.
#[cfg(all(feature = "split-highlight", not(feature = "ansi-str")))]
#[cfg_attr(
docsrs,
Expand All @@ -132,9 +134,8 @@ pub trait Highlighter {
where
Self: Sized,
{
let _ = pos;
// TODO default style vs empty vec to indicate no highlighting
vec![(Self::Style::default(), line)]
let _ = (line, pos);
vec![]
}

/// Takes the `prompt` and
Expand Down Expand Up @@ -229,6 +230,8 @@ impl<'r, H: Highlighter> Highlighter for &'r H {
/// Highlight matching bracket when typed or cursor moved on.
#[derive(Default)]
pub struct MatchingBracketHighlighter {
#[cfg(feature = "anstyle")]
style: anstyle::Style,
bracket: Cell<Option<(u8, usize)>>, // memorize the character to search...
}

Expand All @@ -237,13 +240,21 @@ impl MatchingBracketHighlighter {
#[must_use]
pub fn new() -> Self {
Self {
#[cfg(feature = "anstyle")]
style: anstyle::Style::new()
.bold()
.fg_color(Some(anstyle::AnsiColor::Blue.into())),
bracket: Cell::new(None),
}
}
}

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

#[cfg(any(not(feature = "split-highlight"), feature = "ansi-str"))]
fn highlight<'l>(&self, line: &'l str, _pos: usize) -> Cow<'l, str> {
if line.len() <= 1 {
return Borrowed(line);
Expand All @@ -259,6 +270,23 @@ impl Highlighter for MatchingBracketHighlighter {
Borrowed(line)
}

#[cfg(all(feature = "split-highlight", not(feature = "ansi-str")))]
fn highlight_line<'l>(&self, line: &'l str, _pos: usize) -> Vec<(Self::Style, &'l str)> {
if line.len() <= 1 {
return vec![];
}
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..]),
];
}
}
vec![]
}

fn highlight_char(&self, line: &str, pos: usize, forced: bool) -> bool {
if forced {
self.bracket.set(None);
Expand Down
8 changes: 4 additions & 4 deletions src/tty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,14 @@ pub trait Renderer {

/// Display `prompt`, line and cursor in terminal output
#[allow(clippy::too_many_arguments)]
fn refresh_line(
fn refresh_line<H: Highlighter>(
&mut self,
prompt: &str,
line: &LineBuffer,
hint: Option<&str>,
old_layout: &Layout,
new_layout: &Layout,
highlighter: Option<&dyn Highlighter>,
highlighter: Option<&H>,
) -> Result<()>;

/// Compute layout for rendering prompt + line + some info (either hint,
Expand Down Expand Up @@ -126,14 +126,14 @@ impl<'a, R: Renderer + ?Sized> Renderer for &'a mut R {
(**self).move_cursor(old, new)
}

fn refresh_line(
fn refresh_line<H: Highlighter>(
&mut self,
prompt: &str,
line: &LineBuffer,
hint: Option<&str>,
old_layout: &Layout,
new_layout: &Layout,
highlighter: Option<&dyn Highlighter>,
highlighter: Option<&H>,
) -> Result<()> {
(**self).refresh_line(prompt, line, hint, old_layout, new_layout, highlighter)
}
Expand Down
4 changes: 2 additions & 2 deletions src/tty/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,14 +100,14 @@ impl Renderer for Sink {
Ok(())
}

fn refresh_line(
fn refresh_line<H: Highlighter>(
&mut self,
_prompt: &str,
_line: &LineBuffer,
_hint: Option<&str>,
_old_layout: &Layout,
_new_layout: &Layout,
_highlighter: Option<&dyn Highlighter>,
_highlighter: Option<&H>,
) -> Result<()> {
Ok(())
}
Expand Down
25 changes: 19 additions & 6 deletions src/tty/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use utf8parse::{Parser, Receiver};

use super::{width, Event, RawMode, RawReader, Renderer, Term};
use crate::config::{Behavior, BellStyle, ColorMode, Config};
use crate::highlight::Highlighter;
use crate::highlight::{Highlighter, Style};

Check failure on line 30 in src/tty/unix.rs

View workflow job for this annotation

GitHub Actions / Test min versions

unresolved import `crate::highlight::Style`
use crate::keys::{KeyCode as K, KeyEvent, KeyEvent as E, Modifiers as M};
use crate::layout::{Layout, Position};
use crate::line_buffer::LineBuffer;
Expand Down Expand Up @@ -979,14 +979,14 @@ impl Renderer for PosixRenderer {
Ok(())
}

fn refresh_line(
fn refresh_line<H: Highlighter>(
&mut self,
prompt: &str,
line: &LineBuffer,
hint: Option<&str>,
old_layout: &Layout,
new_layout: &Layout,
highlighter: Option<&dyn Highlighter>,
highlighter: Option<&H>,
) -> Result<()> {
use std::fmt::Write;
self.buffer.clear();
Expand All @@ -1002,8 +1002,21 @@ impl Renderer for PosixRenderer {
self.buffer
.push_str(&highlighter.highlight_prompt(prompt, default_prompt));
// display the input line
self.buffer
.push_str(&highlighter.highlight(line, line.pos()));
cfg_if::cfg_if! {
if #[cfg(not(feature = "split-highlight"))] {
self.buffer
.push_str(&highlighter.highlight(line, line.pos()));
} else if #[cfg(feature = "ansi-str")] {
self.buffer
.push_str(&highlighter.highlight(line, line.pos()));
} else {
for (style, block) in highlighter.highlight_line(line, line.pos()) {
write!(self.buffer, "{}", style.start())?;
self.buffer.push_str(block);
write!(self.buffer, "{}", style.end())?;
}
}
}
} else {
// display the prompt
self.buffer.push_str(prompt);
Expand Down Expand Up @@ -1695,7 +1708,7 @@ mod test {
let new_layout = out.compute_layout(prompt_size, default_prompt, &line, None);
assert_eq!(Position { col: 1, row: 1 }, new_layout.cursor);
assert_eq!(new_layout.cursor, new_layout.end);
out.refresh_line(prompt, &line, None, &old_layout, &new_layout, None)
out.refresh_line::<()>(prompt, &line, None, &old_layout, &new_layout, None)
.unwrap();
#[rustfmt::skip]
assert_eq!(
Expand Down
4 changes: 2 additions & 2 deletions src/tty/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -429,14 +429,14 @@ impl Renderer for ConsoleRenderer {
.map(|_| ())
}

fn refresh_line(
fn refresh_line<H: Highlighter>(
&mut self,
prompt: &str,
line: &LineBuffer,
hint: Option<&str>,
old_layout: &Layout,
new_layout: &Layout,
highlighter: Option<&dyn Highlighter>,
highlighter: Option<&H>,
) -> Result<()> {
let default_prompt = new_layout.default_prompt;
let cursor = new_layout.cursor;
Expand Down

0 comments on commit cb173ff

Please sign in to comment.