From 90e7c67629ccd0e01176df5b59eb9301fab7121d Mon Sep 17 00:00:00 2001 From: Tom Feist Date: Wed, 6 Oct 2010 18:21:03 +0100 Subject: more progress on replacing prompt bar for visual mode and other trickery. Prompt is mostly working but needs configuration options and more cleanup. Visual mode is still hacky as sin. --- prompt_info/prompt_replace.pl | 275 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 275 insertions(+) create mode 100644 prompt_info/prompt_replace.pl diff --git a/prompt_info/prompt_replace.pl b/prompt_info/prompt_replace.pl new file mode 100644 index 0000000..5e29f92 --- /dev/null +++ b/prompt_info/prompt_replace.pl @@ -0,0 +1,275 @@ +use strict; +use warnings; + +use Irssi; +use Irssi::TextUI; # for sbar_items_redraw +use Data::Dumper; +use Term::Size; + + + +our $VERSION = "0.1"; +our %IRSSI = + ( + authors => "shabble", + contact => 'shabble+irssi@metavore.org, shabble@#irssi/Freenode', + name => "prompt_info", + description => "Helper script for dynamically adding text " + . "into the input-bar prompt.", + license => "Public Domain", + changed => "24/7/2010" + ); + +sub DEBUG () { 1 } +#sub DEBUG () { 0 } + +my $prompt_data = undef; +my $prompt_item = undef; + +my $vis_enabled = 0; + +my ($term_w, $term_h); + +my ($region_start, $region_end); + +init(); + +sub update_terminal_size { + my @stty_lines = qx/stty -a/; + my $line = $stty_lines[0]; + @stty_lines = (); # don't need the rest. + + if ($line =~ m/\s*(\d+)\s*rows\s*;\s*(\d+)\s*columns\s*;/) { + $term_h = $1; + $term_w = $2; + } else { + print "Failed to detect terminal size"; + } +} + +sub init { + + Irssi::command_bind('prompt_on', \&replace_prompt_items); + Irssi::command_bind('prompt_off', \&restore_prompt_items); + + Irssi::command_bind('prompt_set', + sub { + my $data = shift; + $prompt_data = $data; + refresh_prompt(); + }); + + Irssi::command_bind('prompt_clear', + sub { + $prompt_data = undef; + refresh_prompt(); + }); + + Irssi::command_bind('visual', \&cmd_vis); + Irssi::command("^BIND meta-l /visual"); + + Irssi::statusbar_item_register ('new_prompt', 0, 'new_prompt_render'); + + + Irssi::signal_add_last('gui key pressed', \&key_pressed); + Irssi::signal_add('window changed', \&refresh_prompt); + Irssi::signal_add('window name changed', \&refresh_prompt); + Irssi::signal_add('window changed automatic', \&refresh_prompt); + Irssi::signal_add('window item changed', \&refresh_prompt); + + Irssi::signal_add('terminal resized', \&update_terminal_size); + + update_terminal_size(); + replace_prompt_items(); +} + +# Irssi::signal_add('window changed automatic', \&refresh_prompt); +# Irssi::signal_add('window changed automatic', \&refresh_prompt); + + +sub UNLOAD { + restore_prompt_items(); +} + +sub cmd_vis { + $vis_enabled = not $vis_enabled; + if ($vis_enabled) { + print "visual mode started"; + $region_start = _pos(); + } else { + print "Visual mode ended"; + $region_end = _pos(); + + if ($region_end > $region_start) { + my $input = Irssi::parse_special('$L', 0, 0); + my $str = substr($input, $region_start, $region_end - $region_start); + print "Region selected: $str"; + } else { + print "Invalid region selection: [ $region_start - $region_end ]"; + $region_start = $region_end = undef; + } + } + +} + +sub refresh_prompt { + Irssi::statusbar_items_redraw('new_prompt'); +} + +my $buf = ''; + +sub key_pressed { + my ($key) = @_; + my $char = chr($key); + $buf .= $char; + my $str = Irssi::parse_special('$L'); + + return unless $vis_enabled; + + print_to_input($str, $prompt_item->{size}); +} + +sub print_to_input { + my ($str, $offset) = @_; + $str = "%8$str%8"; + + # my ($term_w, $term_h) = Term::Size::chars *STDOUT{IO}; + + + # my $theme = Irssi::current_theme(); + # my $prompt = $theme->format_expand('{prompt $itemname $winname}', + # Irssi::EXPAND_FLAG_RECURSIVE_MASK); + #print "Prompt is $prompt"; + + Irssi::gui_printtext($offset, $term_h, $str); +} + + + sub new_prompt_render { + my ($sb_item, $get_size_only) = @_; + + + my $default_prompt = ''; + + my $window = Irssi::active_win(); + if (scalar( () = $window->items )) { + $default_prompt = '{prompt $[.15]itemname}'; + } else { + $default_prompt = '{prompt $winname}'; + } + + my $p_copy = $prompt_data; + if (defined $prompt_data) { + # check if we have a marker + $p_copy =~ s/\$p/$default_prompt/; + } else { + $p_copy = $default_prompt; + } + print "Redrawing with: $p_copy"; + + $prompt_item = $sb_item; + + $sb_item->default_handler($get_size_only, $p_copy, '', 0); + } + +sub replace_prompt_items { + # remove existing ones. + print "Removing original prompt" if DEBUG; + + _sbar_command('prompt', 'remove', 'prompt'); + _sbar_command('prompt', 'remove', 'prompt_empty'); + + # add the new one. + + _sbar_command('prompt', 'add', 'new_prompt', + qw/-alignment left -before input -priority 0/); + +} + +sub restore_prompt_items { + + _sbar_command('prompt', 'remove', 'new_prompt'); + + print "Restoring original prompt" if DEBUG; + _sbar_command('prompt', 'add', 'prompt', + qw/-alignment left -before input -priority 0/); + _sbar_command('prompt', 'add', 'prompt_empty', + qw/-alignment left -after prompt -priority 0/); +} + + +sub _sbar_command { + my ($bar, $cmd, $item, @args) = @_; + + my $args_str = join ' ', @args; + + $args_str .= ' ' if length $args_str; + + my $command = sprintf 'STATUSBAR %s %s %s%s', + $bar, $cmd, $args_str, defined($item)?$item:''; + + print "Running command: $command" if DEBUG; + Irssi::command($command); +} + + +sub _pos { + return Irssi::gui_input_get_pos(); +} + + +# my $prompt_additional_content = ''; + +# Irssi::expando_create('prompt_additional', \&expando_prompt, {}); + +# sub expando_prompt { +# my ($server, $witem, $arg) = @_; +# return $prompt_additional_content; +# #return Irssi::current_theme->format_expand("{sb +# #$prompt_additional_content}", 0x0f); +# } + +# sub redraw_prompts { +# Irssi::statusbar_items_redraw ('prompt'); +# Irssi::statusbar_items_redraw ('prompt_empty'); +# } + +# sub handle_change_prompt_sig { +# my ($text) = @_; + +# my $expanded_text = Irssi::parse_special($text); + +# print "Got prompt change sig with: $text -> $expanded_text" if DEBUG; + +# my $changed = ($expanded_text ne $prompt_additional_content); + +# $prompt_additional_content = $expanded_text; + +# if ($changed) { +# print "Redrawing prompts" if DEBUG; +# redraw_prompts(); +# } +# } + +# sub prompt_additional_cmd { +# my ($str) = @_; +# print "Setting prompt to: $str" if DEBUG; +# Irssi::signal_emit('change prompt', $str); +# } + +# test_abstract_setup(); +# Irssi::signal_register({'change prompt' => [qw/string/]}); +# Irssi::signal_add('change prompt' => \&handle_change_prompt_sig); + +# Irssi::command_bind('set_prompt' => \&prompt_additional_cmd); + +# sub test_abstract_setup { +# my $theme = Irssi::current_theme(); +# my $prompt = $theme->format_expand('{prompt}', 0); +# if ($prompt !~ m/\$prompt_additional/) { +# print "Prompt_Info: It looks like you haven't modified your theme" +# . " to include the \$prompt_additional expando. You will not see" +# . " any prompt info messages until you do. See script comments" +# . "for details"; +# } +# } -- cgit v1.2.3