Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
FroVolod authored Dec 27, 2023
2 parents e59ee39 + 2575ad1 commit c24c370
Show file tree
Hide file tree
Showing 27 changed files with 1,049 additions and 537 deletions.
15 changes: 10 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,25 @@
- Expand workflow clippy task to lint all-features in workspace.
- Add docs badge to readme.
- **Breaking** The Select and Multiselect Filter now scores input and is now expected to return an `Option<i64>`, making it possible to order/rank the list of options. [#176](https://github.com/mikaelmello/inquire/pull/176)
`None`: Will not be displayed in the list of options.
`Some(score)`: score determines the order of options, higher score, higher on the list of options.
`None`: Will not be displayed in the list of options.
`Some(score)`: score determines the order of options, higher score, higher on the list of options.
- Implement fuzzy search as default on Select and MultiSelect prompts. [#176](https://github.com/mikaelmello/inquire/pull/176)
- Add new option on Select/MultiSelect prompts allowing to reset selection to the first item on filter-input changes. [#176](https://github.com/mikaelmello/inquire/pull/176)
- Emacs-like keybindings added where applicable:
- Ctrl-p/Ctrl-n for up/down
- Ctrl-b/Ctrl-f for left/right
- Ctrl-j/Ctrl-g for enter/cancel
- Ctrl-p/Ctrl-n for up/down
- Ctrl-b/Ctrl-f for left/right
- Ctrl-j/Ctrl-g for enter/cancel
- Added 'with_starting_filter_input' to both Select and MultiSelect, which allows for setting an initial value to the filter section of the prompt.
- Added starting_input for CustomType. [#194](https://github.com/mikaelmello/inquire/pull/194)
- Added 'without_filtering' to both Select and MultiSelect, useful when you want to simplify the UX if the filter does not add any value, such as when the list is already short.
- Added 'with_answered_prompt_prefix' to RenderConfig to allow customization of answered prompt prefix.
- Revamped keybindings for DateSelect.


### Fixes

- Fixed typos in the code's comments.
- Fixed issue where inquire, using termion, would crash when receiving piped inputs.

### Dependency changes (some breaking)

Expand Down
5 changes: 4 additions & 1 deletion inquire/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,10 @@ impl From<CustomUserError> for InquireError {

impl From<io::Error> for InquireError {
fn from(err: io::Error) -> Self {
InquireError::IO(err)
match err.raw_os_error() {
Some(25 | 6) => InquireError::NotTTY,
_ => InquireError::IO(err),
}
}
}

Expand Down
75 changes: 45 additions & 30 deletions inquire/src/prompts/dateselect/action.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,38 +30,53 @@ pub enum DateSelectPromptAction {
impl InnerAction for DateSelectPromptAction {
type Config = DateSelectConfig;

fn from_key(key: Key, config: &DateSelectConfig) -> Option<Self> {
if config.vim_mode {
let action = match key {
Key::Char('k', KeyModifiers::NONE) => Some(Self::GoToPrevWeek),
Key::Char('j', KeyModifiers::NONE) => Some(Self::GoToNextWeek),
Key::Char('h', KeyModifiers::NONE) => Some(Self::GoToPrevDay),
Key::Char('l', KeyModifiers::NONE) => Some(Self::GoToNextDay),
_ => None,
};
fn from_key(key: Key, _: &DateSelectConfig) -> Option<Self> {
let action = match key {
Key::Left(KeyModifiers::NONE) // standard
| Key::Char('b', KeyModifiers::CONTROL) // emacs
| Key::Char('h', KeyModifiers::NONE) // vim
=> Self::GoToPrevDay,

if action.is_some() {
return action;
}
}
Key::Right(KeyModifiers::NONE) // standard
| Key::Char('f', KeyModifiers::CONTROL) // emacs
| Key::Char('l', KeyModifiers::NONE) // vim
=> Self::GoToNextDay,

Key::Up(KeyModifiers::NONE) // standard
| Key::Char('p', KeyModifiers::CONTROL) // emacs
| Key::Char('k', KeyModifiers::NONE) // vim
=> Self::GoToPrevWeek,

Key::Down(KeyModifiers::NONE) // standard
| Key::Char('n', KeyModifiers::CONTROL) // emacs
| Key::Char('j', KeyModifiers::NONE) // vim
| Key::Tab // not sure? keeping it for compatibility reasons now
=> Self::GoToNextWeek,

Key::PageUp(KeyModifiers::NONE) // standard
| Key::Char('[', KeyModifiers::NONE) // alternative when page up is not available
| Key::Left(_) // alternative 2, when the left above with no modifiers is not matched
| Key::Char('v' | 'V', KeyModifiers::ALT | KeyModifiers::META) // emacs
| Key::Char('b' | 'B', _) // vim, ideally ctrl-b should be used, but it's not available due to emacs
=> Self::GoToPrevMonth,

Key::PageDown(KeyModifiers::NONE) // standard
| Key::Char(']', KeyModifiers::NONE) // alternative when page down is not available
| Key::Right(_) // alternative 2, when the right above with no modifiers is not matched
| Key::Char('v' | 'V', KeyModifiers::CONTROL) // emacs
| Key::Char('f' | 'F', _) // vim, ideally ctrl-f should be used, but it's not available due to emacs
=> Self::GoToNextMonth,

Key::PageUp(_) // standard, when the above with no modifiers is not matched
| Key::Char('{' | '[', _) // alternative when page up is not available
| Key::Up(_) // alternative 2, when the up above with no modifiers is not matched
=> Self::GoToPrevYear,

Key::PageDown(_) // standard, when the above with no modifiers is not matched
| Key::Char('}' | ']', _) // alternative when page down is not available
| Key::Down(_) // alternative 2, when the down above with no modifiers is not matched
=> Self::GoToNextYear,

let action = match key {
Key::Left(KeyModifiers::NONE) | Key::Char('b', KeyModifiers::CONTROL) => {
Self::GoToPrevDay
}
Key::Right(KeyModifiers::NONE) | Key::Char('f', KeyModifiers::CONTROL) => {
Self::GoToNextDay
}
Key::Up(KeyModifiers::NONE) | Key::Char('p', KeyModifiers::CONTROL) => {
Self::GoToPrevWeek
}
Key::Down(KeyModifiers::NONE) | Key::Char('n', KeyModifiers::CONTROL) | Key::Tab => {
Self::GoToNextWeek
}
Key::Left(KeyModifiers::CONTROL) => Self::GoToPrevMonth,
Key::Right(KeyModifiers::CONTROL) => Self::GoToNextMonth,
Key::Up(KeyModifiers::CONTROL) => Self::GoToPrevYear,
Key::Down(KeyModifiers::CONTROL) => Self::GoToNextYear,
_ => return None,
};

Expand Down
2 changes: 1 addition & 1 deletion inquire/src/prompts/dateselect/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::DateSelect;
/// Configuration settings used in the execution of a DateSelectPrompt.
#[derive(Copy, Clone, Debug)]
pub struct DateSelectConfig {
/// Whether to use vim-style keybindings.
/// Whether to support vim-style keybindings.
pub vim_mode: bool,

/// Min date allowed to be selected.
Expand Down
2 changes: 1 addition & 1 deletion inquire/src/prompts/dateselect/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ impl<'a> DateSelect<'a> {

/// Default help message.
pub const DEFAULT_HELP_MESSAGE: Option<&'a str> =
Some("arrows to move, with ctrl to move months and years, enter to select");
Some("arrows to move, []{} move months and years, enter to select");

/// Default validators added to the [DateSelect] prompt, none.
pub const DEFAULT_VALIDATORS: Vec<Box<dyn DateValidator>> = vec![];
Expand Down
39 changes: 17 additions & 22 deletions inquire/src/prompts/dateselect/prompt.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use std::{
cmp::{max, min},
cmp::{max, min, Ordering},
ops::Add,
};

use chrono::{Datelike, Duration, NaiveDate};
use chrono::{Datelike, Duration, Months, NaiveDate};

use crate::{
date_utils::{get_current_date, get_month},
Expand Down Expand Up @@ -60,27 +60,22 @@ impl<'a> DateSelectPrompt<'a> {
}

fn shift_months(&mut self, qty: i32) -> ActionResult {
let date = self.current_date;

let years = qty / 12;
let months = qty % 12;

let new_year = date.year() + years;
let cur_month = date.month0() as i32;
let mut new_month = (cur_month + months) % 12;
if new_month < 0 {
new_month += 12;
}

let new_date = date
.with_month0(new_month as u32)
.and_then(|d| d.with_year(new_year));
let new_date = match qty.cmp(&0) {
Ordering::Greater | Ordering::Equal => {
let qty_as_months = Months::new(qty as u32);
self.current_date
.checked_add_months(qty_as_months)
.unwrap_or(NaiveDate::MAX)
}
Ordering::Less => {
let qty_as_months = Months::new((-qty) as u32);
self.current_date
.checked_sub_months(qty_as_months)
.unwrap_or(NaiveDate::MIN)
}
};

if let Some(new_date) = new_date {
self.update_date(new_date)
} else {
ActionResult::Clean
}
self.update_date(new_date)
}

fn update_date(&mut self, new_date: NaiveDate) -> ActionResult {
Expand Down
Loading

0 comments on commit c24c370

Please sign in to comment.