-
Notifications
You must be signed in to change notification settings - Fork 182
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
Vi mode indicators #369
base: master
Are you sure you want to change the base?
Vi mode indicators #369
Conversation
I am not sure it is feasible but I would prefer a less intrusive change:
pub struct PromptState {
pub default: bool,
pub mode: InputMode,
}
pub trait Highlighter {
...
fn highlight_prompt<'b, 's: 'b, 'p: 'b>(
&'s self,
prompt: &'p str,
state: PromptState,
) -> Cow<'b, str> {
...
I may investigate further if I have time. |
I see. I think this is quite doable. My only concern would be that it essentially would mean that all your indicators must be the same width. This could be a bit limiting in general (I see no reason why someone shouldn't be able to use Regarding (b), is there a plan to allow for highlighting to have a different width or is it here to stay? |
Is this one more like what you were thinking? (Probably want a separate example for Vi mode, but wanted to illustrate quickly the approach.) |
The limitation |
src/tty/mod.rs
Outdated
@@ -39,6 +40,7 @@ pub trait Renderer { | |||
old_layout: &Layout, | |||
new_layout: &Layout, | |||
highlighter: Option<&dyn Highlighter>, | |||
vi_mode: Option<InputMode>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can factorize code by passing a PromptState
instead of Option<InputMode>
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I ignore dead code and unrelated changes, it looks good to me.
Maybe we should have a PrompState
trait instead of a struct ?
About the trait, are you thinking of having different implementations for vi/emacs? |
Also, I wasn't sure what your preference on example is, whether extract the common code or maybe use a more minimal example for Vi mode? Or maybe parameterize the default example with input mode? |
I would prefer you keep the default example untouched. |
Oops! |
I am not sure but it may be easier to extend the trait in the future and we already have |
examples/vi.rs
Outdated
@@ -0,0 +1,132 @@ | |||
use std::borrow::Cow::{self, Borrowed, Owned}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should have keep your example minimalist (like https://github.com/kkawakam/rustyline/blob/master/examples/read_password.rs)
src/config.rs
Outdated
@@ -2,7 +2,7 @@ | |||
use std::default::Default; | |||
|
|||
/// User preferences | |||
#[derive(Clone, Copy, Debug, PartialEq, Eq)] | |||
#[derive(Clone, Debug, PartialEq, Eq)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be reverted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 missed that.
@@ -33,6 +34,7 @@ pub struct State<'out, 'prompt, H: Helper> { | |||
pub ctx: Context<'out>, // Give access to history for `hinter` | |||
pub hint: Option<String>, // last hint displayed | |||
highlight_char: bool, // `true` if a char has been highlighted | |||
input_mode: Option<InputMode>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We may avoid to duplicate input_mode if we move InputState
in State
?
I will give a try and do it in a dedicated PR.
src/history.rs
Outdated
@@ -319,7 +319,7 @@ mod tests { | |||
#[test] | |||
fn add() { | |||
let config = Config::builder().history_ignore_space(true).build(); | |||
let mut history = History::with_config(config); | |||
let mut history = History::with_config(config.clone()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be reverted.
src/lib.rs
Outdated
@@ -784,7 +784,7 @@ impl<H: Helper> Editor<H> { | |||
); | |||
Self { | |||
term, | |||
history: History::with_config(config), | |||
history: History::with_config(config.clone()), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be reverted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your patience.
Thanks for the feedback, I'll try to push some changes soon. |
The problem with using What do you think? |
We should make |
Ok, so extracting Either way, do you want me to wait for that other PR to be merged and work on top of that? It might be easier for everyone. |
I am afraid there will be no indicator when colors are disabled ( |
There is a draft here to support dynamic prompt even if there is no highlighting. |
Thanks for the update, let me know if I can help with anything. |
rustyline doesn't currently support changing the prompt while in the core readline loop. There are a number of open PRs and issues for this functionality, but all of them appear to be stalled for more than a year. Looking at kkawakam#696 and 4ec26e8, the traditional appoach to this is to provide a reference to a trait object (`Prompt` or `ToString`), but with that appoach there's no way to cause the prompt to be redrawn for a change without user input. This means for these appoaches the prompt could change without being displayed to the user. There's an existing mechanism to allow another async task/thread to push input into the core readline loop, the `ExternalPrinter`. In this commit, I expand `ExternalPrinter` to add `set_prompt()`. With various plumbing, this function results in `wait_for_input` to return `Cmd::SetPrompt(String)`. One of key change here is `State.prompt` changes from `&str` to `String`. There is a performance hit here from the copy, but rustyline would need to prompt and receive input hundreds of times per second for the copy to have a noticable performance inpact. Added examples/dynamic_prompt.rs to demonstrate the functionality. Closes kkawakam#417 Related kkawakam#208, kkawakam#372, kkawakam#369, kkawakam#417, kkawakam#598, kkawakam#696
My first take on #208
I personally agree with @AdminXVII that it would be nice to have a line cursor, maybe behind an option if there are support concerns. But I wasn't sure how to do that, so I started off with this.
I realize it's not finished yet (for one, I haven't included any unit test that work with the indicators) but I figured it would be nice to get some feedback to see if I'm going the right direction.