Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into cursor_location
Browse files Browse the repository at this point in the history
  • Loading branch information
gwenn committed Jan 5, 2025
2 parents f655a5a + 5910f9e commit 7107c7b
Show file tree
Hide file tree
Showing 26 changed files with 398 additions and 417 deletions.
40 changes: 29 additions & 11 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "rustyline"
version = "14.0.0"
version = "15.0.0"
authors = ["Katsu Kawakami <kkawa1570@gmail.com>"]
edition = "2021"
description = "Rustyline, a readline implementation based on Antirez's Linenoise"
Expand All @@ -11,10 +11,7 @@ keywords = ["readline"]
license = "MIT"
categories = ["command-line-interface"]

exclude = [
"/.github/*",
"/rustfmt.toml",
]
exclude = ["/.github/*", "/rustfmt.toml"]

[badges]
maintenance = { status = "actively-developed" }
Expand All @@ -29,28 +26,43 @@ cfg-if = "1.0"
home = { version = "0.5.4", optional = true }
# For History
fd-lock = { version = "4.0.0", optional = true }
rusqlite = { version = "0.32.0", optional = true, default-features = false, features = ["bundled", "backup"] }
rusqlite = { version = "0.32.0", optional = true, default-features = false, features = [
"bundled",
"backup",
] }
libc = "0.2.155"
log = "0.4.22"
unicode-width = "0.1.13"
unicode-width = "0.2.0"
unicode-segmentation = "1.0"
memchr = "2.7"
# For custom bindings
radix_trie = { version = "0.2", optional = true }
regex = { version = "1.10", optional = true }
# For derive
rustyline-derive = { version = "0.10.0", optional = true, path = "rustyline-derive" }
rustyline-derive = { version = "0.11.0", optional = true, path = "rustyline-derive" }

[target.'cfg(unix)'.dependencies]
nix = { version = "0.29", default-features = false, features = ["fs", "ioctl", "poll", "signal", "term"] }
nix = { version = "0.29", default-features = false, features = [
"fs",
"ioctl",
"poll",
"signal",
"term",
] }
utf8parse = "0.2"
skim = { version = "0.10", optional = true, default-features = false }
signal-hook = { version = "0.3", optional = true, default-features = false }
termios = { version = "0.3.3", optional = true }
buffer-redux = { version = "1.0", optional = true, default-features = false }

[target.'cfg(windows)'.dependencies]
windows-sys = { version = "0.59.0", features = ["Win32_Foundation", "Win32_System_Console", "Win32_Security", "Win32_System_Threading", "Win32_UI_Input_KeyboardAndMouse"] }
windows-sys = { version = "0.59.0", features = [
"Win32_Foundation",
"Win32_System_Console",
"Win32_Security",
"Win32_System_Threading",
"Win32_UI_Input_KeyboardAndMouse",
] }
clipboard-win = "5.0"

[dev-dependencies]
Expand Down Expand Up @@ -96,7 +108,13 @@ name = "sqlite_history"
required-features = ["with-sqlite-history"]

[package.metadata.docs.rs]
features = ["custom-bindings", "derive", "with-dirs", "with-file-history", "with-fuzzy"]
features = [
"custom-bindings",
"derive",
"with-dirs",
"with-file-history",
"with-fuzzy",
]
all-features = false
no-default-features = true
default-target = "x86_64-unknown-linux-gnu"
Expand Down
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ to your `Cargo.toml`:

```toml
[dependencies]
rustyline = "14.0.0"
rustyline = "15.0.0"
```

## Features
Expand Down Expand Up @@ -188,7 +188,7 @@ For all modes:

[Readline vi Editing Mode Cheat Sheet](http://www.catonmat.net/download/bash-vi-editing-mode-cheat-sheet.pdf)

[Terminal codes (ANSI/VT100)](http://wiki.bash-hackers.org/scripting/terminalcodes)
[ANSI escape code](https://en.wikipedia.org/wiki/ANSI_escape_code)

## Wine

Expand Down Expand Up @@ -252,3 +252,7 @@ literal newline to be added to the input buffer.
The way to achieve multi-line editing is to implement the `Validator`
trait.
## Minimum supported Rust version (MSRV)
Latest stable Rust version at the time of release. It might compile with older versions.
6 changes: 3 additions & 3 deletions examples/example.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::borrow::Cow::{self, Borrowed, Owned};

use rustyline::completion::FilenameCompleter;
use rustyline::error::ReadlineError;
use rustyline::highlight::{Highlighter, MatchingBracketHighlighter};
use rustyline::highlight::{CmdKind, Highlighter, MatchingBracketHighlighter};
use rustyline::hint::HistoryHinter;
use rustyline::validate::MatchingBracketValidator;
use rustyline::{Cmd, CompletionType, Config, EditMode, Editor, KeyEvent};
Expand Down Expand Up @@ -41,8 +41,8 @@ impl Highlighter for MyHelper {
self.highlighter.highlight(line, pos)
}

fn highlight_char(&self, line: &str, pos: usize, forced: bool) -> bool {
self.highlighter.highlight_char(line, pos, forced)
fn highlight_char(&self, line: &str, pos: usize, kind: CmdKind) -> bool {
self.highlighter.highlight_char(line, pos, kind)
}
}

Expand Down
10 changes: 7 additions & 3 deletions examples/read_password.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::borrow::Cow::{self, Borrowed, Owned};

use rustyline::config::Configurer;
use rustyline::highlight::Highlighter;
use rustyline::highlight::{CmdKind, Highlighter};
use rustyline::{ColorMode, Editor, Result};
use rustyline::{Completer, Helper, Hinter, Validator};

Expand All @@ -20,12 +20,16 @@ impl Highlighter for MaskingHighlighter {
}
}

fn highlight_char(&self, _line: &str, _pos: usize, _forced: bool) -> bool {
self.masking
fn highlight_char(&self, _line: &str, _pos: usize, kind: CmdKind) -> bool {
match kind {
CmdKind::MoveCursor => false,
_ => self.masking,
}
}
}

fn main() -> Result<()> {
env_logger::init();
println!("This is just a hack. Reading passwords securely requires more than that.");
let h = MaskingHighlighter { masking: false };
let mut rl = Editor::new()?;
Expand Down
9 changes: 7 additions & 2 deletions rustyline-derive/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "rustyline-derive"
version = "0.10.0"
version = "0.11.0"
authors = ["gwenn"]
edition = "2018"
description = "Rustyline macros implementation of #[derive(Completer, Helper, Hinter, Highlighter)]"
Expand All @@ -19,6 +19,11 @@ maintenance = { status = "actively-developed" }
proc-macro = true

[dependencies]
syn = { version = "2.0.72", default-features = false, features = ["derive", "parsing", "printing", "proc-macro"] }
syn = { version = "2.0.72", default-features = false, features = [
"derive",
"parsing",
"printing",
"proc-macro",
] }
quote = { version = "1.0.36", default-features = false }
proc-macro2 = { version = "1.0.86", default-features = false }
6 changes: 3 additions & 3 deletions rustyline-derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ fn get_field_by_attr<'a>(data: &'a Data, ident: &str) -> Option<(usize, &'a Fiel
attr.path().is_ident("rustyline")
&& attr
.parse_args::<Path>()
.map_or(false, |arg| arg.is_ident(ident))
.is_ok_and(|arg| arg.is_ident(ident))
})
});

Expand Down Expand Up @@ -126,8 +126,8 @@ pub fn highlighter_macro_derive(input: TokenStream) -> TokenStream {
::rustyline::highlight::Highlighter::highlight_candidate(&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(&self, line: &str, pos: usize, kind: ::rustyline::highlight::CmdKind) -> bool {
::rustyline::highlight::Highlighter::highlight_char(&self.#field_name_or_index, line, pos, kind)
}
}
}
Expand Down
7 changes: 3 additions & 4 deletions src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::complete_hint_line;
use crate::config::Config;
use crate::edit::State;
use crate::error;
use crate::highlight::CmdKind;
use crate::history::SearchDirection;
use crate::keymap::{Anchor, At, Cmd, Movement, Word};
use crate::keymap::{InputState, Refresher};
Expand All @@ -28,9 +29,7 @@ pub fn execute<H: Helper>(
if s.has_hint() || !s.is_default_prompt() || s.highlight_char {
// Force a refresh without hints to leave the previous
// line as the user typed it after a newline.
s.forced_refresh = true;
s.refresh_line_with_msg(None)?;
s.forced_refresh = false;
s.refresh_line_with_msg(None, CmdKind::ForcedRefresh)?;
}
}
_ => {}
Expand Down Expand Up @@ -190,7 +189,7 @@ pub fn execute<H: Helper>(
}
Cmd::Move(Movement::EndOfBuffer) => {
// Move to the end of the buffer.
s.edit_move_buffer_end()?;
s.edit_move_buffer_end(CmdKind::MoveCursor)?;
}
Cmd::DowncaseWord => {
// lowercase word after point
Expand Down
80 changes: 29 additions & 51 deletions src/completion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,44 +14,13 @@ pub trait Candidate {
fn replacement(&self) -> &str;
}

impl Candidate for String {
impl<T: AsRef<str>> Candidate for T {
fn display(&self) -> &str {
self.as_str()
self.as_ref()
}

fn replacement(&self) -> &str {
self.as_str()
}
}

/// #[deprecated = "Unusable"]
impl Candidate for str {
fn display(&self) -> &str {
self
}

fn replacement(&self) -> &str {
self
}
}

impl Candidate for &'_ str {
fn display(&self) -> &str {
self
}

fn replacement(&self) -> &str {
self
}
}

impl Candidate for Rc<str> {
fn display(&self) -> &str {
self
}

fn replacement(&self) -> &str {
self
self.as_ref()
}
}

Expand Down Expand Up @@ -113,22 +82,6 @@ impl Completer for () {
}
}

impl<'c, C: ?Sized + Completer> Completer for &'c 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 update(&self, line: &mut LineBuffer, start: usize, elected: &str, cl: &mut Changeset) {
(**self).update(line, start, elected, cl);
}
}
macro_rules! box_completer {
($($id: ident)*) => {
$(
Expand Down Expand Up @@ -211,7 +164,6 @@ impl FilenameCompleter {
/// partial path to be completed.
pub fn complete_path(&self, line: &str, pos: usize) -> Result<(usize, Vec<Pair>)> {
let (start, mut matches) = self.complete_path_unsorted(line, pos)?;
#[allow(clippy::unnecessary_sort_by)]
matches.sort_by(|a, b| a.display().cmp(b.display()));
Ok((start, matches))
}
Expand Down Expand Up @@ -415,6 +367,7 @@ fn normalize(s: &str) -> Cow<str> {

/// Given a `line` and a cursor `pos`ition,
/// try to find backward the start of a word.
///
/// Return (0, `line[..pos]`) if no break char has been found.
/// Return the word and its start position (idx, `line[idx..pos]`) otherwise.
#[must_use]
Expand Down Expand Up @@ -543,6 +496,8 @@ fn find_unclosed_quote(s: &str) -> Option<(usize, Quote)> {

#[cfg(test)]
mod tests {
use super::{Completer, FilenameCompleter};

#[test]
pub fn extract_word() {
let break_chars = super::default_break_chars;
Expand Down Expand Up @@ -647,4 +602,27 @@ mod tests {
pub fn normalize() {
assert_eq!(super::normalize("Windows"), "windows")
}

#[test]
pub fn candidate_impls() {
struct StrCmp;
impl Completer for StrCmp {
type Candidate = &'static str;
}
struct RcCmp;
impl Completer for RcCmp {
type Candidate = std::rc::Rc<str>;
}
struct ArcCmp;
impl Completer for ArcCmp {
type Candidate = std::sync::Arc<str>;
}
}

#[test]
pub fn completer_impls() {
struct Wrapper<T: Completer>(T);
let boxed = Box::new(FilenameCompleter::new());
let _ = Wrapper(boxed);
}
}
Loading

0 comments on commit 7107c7b

Please sign in to comment.