1use std::borrow::Cow;
4use std::collections::{HashMap, VecDeque};
5use std::io;
6use std::mem::replace;
7use std::ops::{Deref, DerefMut};
8use std::path::{Path, PathBuf};
9use std::slice;
10use std::sync::{Arc, MutexGuard};
11use std::time::{Duration, Instant};
12
13use mortal::SequenceMap;
14
15use crate::command::{Category, Command};
16use crate::complete::{Completer, Completion, DummyCompleter};
17use crate::function::Function;
18use crate::inputrc::{parse_file, Directive};
19use crate::interface::Interface;
20use crate::prompter::Prompter;
21use crate::sys::path::{env_init_file, system_init_file, user_init_file};
22use crate::terminal::{RawRead, Signal, SignalSet, Size, Terminal, TerminalReader};
23use crate::util::{first_char, match_name};
24use crate::variables::{Variable, VariableIter, Variables};
25
26pub const STRING_CHARS: &str = "\"'";
28
29pub const WORD_BREAK_CHARS: &str = " \t\n\"\\'`@$><=;|&{(";
31
32pub const START_INVISIBLE: char = '\x01';
34
35pub const END_INVISIBLE: char = '\x02';
37
38const MAX_KILLS: usize = 10;
40
41pub struct Reader<'a, Term: 'a + Terminal> {
52 iface: &'a Interface<Term>,
53 lock: ReadLock<'a, Term>,
54}
55
56pub(crate) struct Read<Term: Terminal> {
57 pub application: Cow<'static, str>,
59
60 pub input_buffer: Vec<u8>,
62 pub macro_buffer: String,
64
65 pub bindings: SequenceMap<Cow<'static, str>, Command>,
66 pub functions: HashMap<Cow<'static, str>, Arc<dyn Function<Term>>>,
67
68 pub sequence: String,
70 pub input_accepted: bool,
72
73 pub overwrite_mode: bool,
75 pub overwritten_append: usize,
77 pub overwritten_chars: String,
79
80 pub completer: Arc<dyn Completer<Term>>,
82 pub completion_append_character: Option<char>,
84 pub completions: Option<Vec<Completion>>,
86 pub completion_index: usize,
88 pub completion_start: usize,
90 pub completion_prefix: usize,
92 pub completion_display_prefix: usize,
94 pub highlight_completions: bool,
96
97 pub string_chars: Cow<'static, str>,
98 pub word_break: Cow<'static, str>,
99
100 pub last_cmd: Category,
101 pub last_yank: Option<(usize, usize)>,
102 pub kill_ring: VecDeque<String>,
103
104 pub catch_signals: bool,
105 pub ignore_signals: SignalSet,
106 pub report_signals: SignalSet,
107 pub last_resize: Option<Size>,
108 pub last_signal: Option<Signal>,
109
110 variables: Variables,
111
112 pub state: InputState,
113 pub max_wait_duration: Option<Duration>,
114}
115
116pub(crate) struct ReadLock<'a, Term: 'a + Terminal> {
117 term: Box<dyn TerminalReader<Term> + 'a>,
118 data: MutexGuard<'a, Read<Term>>,
119}
120
121#[derive(Debug)]
125pub enum ReadResult {
126 Eof,
128 Input(String),
130 Signal(Signal),
132}
133
134#[derive(Copy, Clone, Debug)]
135pub(crate) enum InputState {
136 Inactive,
137 NewSequence,
138 ContinueSequence { expiry: Option<Instant> },
139 Number,
140 CharSearch { n: usize, backward: bool },
141 TextSearch,
142 CompleteIntro,
143 CompleteMore(usize),
144 QuotedInsert(usize),
145}
146
147impl<'a, Term: 'a + Terminal> Reader<'a, Term> {
148 pub(crate) fn new(iface: &'a Interface<Term>, lock: ReadLock<'a, Term>) -> Reader<'a, Term> {
149 Reader { iface, lock }
150 }
151
152 pub fn read_line(&mut self) -> io::Result<ReadResult> {
168 loop {
169 if let Some(res) = self.read_line_step(None)? {
170 return Ok(res);
171 }
172 }
173 }
174
175 pub fn read_line_step(&mut self, timeout: Option<Duration>) -> io::Result<Option<ReadResult>> {
193 self.initialize_read_line()?;
194
195 let state = self.prepare_term()?;
196 let res = self.read_line_step_impl(timeout);
197 self.lock.term.restore(state)?;
198
199 res
200 }
201
202 pub fn cancel_read_line(&mut self) -> io::Result<()> {
215 self.end_read_line()
216 }
217
218 fn initialize_read_line(&mut self) -> io::Result<()> {
219 if !self.lock.is_active() {
220 self.prompter().start_read_line()?;
221 }
222 Ok(())
223 }
224
225 fn read_line_step_impl(&mut self, timeout: Option<Duration>) -> io::Result<Option<ReadResult>> {
226 let do_read = if self.lock.is_input_available() {
227 self.lock
231 .term
232 .wait_for_input(Some(Duration::from_secs(0)))?
233 } else {
234 let timeout = limit_duration(timeout, self.lock.max_wait_duration);
235 self.lock.term.wait_for_input(timeout)?
236 };
237
238 if do_read {
239 self.lock.read_input()?;
240 }
241
242 if let Some(size) = self.lock.take_resize() {
243 self.handle_resize(size)?;
244 }
245
246 if let Some(sig) = self.lock.take_signal() {
247 if self.lock.report_signals.contains(sig) {
248 return Ok(Some(ReadResult::Signal(sig)));
249 }
250 if !self.lock.ignore_signals.contains(sig) {
251 self.handle_signal(sig)?;
252 }
253 }
254
255 {
257 let mut prompter = self.prompter();
258
259 prompter.check_expire_timeout()?;
260
261 let mut macro_len = prompter.read.data.macro_buffer.len();
265
266 while prompter.read.is_input_available() {
267 if let Some(ch) = prompter.read.read_char()? {
268 if let Some(r) = prompter.handle_input(ch)? {
269 prompter.end_read_line()?;
270 return Ok(Some(r));
271 }
272 }
273
274 let new_macro_len = prompter.read.data.macro_buffer.len();
275
276 if new_macro_len != 0 && new_macro_len >= macro_len {
277 break;
278 }
279
280 macro_len = new_macro_len;
281 }
282 }
283
284 Ok(None)
285 }
286
287 fn end_read_line(&mut self) -> io::Result<()> {
288 if self.lock.is_active() {
289 self.prompter().end_read_line()?;
290 }
291 Ok(())
292 }
293
294 fn prepare_term(&mut self) -> io::Result<Term::PrepareState> {
295 if self.read_next_raw() {
296 self.lock.term.prepare(true, SignalSet::new())
297 } else {
298 let mut signals = self.lock.report_signals.union(self.lock.ignore_signals);
299
300 if self.lock.catch_signals {
301 signals.insert(Signal::Interrupt);
304 }
305
306 let block_signals = !self.lock.catch_signals;
307
308 self.lock.term.prepare(block_signals, signals)
309 }
310 }
311
312 fn read_next_raw(&self) -> bool {
313 match self.lock.state {
314 InputState::QuotedInsert(_) => true,
315 _ => false,
316 }
317 }
318
319 pub fn set_buffer(&mut self, buf: &str) -> io::Result<()> {
328 if self.lock.is_active() {
329 self.prompter().set_buffer(buf)
330 } else {
331 self.iface.lock_write_data().set_buffer(buf);
332 Ok(())
333 }
334 }
335
336 pub fn set_cursor(&mut self, pos: usize) -> io::Result<()> {
344 if self.lock.is_active() {
345 self.prompter().set_cursor(pos)
346 } else {
347 self.iface.lock_write_data().set_cursor(pos);
348 Ok(())
349 }
350 }
351
352 pub fn set_prompt(&mut self, prompt: &str) -> io::Result<()> {
362 self.prompter().set_prompt(prompt)
363 }
364
365 pub fn add_history(&self, line: String) {
371 if !self.lock.is_active() {
372 self.iface.lock_write().add_history(line);
373 }
374 }
375
376 pub fn add_history_unique(&self, line: String) {
382 if !self.lock.is_active() {
383 self.iface.lock_write().add_history_unique(line);
384 }
385 }
386
387 pub fn clear_history(&self) {
393 if !self.lock.is_active() {
394 self.iface.lock_write().clear_history();
395 }
396 }
397
398 pub fn remove_history(&self, idx: usize) {
406 if !self.lock.is_active() {
407 self.iface.lock_write().remove_history(idx);
408 }
409 }
410
411 pub fn set_history_size(&self, n: usize) {
420 if !self.lock.is_active() {
421 self.iface.lock_write().set_history_size(n);
422 }
423 }
424
425 pub fn truncate_history(&self, n: usize) {
431 if !self.lock.is_active() {
432 self.iface.lock_write().truncate_history(n);
433 }
434 }
435
436 pub fn application(&self) -> &str {
438 &self.lock.application
439 }
440
441 pub fn set_application<T>(&mut self, application: T)
443 where
444 T: Into<Cow<'static, str>>,
445 {
446 self.lock.application = application.into();
447 }
448
449 pub fn completer(&self) -> &Arc<dyn Completer<Term>> {
451 &self.lock.completer
452 }
453
454 pub fn set_completer(
456 &mut self,
457 completer: Arc<dyn Completer<Term>>,
458 ) -> Arc<dyn Completer<Term>> {
459 replace(&mut self.lock.completer, completer)
460 }
461
462 pub fn set_highlight_completions(&mut self, enable: bool) {
464 self.lock.highlight_completions = enable;
465 }
466
467 pub fn get_variable(&self, name: &str) -> Option<Variable> {
470 self.lock.get_variable(name)
471 }
472
473 pub fn set_variable(&mut self, name: &str, value: &str) -> Option<Variable> {
479 self.lock.set_variable(name, value)
480 }
481
482 pub fn variables(&self) -> VariableIter<'_> {
484 self.lock.variables.iter()
485 }
486
487 pub fn blink_matching_paren(&self) -> bool {
492 self.lock.blink_matching_paren
493 }
494
495 pub fn set_blink_matching_paren(&mut self, set: bool) {
497 self.lock.blink_matching_paren = set;
498 }
499
500 pub fn catch_signals(&self) -> bool {
502 self.lock.catch_signals
503 }
504
505 pub fn set_catch_signals(&mut self, enabled: bool) {
510 self.lock.catch_signals = enabled;
511 }
512
513 pub fn ignore_signal(&self, signal: Signal) -> bool {
515 self.lock.ignore_signals.contains(signal)
516 }
517
518 pub fn set_ignore_signal(&mut self, signal: Signal, set: bool) {
520 if set {
521 self.lock.ignore_signals.insert(signal);
522 self.lock.report_signals.remove(signal);
523 } else {
524 self.lock.ignore_signals.remove(signal);
525 }
526 }
527
528 pub fn report_signal(&self, signal: Signal) -> bool {
530 self.lock.report_signals.contains(signal)
531 }
532
533 pub fn set_report_signal(&mut self, signal: Signal, set: bool) {
538 if set {
539 self.lock.report_signals.insert(signal);
540 self.lock.ignore_signals.remove(signal);
541 } else {
542 self.lock.report_signals.remove(signal);
543 }
544 }
545
546 pub fn disable_completion(&self) -> bool {
550 self.lock.disable_completion
551 }
552
553 pub fn set_disable_completion(&mut self, disable: bool) {
555 self.lock.disable_completion = disable;
556 }
557
558 pub fn echo_control_characters(&self) -> bool {
563 self.lock.echo_control_characters
564 }
565
566 pub fn set_echo_control_characters(&mut self, echo: bool) {
568 self.lock.echo_control_characters = echo;
569 }
570
571 pub fn completion_append_character(&self) -> Option<char> {
573 self.lock.completion_append_character
574 }
575
576 pub fn set_completion_append_character(&mut self, ch: Option<char>) {
578 self.lock.completion_append_character = ch;
579 }
580
581 pub fn completion_display_width(&self) -> usize {
588 self.lock.completion_display_width
589 }
590
591 pub fn set_completion_display_width(&mut self, n: usize) {
593 self.lock.completion_display_width = n;
594 }
595
596 pub fn completion_query_items(&self) -> usize {
601 self.lock.completion_query_items
602 }
603
604 pub fn set_completion_query_items(&mut self, n: usize) {
606 self.lock.completion_query_items = n;
607 }
608
609 pub fn keyseq_timeout(&self) -> Option<Duration> {
614 self.lock.keyseq_timeout
615 }
616
617 pub fn set_keyseq_timeout(&mut self, timeout: Option<Duration>) {
619 self.lock.keyseq_timeout = timeout;
620 }
621
622 pub fn page_completions(&self) -> bool {
626 self.lock.page_completions
627 }
628
629 pub fn set_page_completions(&mut self, set: bool) {
631 self.lock.page_completions = set;
632 }
633
634 pub fn print_completions_horizontally(&self) -> bool {
639 self.lock.print_completions_horizontally
640 }
641
642 pub fn set_print_completions_horizontally(&mut self, set: bool) {
644 self.lock.print_completions_horizontally = set;
645 }
646
647 pub fn string_chars(&self) -> &str {
649 &self.lock.string_chars
650 }
651
652 pub fn set_string_chars<T>(&mut self, chars: T)
654 where
655 T: Into<Cow<'static, str>>,
656 {
657 self.lock.string_chars = chars.into();
658 }
659
660 pub fn word_break_chars(&self) -> &str {
662 &self.lock.word_break
663 }
664
665 pub fn set_word_break_chars<T>(&mut self, chars: T)
667 where
668 T: Into<Cow<'static, str>>,
669 {
670 self.lock.word_break = chars.into();
671 }
672
673 pub fn bindings(&self) -> BindingIter<'_> {
675 self.lock.bindings()
676 }
677
678 pub fn bind_sequence<T>(&mut self, seq: T, cmd: Command) -> Option<Command>
682 where
683 T: Into<Cow<'static, str>>,
684 {
685 self.lock.bind_sequence(seq, cmd)
686 }
687
688 pub fn bind_sequence_if_unbound<T>(&mut self, seq: T, cmd: Command) -> bool
693 where
694 T: Into<Cow<'static, str>>,
695 {
696 self.lock.bind_sequence_if_unbound(seq, cmd)
697 }
698
699 pub fn unbind_sequence(&mut self, seq: &str) -> Option<Command> {
703 self.lock.unbind_sequence(seq)
704 }
705
706 pub fn define_function<T>(
714 &mut self,
715 name: T,
716 cmd: Arc<dyn Function<Term>>,
717 ) -> Option<Arc<dyn Function<Term>>>
718 where
719 T: Into<Cow<'static, str>>,
720 {
721 self.lock.define_function(name, cmd)
722 }
723
724 pub fn remove_function(&mut self, name: &str) -> Option<Arc<dyn Function<Term>>> {
728 self.lock.remove_function(name)
729 }
730
731 pub(crate) fn evaluate_directives(&mut self, term: &Term, dirs: Vec<Directive>) {
732 self.lock.data.evaluate_directives(term, dirs)
733 }
734
735 pub(crate) fn evaluate_directive(&mut self, term: &Term, dir: Directive) {
736 self.lock.data.evaluate_directive(term, dir)
737 }
738
739 fn prompter<'b>(&'b mut self) -> Prompter<'b, 'a, Term> {
740 Prompter::new(&mut self.lock, self.iface.lock_write())
741 }
742
743 fn handle_resize(&mut self, size: Size) -> io::Result<()> {
744 self.prompter().handle_resize(size)
745 }
746
747 fn handle_signal(&mut self, sig: Signal) -> io::Result<()> {
748 self.prompter().handle_signal(sig)
749 }
750}
751
752impl<'a, Term: 'a + Terminal> ReadLock<'a, Term> {
753 pub fn new(
754 term: Box<dyn TerminalReader<Term> + 'a>,
755 data: MutexGuard<'a, Read<Term>>,
756 ) -> ReadLock<'a, Term> {
757 ReadLock { term, data }
758 }
759
760 pub fn read_char(&mut self) -> io::Result<Option<char>> {
767 if let Some(ch) = self.macro_pop() {
768 Ok(Some(ch))
769 } else if let Some(ch) = self.decode_input()? {
770 Ok(Some(ch))
771 } else {
772 Ok(None)
773 }
774 }
775
776 fn read_input(&mut self) -> io::Result<()> {
777 match self.term.read(&mut self.data.input_buffer)? {
778 RawRead::Bytes(_) => (),
779 RawRead::Resize(new_size) => {
780 self.last_resize = Some(new_size);
781 }
782 RawRead::Signal(sig) => {
783 self.last_signal = Some(sig);
784 }
785 }
786
787 Ok(())
788 }
789
790 fn is_input_available(&self) -> bool {
791 !self.data.macro_buffer.is_empty()
792 || match self.peek_input() {
793 Ok(Some(_)) | Err(_) => true,
794 Ok(None) => false,
795 }
796 }
797
798 fn macro_pop(&mut self) -> Option<char> {
799 if self.data.macro_buffer.is_empty() {
800 None
801 } else {
802 Some(self.data.macro_buffer.remove(0))
803 }
804 }
805
806 fn decode_input(&mut self) -> io::Result<Option<char>> {
807 let res = self.peek_input();
808
809 if let Ok(Some(ch)) = res {
810 self.data.input_buffer.drain(..ch.len_utf8());
811 }
812
813 res
814 }
815
816 fn peek_input(&self) -> io::Result<Option<char>> {
817 if self.data.input_buffer.is_empty() {
818 Ok(None)
819 } else {
820 first_char(&self.data.input_buffer)
821 }
822 }
823
824 pub fn reset_data(&mut self) {
825 self.data.reset_data();
826 }
827}
828
829impl<'a, Term: 'a + Terminal> Deref for ReadLock<'a, Term> {
830 type Target = Read<Term>;
831
832 fn deref(&self) -> &Read<Term> {
833 &self.data
834 }
835}
836
837impl<'a, Term: 'a + Terminal> DerefMut for ReadLock<'a, Term> {
838 fn deref_mut(&mut self) -> &mut Read<Term> {
839 &mut self.data
840 }
841}
842
843impl<Term: Terminal> Deref for Read<Term> {
844 type Target = Variables;
845
846 fn deref(&self) -> &Variables {
847 &self.variables
848 }
849}
850
851impl<Term: Terminal> DerefMut for Read<Term> {
852 fn deref_mut(&mut self) -> &mut Variables {
853 &mut self.variables
854 }
855}
856
857impl<Term: Terminal> Read<Term> {
858 pub fn new(term: &Term, application: Cow<'static, str>) -> Read<Term> {
859 let mut r = Read {
860 application,
861
862 bindings: default_bindings(),
863 functions: HashMap::new(),
864
865 input_buffer: Vec::new(),
866 macro_buffer: String::new(),
867
868 sequence: String::new(),
869 input_accepted: false,
870
871 overwrite_mode: false,
872 overwritten_append: 0,
873 overwritten_chars: String::new(),
874
875 completer: Arc::new(DummyCompleter),
876 completion_append_character: Some(' '),
877 completions: None,
878 completion_index: 0,
879 completion_start: 0,
880 completion_prefix: 0,
881 completion_display_prefix: 0,
882 highlight_completions: false,
883
884 string_chars: STRING_CHARS.into(),
885 word_break: WORD_BREAK_CHARS.into(),
886
887 last_cmd: Category::Other,
888 last_yank: None,
889 kill_ring: VecDeque::with_capacity(MAX_KILLS),
890
891 catch_signals: true,
892 ignore_signals: SignalSet::new(),
893 report_signals: SignalSet::new(),
894 last_resize: None,
895 last_signal: None,
896
897 variables: Variables::default(),
898
899 state: InputState::Inactive,
900 max_wait_duration: None,
901 };
902
903 r.read_init(term);
904 r
905 }
906
907 pub fn bindings(&self) -> BindingIter<'_> {
908 BindingIter(self.bindings.sequences().iter())
909 }
910
911 pub fn variables(&self) -> VariableIter<'_> {
912 self.variables.iter()
913 }
914
915 fn take_resize(&mut self) -> Option<Size> {
916 self.last_resize.take()
917 }
918
919 fn take_signal(&mut self) -> Option<Signal> {
920 self.last_signal.take()
921 }
922
923 pub fn queue_input(&mut self, seq: &str) {
924 self.macro_buffer.insert_str(0, seq);
925 }
926
927 pub fn is_active(&self) -> bool {
928 match self.state {
929 InputState::Inactive => false,
930 _ => true,
931 }
932 }
933
934 pub fn reset_data(&mut self) {
935 self.state = InputState::NewSequence;
936 self.input_accepted = false;
937 self.overwrite_mode = false;
938 self.overwritten_append = 0;
939 self.overwritten_chars.clear();
940 self.sequence.clear();
941
942 self.completions = None;
943
944 self.last_cmd = Category::Other;
945 self.last_yank = None;
946
947 self.last_resize = None;
948 self.last_signal = None;
949 }
950
951 pub fn bind_sequence<T>(&mut self, seq: T, cmd: Command) -> Option<Command>
952 where
953 T: Into<Cow<'static, str>>,
954 {
955 self.bindings.insert(seq.into(), cmd)
956 }
957
958 pub fn bind_sequence_if_unbound<T>(&mut self, seq: T, cmd: Command) -> bool
959 where
960 T: Into<Cow<'static, str>>,
961 {
962 use mortal::sequence::Entry;
963
964 match self.bindings.entry(seq.into()) {
965 Entry::Occupied(_) => false,
966 Entry::Vacant(ent) => {
967 ent.insert(cmd);
968 true
969 }
970 }
971 }
972
973 pub fn unbind_sequence(&mut self, seq: &str) -> Option<Command> {
974 self.bindings.remove(seq).map(|(_, cmd)| cmd)
975 }
976
977 pub fn define_function<T>(
978 &mut self,
979 name: T,
980 cmd: Arc<dyn Function<Term>>,
981 ) -> Option<Arc<dyn Function<Term>>>
982 where
983 T: Into<Cow<'static, str>>,
984 {
985 self.functions.insert(name.into(), cmd)
986 }
987
988 pub fn remove_function(&mut self, name: &str) -> Option<Arc<dyn Function<Term>>> {
989 self.functions.remove(name)
990 }
991
992 fn read_init(&mut self, term: &Term) {
993 if let Some(path) = env_init_file() {
994 self.read_init_file_if_exists(term, Some(path));
997 } else {
998 if !self.read_init_file_if_exists(term, user_init_file()) {
999 self.read_init_file_if_exists(term, system_init_file());
1000 }
1001 }
1002 }
1003
1004 fn read_init_file_if_exists(&mut self, term: &Term, path: Option<PathBuf>) -> bool {
1005 match path {
1006 Some(ref path) if path.exists() => {
1007 self.read_init_file(term, path);
1008 true
1009 }
1010 _ => false,
1011 }
1012 }
1013
1014 fn read_init_file(&mut self, term: &Term, path: &Path) {
1015 if let Some(dirs) = parse_file(path) {
1016 self.evaluate_directives(term, dirs);
1017 }
1018 }
1019
1020 pub(crate) fn evaluate_directives(&mut self, term: &Term, dirs: Vec<Directive>) {
1022 for dir in dirs {
1023 self.evaluate_directive(term, dir);
1024 }
1025 }
1026
1027 pub(crate) fn evaluate_directive(&mut self, term: &Term, dir: Directive) {
1029 match dir {
1030 Directive::Bind(seq, cmd) => {
1031 self.bind_sequence(seq, cmd);
1032 }
1033 Directive::Conditional {
1034 name,
1035 value,
1036 then_group,
1037 else_group,
1038 } => {
1039 let name = name.as_ref().map(|s| &s[..]);
1040
1041 if self.eval_condition(term, name, &value) {
1042 self.evaluate_directives(term, then_group);
1043 } else {
1044 self.evaluate_directives(term, else_group);
1045 }
1046 }
1047 Directive::SetVariable(name, value) => {
1048 self.set_variable(&name, &value);
1049 }
1050 }
1051 }
1052
1053 fn eval_condition(&self, term: &Term, name: Option<&str>, value: &str) -> bool {
1054 match name {
1055 None => self.application == value,
1056 Some("lib") => value == "lineread",
1057 Some("mode") => value == "emacs",
1058 Some("term") => self.term_matches(term, value),
1059 _ => false,
1060 }
1061 }
1062
1063 fn term_matches(&self, term: &Term, value: &str) -> bool {
1064 match_name(term.name(), value)
1065 }
1066}
1067
1068pub struct BindingIter<'a>(slice::Iter<'a, (Cow<'static, str>, Command)>);
1070
1071impl<'a> ExactSizeIterator for BindingIter<'a> {}
1072
1073impl<'a> Iterator for BindingIter<'a> {
1074 type Item = (&'a str, &'a Command);
1075
1076 #[inline]
1077 fn next(&mut self) -> Option<Self::Item> {
1078 self.0.next().map(|&(ref s, ref cmd)| (&s[..], cmd))
1079 }
1080
1081 #[inline]
1082 fn nth(&mut self, n: usize) -> Option<Self::Item> {
1083 self.0.nth(n).map(|&(ref s, ref cmd)| (&s[..], cmd))
1084 }
1085
1086 #[inline]
1087 fn size_hint(&self) -> (usize, Option<usize>) {
1088 self.0.size_hint()
1089 }
1090}
1091
1092impl<'a> DoubleEndedIterator for BindingIter<'a> {
1093 #[inline]
1094 fn next_back(&mut self) -> Option<Self::Item> {
1095 self.0.next_back().map(|&(ref s, ref cmd)| (&s[..], cmd))
1096 }
1097}
1098
1099fn default_bindings() -> SequenceMap<Cow<'static, str>, Command> {
1100 use crate::command::Command::*;
1101
1102 SequenceMap::from(vec![
1103 ("\r".into(), AcceptLine),
1105 ("\n".into(), AcceptLine),
1106 ("\x1b[A".into(), PreviousHistory),
1108 ("\x1b[B".into(), NextHistory),
1109 ("\x1b[C".into(), ForwardChar),
1110 ("\x1b[D".into(), BackwardChar),
1111 ("\x1b[H".into(), BeginningOfLine),
1112 ("\x1b[F".into(), EndOfLine),
1113 ("\x1bOA".into(), PreviousHistory),
1115 ("\x1bOB".into(), NextHistory),
1116 ("\x1bOC".into(), ForwardChar),
1117 ("\x1bOD".into(), BackwardChar),
1118 ("\x1bOH".into(), BeginningOfLine),
1119 ("\x1bOF".into(), EndOfLine),
1120 ("\x1b[2~".into(), OverwriteMode),
1122 ("\x1b[3~".into(), DeleteChar),
1123 ("\x01".into(), BeginningOfLine), ("\x02".into(), BackwardChar), ("\x04".into(), DeleteChar), ("\x05".into(), EndOfLine), ("\x06".into(), ForwardChar), ("\x07".into(), Abort), ("\x08".into(), BackwardDeleteChar), ("\x0b".into(), KillLine), ("\x0c".into(), ClearScreen), ("\x0e".into(), NextHistory), ("\x10".into(), PreviousHistory), ("\x12".into(), ReverseSearchHistory), ("\x14".into(), TransposeChars), ("\x15".into(), BackwardKillLine), ("\x16".into(), QuotedInsert), ("\x17".into(), UnixWordRubout), ("\x19".into(), Yank), ("\x1d".into(), CharacterSearch), ("\x7f".into(), BackwardDeleteChar), ("\x1b\x08".into(), BackwardKillWord), ("\x1b\x1d".into(), CharacterSearchBackward), ("\x1b\x7f".into(), BackwardKillWord), ("\x1bb".into(), BackwardWord), ("\x1bd".into(), KillWord), ("\x1bf".into(), ForwardWord), ("\x1bt".into(), TransposeWords), ("\x1by".into(), YankPop), ("\x1b#".into(), InsertComment), ("\x1b<".into(), BeginningOfHistory), ("\x1b>".into(), EndOfHistory), ("\t".into(), Complete), ("\x1b?".into(), PossibleCompletions), ("\x1b*".into(), InsertCompletions), ("\x1b-".into(), DigitArgument), ("\x1b0".into(), DigitArgument), ("\x1b1".into(), DigitArgument), ("\x1b2".into(), DigitArgument), ("\x1b3".into(), DigitArgument), ("\x1b4".into(), DigitArgument), ("\x1b5".into(), DigitArgument), ("\x1b6".into(), DigitArgument), ("\x1b7".into(), DigitArgument), ("\x1b8".into(), DigitArgument), ("\x1b9".into(), DigitArgument), ])
1171}
1172
1173fn limit_duration(dur: Option<Duration>, max: Option<Duration>) -> Option<Duration> {
1174 match (dur, max) {
1175 (dur, None) | (None, dur) => dur,
1176 (Some(dur), Some(max)) => Some(dur.min(max)),
1177 }
1178}