diff options
| author | Tom Feist <shabble@cowu.be> | 2010-09-20 22:44:33 +0000 | 
|---|---|---|
| committer | Tom Feist <shabble@cowu.be> | 2010-09-20 22:44:33 +0000 | 
| commit | 019e1586df3cad94b145cbf6db8a3041e27013de (patch) | |
| tree | c47a95c1b6532bc594263af4cb4306d1e2e85261 | |
| parent | new key detection system that incorporates a buffer to identify sequences that (diff) | |
| download | irssi-scripts-019e1586df3cad94b145cbf6db8a3041e27013de.tar.gz irssi-scripts-019e1586df3cad94b145cbf6db8a3041e27013de.zip | |
moved to an emulated keystrokes approach rather than trying to reimplement the
various movement functions.  Might be an issue finding the correct bindings -
maybe easier to have it set a whole load of its own on init in some obscure place
| -rw-r--r-- | vim-mode/vim_mode.pl | 111 | 
1 files changed, 69 insertions, 42 deletions
| diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index 892abf7..2418eb0 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -23,6 +23,7 @@ sub DEBUG () { 0 }  # circular buffer to keep track of the last N keystrokes.  my @key_buf; +my $buf_idx = 0;  my $key_buf_timer;  my $key_buf_enabled = 0;  my $should_ignore = 0; @@ -59,11 +60,50 @@ my $commands                params => { 'dir' => 'right' },              }, +     'w' => { command => 'move forward word', +              func => \&cmd_jump_word, +              params => { 'dir' => 'fwd', +                          'pos' => sub { _input_pos() } +                        }, +            }, +     'b' => { command => 'move backward word', +              func => \&cmd_jump_word, +              params => { 'dir' => 'back', +                          'pos' => sub { _input_pos() } +                        }, +            }, + +     'x' => { command => 'delete char forward', +              func => \&cmd_delete_char, +              params => { 'dir' => 'fwd', +                          'pos' => sub { _input_pos() } +                        }, +            },      }; -sub cmd_jump_word { +sub cmd_delete_char {      my ($params) = @_; +    my $pos = $params->{pos}->(); +    my $direction = $params->{dir}; +    print "Sending keystrokes for delete-char"; +    _stop(); +    my @buf = (4); +    _emulate_keystrokes(@buf); + +} +sub cmd_jump_word { +    my ($params) = @_; +    my $pos = $params->{pos}->(); +    my $direction = $params->{dir}; +    _stop(); +    my @buf; +    if ($direction eq 'fwd') { +        push @buf, (27, 102); +    } else { +        push @buf, (27, 98); +    } +    _emulate_keystrokes(@buf);  }  sub cmd_insert { @@ -83,17 +123,14 @@ sub cmd_move {      my ($params) = @_;      my $dir = $params->{dir};      my $current_pos = _input_pos(); - +    _stop(); +    my @buf = (27, 91);      if ($dir eq 'left') { -        _input_pos($current_pos -1) if $current_pos; -    } elsif ($dir eq 'right') { -        my $current_len = _input_len(); -        _input_pos($current_pos +1) unless $current_pos == $current_len; +        push @buf, 68;      } else { -        print "Unknown direction: $dir"; +        push @buf, 67;      } - -    _stop(); +    _emulate_keystrokes(@buf);  }  sub vim_mode_cb { @@ -111,38 +148,21 @@ sub vim_mode_cb {  sub got_key {      my ($key) = @_; -# goals: - -# * all keys should work normally in insert mode (including Arrow keys) -# * we should be able to reliably detect a single press of the esc key and -#     switch to command mode -# * - -# whenever we see an escape, we need to be sure it's not part of a -# longer escape sequence (eg ^[[A for arrowkeys or whatever) - -# when we see an escape (27), we start a timer for a short period, and -# capture all additional keystrokes into a buffer. - -# once the timer expires, we examine the buffer to see if it's a plain escape -# (hopefully time is short enough that we don't get user-repeated keypresses) -# or an escape sequence, which we can then parse and do whatever with. - -# issues: - -# do the buffered commands get evaluated? (ie: do we sig_stop them?) -#      return if ($should_ignore);      if ($key == 27) {          print "Esc seen, starting buffer";          $key_buf_enabled = 1; + +        # NOTE: this timeout might be too low on laggy systems, but +        # it comes at the cost of keystroke latency for things that +        # contain escape sequences (arrow keys, etc)          $key_buf_timer            = Irssi::timeout_add_once(10, \&handle_key_buffer, undef);      }      if ($key_buf_enabled) { -        push @key_buf, $key; +        $key_buf[$buf_idx++] = $key;          _stop();      } @@ -170,22 +190,19 @@ sub handle_key_buffer {          # or pass it off to the command handler.          if ($mode == M_CMD) {              # command -            my $key_str = join '', map { chr $_ } @key_buf; +            my $key_str = join '', map { chr } @key_buf;              if ($key_str =~ m/^\e\[([ABCD])/) {                  print "Arrow key: $1";              } else {                  print "Dunno what that is."              }          } else { -            $should_ignore = 1; -            for my $key (@key_buf) { -                Irssi::signal_emit('gui key pressed', $key); -            } -            $should_ignore = 0; +            _emulate_keystrokes(@key_buf);          }      }      @key_buf = (); +    $buf_idx = 0;      $key_buf_enabled = 0;  } @@ -194,14 +211,13 @@ sub handle_command {      my $char = chr($key);      if (exists $commands->{$char}) {          my $cmd = $commands->{$char}; -        print "Going to execute command: ", $cmd->{command}; +        # print "Going to execute command: ", $cmd->{command};          $cmd->{func}->( $cmd->{params} );      } else {          _stop(); # disable everything else      }  } -  Irssi::signal_add_first 'gui key pressed' => \&got_key;  Irssi::statusbar_item_register ('vim_mode', 0, 'vim_mode_cb'); @@ -216,19 +232,30 @@ sub _input {  }  sub _input_len { -    return length (Irssi::parse_special('$L', 0, 0)); +    return length _input();  }  sub _input_pos {      my ($pos) = @_; +    my $cur_pos = Irssi::gui_input_get_pos(); +      if (defined $pos) { -        Irssi::gui_input_set_pos($pos); +        Irssi::gui_input_set_pos($pos) if $pos != $cur_pos;      } else { -        $pos = Irssi::gui_input_get_pos(); +        $pos = $cur_pos;      } +      return $pos;  } +sub _emulate_keystrokes { +    my @keys = @_; +    $should_ignore = 1; +    for my $key (@keys) { +        Irssi::signal_emit('gui key pressed', $key); +    } +    $should_ignore = 0; +}  sub _stop() {      Irssi::signal_stop();  } | 
