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

Use lookup tables instead of linear search with memchr #625

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
19 changes: 15 additions & 4 deletions src/completion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use std::path::{self, Path};

use crate::line_buffer::LineBuffer;
use crate::{Context, Result};
use memchr::memchr;

/// A completion candidate.
pub trait Candidate {
Expand Down Expand Up @@ -289,9 +288,15 @@ pub fn escape(
if quote == Quote::Single {
return input; // no escape in single quotes
}

let mut break_chars_byteset = [false; 256];
for &byte in break_chars {
break_chars_byteset[usize::from(byte)] = true;
}

let n = input
.bytes()
.filter(|b| memchr(*b, break_chars).is_some())
.filter(|&b| break_chars_byteset[usize::from(b)])
.count();
if n == 0 {
return input; // no need to escape
Expand All @@ -308,7 +313,7 @@ pub fn escape(
let mut result = String::with_capacity(input.len() + n);

for c in input.chars() {
if c.is_ascii() && memchr(c as u8, break_chars).is_some() {
if c.is_ascii() && break_chars_byteset[c as usize] {
result.push(esc_char);
}
result.push(c);
Expand Down Expand Up @@ -418,6 +423,12 @@ pub fn extract_word<'l>(
if line.is_empty() {
return (0, line);
}

let mut break_chars_byteset = [false; 256];
for &byte in break_chars {
break_chars_byteset[usize::from(byte)] = true;
}

let mut start = None;
for (i, c) in line.char_indices().rev() {
if let (Some(esc_char), true) = (esc_char, start.is_some()) {
Expand All @@ -428,7 +439,7 @@ pub fn extract_word<'l>(
}
break;
}
if c.is_ascii() && memchr(c as u8, break_chars).is_some() {
if c.is_ascii() && break_chars_byteset[c as usize] {
start = Some(i + c.len_utf8());
if esc_char.is_none() {
break;
Expand Down
8 changes: 2 additions & 6 deletions src/highlight.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//! Syntax highlighting

use crate::config::CompletionType;
use memchr::memchr;
use std::borrow::Cow::{self, Borrowed, Owned};
use std::cell::Cell;

Expand Down Expand Up @@ -91,9 +90,6 @@ impl<'r, H: ?Sized + Highlighter> Highlighter for &'r H {
}
}

const OPENS: &[u8; 3] = b"{[(";
const CLOSES: &[u8; 3] = b"}])";

// TODO versus https://python-prompt-toolkit.readthedocs.io/en/master/pages/reference.html?highlight=HighlightMatchingBracketProcessor#prompt_toolkit.layout.processors.HighlightMatchingBracketProcessor

/// Highlight matching bracket when typed or cursor moved on.
Expand Down Expand Up @@ -225,10 +221,10 @@ const fn matching_bracket(bracket: u8) -> u8 {
}
}
fn is_open_bracket(bracket: u8) -> bool {
memchr(bracket, OPENS).is_some()
matches!(bracket, b'{' | b'[' | b'(')
}
fn is_close_bracket(bracket: u8) -> bool {
memchr(bracket, CLOSES).is_some()
matches!(bracket, b'}' | b']' | b')')
}

#[cfg(test)]
Expand Down