Skip to content

Commit

Permalink
Misc
Browse files Browse the repository at this point in the history
  • Loading branch information
gwenn committed Jan 1, 2017
1 parent b42683c commit 8d6547b
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 19 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ license = "MIT"
[dependencies]
libc = "0.2"
unicode-width = "0.1"
unicode-segmentation = "1.0"

[target.'cfg(unix)'.dependencies]
nix = "0.7"
Expand Down
6 changes: 5 additions & 1 deletion src/completion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub trait Completer {
/// Updates the edited `line` with the `elected` candidate.
fn update(&self, line: &mut LineBuffer, start: usize, elected: &str) {
let end = line.pos();
line.replace(start, end, elected)
line.replace(start..end, elected)
}
}

Expand Down Expand Up @@ -60,6 +60,7 @@ use std::rc::Rc;
use std::sync::Arc;
box_completer! { Box Rc Arc }

/// A `Completer` for file and folder names.
pub struct FilenameCompleter {
break_chars: BTreeSet<char>,
}
Expand Down Expand Up @@ -121,6 +122,9 @@ pub fn unescape(input: &str, esc_char: Option<char>) -> Cow<str> {
Owned(result)
}

/// Escape any `break_chars` in `input` string with `esc_char`.
/// For example, '/User Information' becomes '/User\ Information'
/// when space is a breaking char and '\' the escape char.
pub fn escape(input: String, esc_char: Option<char>, break_chars: &BTreeSet<char>) -> String {
if esc_char.is_none() {
return input;
Expand Down
8 changes: 7 additions & 1 deletion src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub struct Config {
completion_prompt_limit: usize,
/// Duration (milliseconds) Rustyline will wait for a character when reading an ambiguous key sequence.
keyseq_timeout: i32,
// Emacs or Vi mode
edit_mode: EditMode,
}

Expand Down Expand Up @@ -131,17 +132,22 @@ impl Builder {
self
}

/// The number of possible completions that determines when the user is asked
/// whether the list of possibilities should be displayed.
pub fn completion_prompt_limit(mut self, completion_prompt_limit: usize) -> Builder {
self.p.completion_prompt_limit = completion_prompt_limit;
self
}

/// Set `keyseq_timeout` in milliseconds.
/// Timeout for ambiguous key sequences in milliseconds.
/// Currently, it is used only to distinguish a single ESC from an ESC sequence.
/// After seeing an ESC key, wait at most `keyseq_timeout_ms` for another byte.
pub fn keyseq_timeout(mut self, keyseq_timeout_ms: i32) -> Builder {
self.p.keyseq_timeout = keyseq_timeout_ms;
self
}

/// Choose between Emacs or Vi mode.
pub fn edit_mode(mut self, edit_mode: EditMode) -> Builder {
self.p.edit_mode = edit_mode;
self
Expand Down
15 changes: 8 additions & 7 deletions src/keymap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,12 @@ impl EditState {
}
}

fn digit_argument<R: RawReader>(&mut self,
rdr: &mut R,
config: &Config,
digit: char)
-> Result<KeyPress> {
// TODO dynamic prompt (arg: ?)
fn emacs_digit_argument<R: RawReader>(&mut self,
rdr: &mut R,
config: &Config,
digit: char)
-> Result<KeyPress> {
match digit {
'0'...'9' => {
self.num_args = digit.to_digit(10).unwrap() as i16;
Expand All @@ -139,9 +140,9 @@ impl EditState {
fn emacs<R: RawReader>(&mut self, rdr: &mut R, config: &Config) -> Result<Cmd> {
let mut key = try!(rdr.next_key(config.keyseq_timeout()));
if let KeyPress::Meta(digit @ '-') = key {
key = try!(self.digit_argument(rdr, config, digit));
key = try!(self.emacs_digit_argument(rdr, config, digit));
} else if let KeyPress::Meta(digit @ '0'...'9') = key {
key = try!(self.digit_argument(rdr, config, digit));
key = try!(self.emacs_digit_argument(rdr, config, digit));
}
let cmd = match key {
KeyPress::Char(c) => Cmd::SelfInsert(c),
Expand Down
14 changes: 8 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@
#![allow(unknown_lints)]

extern crate libc;
extern crate unicode_segmentation;
extern crate unicode_width;
#[cfg(unix)]
extern crate nix;
extern crate unicode_width;
#[cfg(windows)]
extern crate winapi;
#[cfg(windows)]
Expand All @@ -43,6 +44,8 @@ use std::io::{self, Write};
use std::mem;
use std::path::Path;
use std::result;
use unicode_width::{UnicodeWidthChar, UnicodeWidthStr};

use tty::{RawMode, RawReader, Terminal, Term};

use completion::{Completer, longest_common_prefix};
Expand Down Expand Up @@ -288,7 +291,7 @@ fn calculate_position(s: &str, orig: Position, cols: usize) -> Position {
pos.row += 1;
None
} else {
unicode_width::UnicodeWidthChar::width(c)
c.width()
};
if let Some(cw) = cw {
pos.col += cw;
Expand All @@ -309,7 +312,7 @@ fn calculate_position(s: &str, orig: Position, cols: usize) -> Position {
fn edit_insert(s: &mut State, ch: char, count: u16) -> Result<()> {
if let Some(push) = s.line.insert(ch) {
if push {
if s.cursor.col + unicode_width::UnicodeWidthChar::width(ch).unwrap_or(0) < s.cols {
if s.cursor.col + ch.width().unwrap_or(0) < s.cols {
// Avoid a full update of the line in the trivial case.
let cursor = calculate_position(&s.line[..s.line.pos()], s.prompt_size, s.cols);
s.cursor = cursor;
Expand Down Expand Up @@ -665,12 +668,11 @@ fn page_completions<R: RawReader>(rdr: &mut R,
candidates: &[String])
-> Result<Option<Cmd>> {
use std::cmp;
use unicode_width::UnicodeWidthStr;

let min_col_pad = 2;
let max_width = cmp::min(s.cols,
candidates.into_iter()
.map(|s| UnicodeWidthStr::width(s.as_str()))
.map(|s| s.as_str().width())
.max()
.unwrap() + min_col_pad);
let num_cols = s.cols / max_width;
Expand Down Expand Up @@ -711,7 +713,7 @@ fn page_completions<R: RawReader>(rdr: &mut R,
if i < candidates.len() {
let candidate = &candidates[i];
ab.push_str(candidate);
let width = UnicodeWidthStr::width(candidate.as_str());
let width = candidate.as_str().width();
if ((col + 1) * num_rows) + row < candidates.len() {
for _ in width..max_width {
ab.push(' ');
Expand Down
7 changes: 4 additions & 3 deletions src/line_buffer.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! Line buffer with current cursor position
use std::ops::Deref;
use std::ops::{Deref, Range};
use keymap::{Anchor, At, CharSearch, Word};

/// Maximum buffer size for the line read
Expand Down Expand Up @@ -568,8 +568,9 @@ impl LineBuffer {
}

/// Replaces the content between [`start`..`end`] with `text` and positions the cursor to the end of text.
pub fn replace(&mut self, start: usize, end: usize, text: &str) {
self.buf.drain(start..end);
pub fn replace(&mut self, range: Range<usize>, text: &str) {
let start = range.start;
self.buf.drain(range);
self.insert_str(start, text);
self.pos = start + text.len();
}
Expand Down
4 changes: 3 additions & 1 deletion src/tty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ use std::io::Write;
use ::Result;
use consts::KeyPress;

/// Terminal state
pub trait RawMode: Copy + Sized {
/// Disable RAW mode for the terminal.
fn disable_raw_mode(&self) -> Result<()>;
}

/// Translate bytes read from stdin to keys.
pub trait RawReader: Sized {
/// Blocking read of key pressed.
fn next_key(&mut self, timeout_ms: i32) -> Result<KeyPress>;
Expand All @@ -20,7 +22,7 @@ pub trait RawReader: Sized {
pub trait Term: Clone {
type Reader: RawReader;
type Writer: Write;
type Mode;
type Mode: RawMode;

fn new() -> Self;
/// Check if current terminal can provide a rich line-editing user interface.
Expand Down

0 comments on commit 8d6547b

Please sign in to comment.