summaryrefslogtreecommitdiffstats
path: root/scripts/uberprompt.pl
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/uberprompt.pl')
-rw-r--r--scripts/uberprompt.pl787
1 files changed, 787 insertions, 0 deletions
diff --git a/scripts/uberprompt.pl b/scripts/uberprompt.pl
new file mode 100644
index 0000000..c4b8cc9
--- /dev/null
+++ b/scripts/uberprompt.pl
@@ -0,0 +1,787 @@
+=pod
+
+=head1 NAME
+
+uberprompt.pl
+
+=head1 DESCRIPTION
+
+This script replaces the default prompt status-bar item with one capable of
+displaying additional information, under either user control or via scripts.
+
+=head1 INSTALLATION
+
+Copy into your F<~/.irssi/scripts/> directory and load with
+C</SCRIPT LOAD F<filename>>.
+
+It is recommended that you make it autoload in one of the
+L<usual ways|https://github.com/shabble/irssi-docs/wiki/Guide#Autorunning_Scripts>.
+
+=head1 SETUP
+
+If you have a custom prompt format, you may need to copy it to the
+uberprompt_format setting. See below for details.
+
+=head1 USAGE
+
+Although the script is designed primarily for other scripts to set
+status information into the prompt, the following commands are available:
+
+=over 4
+
+=item * C</prompt set [-inner|-pre|-post|only] E<lt>msgE<gt>>
+
+Sets the prompt to the given argument. Any use of C<$p> in the argument will
+be replaced by the original prompt content.
+
+A parameter corresponding to the C<UP_*> constants listed below is required, in
+the format C</prompt set -inner Hello!>
+
+=item * C</prompt clear>
+
+Clears the additional data provided to the prompt.
+
+=item * C</prompt on>
+
+Eenables the uberprompt (things may get confused if this is used
+whilst the prompt is already enabled)
+
+=item * C</prompt off>
+
+Restore the original irssi prompt and prompt_empty statusbars. unloading the
+script has the same effect.
+
+=item * C</help prompt>
+
+show help for uberprompt commands
+
+=back
+
+=head1 SETTINGS
+
+=head2 UBERPROMPT FORMAT
+
+C</set uberprompt_format E<lt>formatE<gt>>
+
+The default is C<[$*$uber]>, which is the same as the default provided in
+F<default.theme>.
+
+Changing this setting will update the prompt immediately, unlike editing your theme.
+
+An additional variable available within this format is C<$uber>, which expands to
+the content of prompt data provided with the C<UP_INNER> or C</prompt set -inner>
+placement argument.
+
+For all other placement arguments, it will expand to the empty string.
+
+B<Note:> This setting completely overrides the C<prompt="...";> line in your
+.theme file, and may cause unexpected behaviour if your theme wishes to set a
+different form of prompt. It can be simply copied from the theme file into the
+above setting.
+
+=head2 OTHER SETTINGS
+
+=over 4
+
+=item * C<uberprompt_autostart>
+
+Boolean value, which determines if uberprompt should enable itself automatically
+upon loading. If Off, it must be enabled manually with C</prompt on>. Defaults to On.
+
+=item * C<uberprompt_debug>
+
+Boolean value, which determines if uberprompt should print debugging information.
+Defaults to Off, and should probably be left that way unless requested for bug-tracing
+purposes.
+
+=item * C<uberprompt_format>
+
+String value containing the format-string which uberprompt uses to display the
+prompt. Defaults to "C<[$*$uber] >", where C<$*> is the content the prompt would
+normally display, and C<$uber> is a placeholder variable for dynamic content, as
+described in the section above.
+
+=item * C<uberprompt_load_hook>
+
+String value which can contain one or more commands to be run whenever the uberprompt
+is enabled, either via autostart, or C</prompt on>. Defaults to the empty string, in
+which case no commands are run. Some examples include:
+
+C</set uberprompt_load_hook /echo prompt enabled> or
+
+C</^sbar prompt add -after input vim_mode> for those using vim_mode.pl who want
+the command status indicator on the prompt line.
+
+=item * C<uberprompt_unload_hook>
+
+String value, defaulting to the empty string, which can contain commands which
+are executed when the uberprompt is disabled, either by unloading the script,
+or by the command C</prompt off>.
+
+=item * C<uberprompt_use_replaces>
+
+Boolean value, defaults to Off. If enabled, the format string for the prompt
+will be subject to the I<replaces> section of the theme. The most obvious
+effect of this is that bracket characters C<[ ]> are displayed in a different
+colour, typically quite dark.
+
+=back
+
+B<Note:> For both C<uberprompt_*_hook> settings above, multiple commands can
+be chained together in the form C</eval /^cmd1 ; /^cmd2>. The C<^> prevents
+any output from the commands (such as error messages) being displayed.
+
+=head2 SCRIPTING USAGE
+
+The primary purpose of uberprompt is to be used by other scripts to
+display information in a way that is not possible by printing to the active
+window or using statusbar items.
+
+The content of the prompt can be set from other scripts via the C<"change prompt">
+signal.
+
+For Example:
+
+ signal_emit 'change prompt' 'some_string', UberPrompt::UP_INNER;
+
+will set the prompt to include that content, by default 'C<[$* some_string]>'
+
+The possible position arguments are the following strings:
+
+=over 4
+
+=item * C<UP_PRE> - place the provided string before the prompt - C<$string$prompt>
+
+=item * C<UP_INNER> - place the provided string inside the prompt - C<{prompt $* $string}>
+
+=item * C<UP_POST> - place the provided string after the prompt - C<$prompt$string>
+
+=item * C<UP_ONLY> - replace the prompt with the provided string - C<$string>
+
+=back
+
+All strings may use the special variable 'C<$prompt>' to include the prompt
+verbatim at that position in the string. It is probably only useful for
+the C<UP_ONLY> mode however. '$C<prompt_nt>' will include the prompt, minus any
+trailing whitespace.
+
+=head2 CHANGE NOTIFICATIONS
+
+You can also be notified when the prompt changes in response to the previous
+signal or manual C</prompt> commands via:
+
+ signal_add 'prompt changed', sub { my ($text, $len) = @_; ... do something ... };
+
+This callback will occur whenever the contents of the prompt is changed.
+
+
+=head2 NOTES FOR SCRIPT WRITERS:
+
+The following code snippet can be used within your own script as a preamble
+to ensure that uberprompt is loaded before your script to avoid
+any issues with loading order. It first checks if uberprompt is loaded, and
+if not, attempts to load it. If the load fails, the script will die
+with an error message, otherwise it will call your app_init() function.
+
+I<---- start of snippet ---->
+
+ my $DEBUG_ENABLED = 0;
+ sub DEBUG () { $DEBUG_ENABLED }
+
+ # check we have uberprompt loaded.
+
+ sub script_is_loaded {
+ return exists($Irssi::Script::{$_[0] . '::'});
+ }
+
+ if (not script_is_loaded('uberprompt')) {
+
+ print "This script requires 'uberprompt.pl' in order to work. "
+ . "Attempting to load it now...";
+
+ Irssi::signal_add('script error', 'load_uberprompt_failed');
+ Irssi::command("script load uberprompt.pl");
+
+ unless(script_is_loaded('uberprompt')) {
+ load_uberprompt_failed("File does not exist");
+ }
+ app_init();
+ } else {
+ app_init();
+ }
+
+ sub load_uberprompt_failed {
+ Irssi::signal_remove('script error', 'load_uberprompt_failed');
+
+ print "Script could not be loaded. Script cannot continue. "
+ . "Check you have uberprompt.pl installed in your path and "
+ . "try again.";
+
+ die "Script Load Failed: " . join(" ", @_);
+ }
+
+I<---- end of snippet ---->
+
+=head1 AUTHORS
+
+Copyright E<copy> 2011 Tom Feist C<E<lt>shabble+irssi@metavore.orgE<gt>>
+
+=head1 LICENCE
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+=head1 BUGS
+
+=over 4
+
+=item *
+
+Resizing the terminal rapidly whilst using this script in debug mode may cause
+irssi to crash. See bug report at http://bugs.irssi.org/index.php?do=details&task_id=772 for details.
+
+=back
+
+=head1 TODO
+
+=over 4
+
+=item * report failure (somehow) to clients if hte prompt is disabled.
+
+=item * fix issue at autorun startup with sbar item doesn't exist.
+
+=back
+
+=cut
+
+use strict;
+use warnings;
+
+use Irssi;
+use Irssi::TextUI;
+use Data::Dumper;
+
+{ package Irssi::Nick } # magic.
+
+our $VERSION = "0.2"; # 255b35bb44161e0
+our %IRSSI =
+ (
+ authors => "shabble",
+ contact => 'shabble+irssi@metavore.org, shabble@#irssi/Freenode',
+ name => "uberprompt",
+ description => "Helper script for dynamically adding text "
+ . "into the input-bar prompt.",
+ license => "MIT",
+ changed => "24/7/2010"
+ );
+
+
+my $DEBUG_ENABLED = 0;
+sub DEBUG { $DEBUG_ENABLED }
+
+my $prompt_data = '';
+my $prompt_data_pos = 'UP_INNER';
+
+my $prompt_last = '';
+my $prompt_format = '';
+my $prompt_format_empty = '';
+
+# flag to indicate whether rendering of hte prompt should allow the replaces
+# theme formats to be applied to the content.
+my $use_replaces = 0;
+my $trim_data = 0;
+
+my $emit_request = 0;
+
+my $expando_refresh_timer;
+my $expando_vars = {};
+
+my $init_callbacks = {load => '', unload => ''};
+
+pre_init();
+
+sub pre_init {
+ `stty -ixon`;
+ init();
+}
+
+sub prompt_subcmd_handler {
+ my ($data, $server, $item) = @_;
+ #$data =~ s/\s+$//g; # strip trailing whitespace.
+ Irssi::command_runsub('prompt', $data, $server, $item);
+}
+
+sub _error($) {
+ my ($msg) = @_;
+ Irssi::active_win->print($msg, MSGLEVEL_CLIENTERROR);
+}
+
+sub _debug_print($) {
+ return unless DEBUG;
+ my ($msg) = @_;
+ Irssi::active_win->print($msg, MSGLEVEL_CLIENTCRAP);
+}
+
+sub _print_help {
+ my ($args) = @_;
+ if ($args =~ m/^\s*prompt/i) {
+ my @help_lines =
+ (
+ "",
+ "PROMPT ON",
+ "PROMPT OFF",
+ "PROMPT CLEAR",
+ "PROMPT SET { -pre | -post | -only | -inner } <content>",
+ "",
+ "Commands for manipulating the UberPrompt.",
+ "",
+ "/PROMPT ON enables uberprompt, replacing the existing prompt ",
+ " statusbar-item",
+ "/PROMPT OFF disables it, and restores the original prompt item",
+ "/PROMPT CLEAR resets the value of any additional data set by /PROMPT SET",
+ " or a script",
+ "/PROMPT SET changes the contents of the prompt, according to the mode",
+ " and content provided.",
+ " { -inner sets the value of the \$uber psuedo-variable in the",
+ " /set uberprompt_format setting.",
+ " | -pre places the content before the current prompt string",
+ " | -post places the content after the prompt string",
+ " | -only replaces the entire prompt contents with the given string }",
+ "",
+ "See Also:",
+ '',
+ '/SET uberprompt_format -- defaults to "[$*$uber] "',
+ '/SET uberprompt_format_empty -- defaults to "[$*] "',
+ "/SET uberprompt_autostart -- determines whether /PROMPT ON is run",
+ " automatically when the script loads",
+ "/SET uberprompt_use_replaces -- toggles the use of the current theme",
+ " \"replaces\" setting. Especially",
+ " noticeable on brackets \"[ ]\" ",
+ "/SET uberprompt_trim_data -- defaults to off. Removes whitespace from",
+ " both sides of the \$uber result.",
+ "",
+ );
+
+ Irssi::print($_, MSGLEVEL_CLIENTCRAP) for @help_lines;
+ Irssi::signal_stop;
+ }
+}
+
+sub UNLOAD {
+ deinit();
+}
+
+sub exp_lbrace() { '{' }
+sub exp_rbrace() { '}' }
+
+sub deinit {
+ Irssi::expando_destroy('lbrace');
+ Irssi::expando_destroy('rbrace');
+
+ # remove uberprompt and return the original ones.
+ #print "Removing uberprompt and restoring original";
+ restore_prompt_items();
+}
+
+sub gui_exit {
+ restore_prompt_items();
+}
+
+sub init {
+ Irssi::statusbar_item_register('uberprompt', 0, 'uberprompt_draw');
+
+ # TODO: flags to prevent these from being recomputed?
+ Irssi::expando_create('lbrace', \&exp_lbrace, {});
+ Irssi::expando_create('rbrace', \&exp_rbrace, {});
+
+ Irssi::settings_add_str ('uberprompt', 'uberprompt_format', '[$*$uber] ');
+ Irssi::settings_add_str ('uberprompt', 'uberprompt_format_empty', '[$*] ');
+
+ Irssi::settings_add_str ('uberprompt', 'uberprompt_load_hook', '');
+ Irssi::settings_add_str ('uberprompt', 'uberprompt_unload_hook', '');
+
+ Irssi::settings_add_bool('uberprompt', 'uberprompt_debug', 0);
+ Irssi::settings_add_bool('uberprompt', 'uberprompt_autostart', 1);
+
+ Irssi::settings_add_bool('uberprompt', 'uberprompt_use_replaces', 0);
+ Irssi::settings_add_bool('uberprompt', 'uberprompt_trim_data', 0);
+
+ Irssi::command_bind("prompt", \&prompt_subcmd_handler);
+ Irssi::command_bind('prompt on', \&replace_prompt_items);
+ Irssi::command_bind('prompt off', \&restore_prompt_items);
+ Irssi::command_bind('prompt set', \&cmd_prompt_set);
+ Irssi::command_bind('prompt clear',
+ sub {
+ Irssi::signal_emit 'change prompt', '$p', 'UP_POST';
+ });
+
+ my $prompt_set_args_format = "inner pre post only";
+ Irssi::command_set_options('prompt set', $prompt_set_args_format);
+
+ Irssi::command_bind('help', \&_print_help);
+
+ Irssi::signal_add_first('gui exit', \&gui_exit);
+ Irssi::signal_add('setup changed', \&reload_settings);
+
+ # intialise the prompt format.
+ reload_settings();
+
+ # make sure we redraw when necessary.
+ Irssi::signal_add('window changed', \&uberprompt_refresh);
+ Irssi::signal_add('window name changed', \&uberprompt_refresh);
+ Irssi::signal_add('window changed automatic', \&uberprompt_refresh);
+ Irssi::signal_add('window item changed', \&uberprompt_refresh);
+ Irssi::signal_add('window item server changed', \&uberprompt_refresh);
+ Irssi::signal_add('window server changed', \&uberprompt_refresh);
+ Irssi::signal_add('server nick changed', \&uberprompt_refresh);
+
+ Irssi::signal_add('nick mode changed', \&refresh_if_me);
+
+ # install our statusbars if required.
+ if (Irssi::settings_get_bool('uberprompt_autostart')) {
+ replace_prompt_items();
+ }
+
+ # API signals
+
+ Irssi::signal_register({'change prompt' => [qw/string string/]});
+ Irssi::signal_add('change prompt' => \&change_prompt_handler);
+
+ # other scripts (specifically overlay/visual) can subscribe to
+ # this event to be notified when the prompt changes.
+ # arguments are new contents (string), new length (int)
+ Irssi::signal_register({'prompt changed' => [qw/string int/]});
+ Irssi::signal_register({'prompt length request' => []});
+
+ Irssi::signal_add('prompt length request', \&length_request_handler);
+}
+
+sub cmd_prompt_set {
+ my $args = shift;
+ my @options_list = Irssi::command_parse_options "prompt set", $args;
+ if (@options_list) {
+ my ($options, $rest) = @options_list;
+
+ my @opt_modes = keys %$options;
+ if (@opt_modes != 1) {
+ _error '%_/prompt set%_ must specify exactly one mode of'
+ . ' {-inner, -only, -pre, -post}';
+ return;
+ }
+
+ my $mode = 'UP_' . uc($opt_modes[0]);
+
+ Irssi::signal_emit 'change prompt', $rest, $mode;
+ } else {
+ _error ('%_/prompt set%_ must specify a mode {-inner, -only, -pre, -post}');
+ }
+}
+
+sub refresh_if_me {
+ my ($channel, $nick) = @_;
+
+ return unless $channel and $nick;
+
+ my $server = Irssi::active_server;
+ my $window = Irssi::active_win;
+
+ return unless $server and $window;
+
+ my $my_chan = $window->{active}->{name};
+ my $my_nick = $server->parse_special('$N');
+
+ return unless $my_chan and $my_nick;
+
+ _debug_print "Chan: $channel->{name}, "
+ . "nick: $nick->{nick}, "
+ . "me: $my_nick, chan: $my_chan";
+
+ if ($my_chan eq $channel->{name} and $my_nick eq $nick->{nick}) {
+ uberprompt_refresh();
+ }
+}
+
+sub length_request_handler {
+ $emit_request = 1;
+ uberprompt_render_prompt();
+ $emit_request = 0;
+}
+
+sub reload_settings {
+
+ $use_replaces = Irssi::settings_get_bool('uberprompt_use_replaces');
+ $DEBUG_ENABLED = Irssi::settings_get_bool('uberprompt_debug');
+
+ $init_callbacks = {
+ load => Irssi::settings_get_str('uberprompt_load_hook'),
+ unload => Irssi::settings_get_str('uberprompt_unload_hook'),
+ };
+
+ if (DEBUG) {
+ Irssi::signal_add 'prompt changed', 'debug_prompt_changed';
+ } else {
+ Irssi::signal_remove 'prompt changed', 'debug_prompt_changed';
+ }
+
+ my $new = Irssi::settings_get_str('uberprompt_format');
+
+ if ($prompt_format ne $new) {
+ _debug_print("Updated prompt format");
+ $prompt_format = $new;
+ $prompt_format =~ s/\$uber/\$\$uber/;
+ Irssi::abstracts_register(['uberprompt', $prompt_format]);
+
+ $expando_vars = {};
+
+ # TODO: something clever here to check if we need to schedule
+ # an update timer or something, rather than just refreshing on
+ # every possible activity in init()
+ while ($prompt_format =~ m/(?<!\$)(\$[A-Za-z,.:;][a-z_]*)/g) {
+ _debug_print("Detected Irssi expando variable $1");
+ my $var_name = substr $1, 1; # strip the $
+ $expando_vars->{$var_name} = Irssi::parse_special($1);
+ }
+ }
+
+ $new = Irssi::settings_get_str('uberprompt_format_empty');
+
+ if ($prompt_format_empty ne $new) {
+ _debug_print("Updated prompt format");
+ $prompt_format_empty = $new;
+ $prompt_format_empty =~ s/\$uber/\$\$uber/;
+ Irssi::abstracts_register(['uberprompt_empty', $prompt_format_empty]);
+
+ $expando_vars = {};
+
+ # TODO: something clever here to check if we need to schedule
+ # an update timer or something, rather than just refreshing on
+ # every possible activity in init()
+ while ($prompt_format_empty =~ m/(?<!\$)(\$[A-Za-z,.:;][a-z_]*)/g) {
+ _debug_print("Detected Irssi expando variable $1");
+ my $var_name = substr $1, 1; # strip the $
+ $expando_vars->{$var_name} = Irssi::parse_special($1);
+ }
+ }
+
+ $trim_data = Irssi::settings_get_bool('uberprompt_trim_data');
+}
+
+sub debug_prompt_changed {
+ my ($text, $len) = @_;
+
+ $text =~ s/%/%%/g;
+
+ print "DEBUG_HANDLER: Prompt Changed to: \"$text\", length: $len";
+}
+
+sub change_prompt_handler {
+ my ($text, $pos) = @_;
+
+ # fix for people who used prompt_info and hence the signal won't
+ # pass the second argument.
+ $pos = 'UP_INNER' unless defined $pos;
+ _debug_print("Got prompt change signal with: $text, $pos");
+
+ my ($changed_text, $changed_pos);
+ $changed_text = defined $prompt_data ? $prompt_data ne $text : 1;
+ $changed_pos = defined $prompt_data_pos ? $prompt_data_pos ne $pos : 1;
+
+ $prompt_data = $text;
+ $prompt_data_pos = $pos;
+
+ if ($changed_text || $changed_pos) {
+ _debug_print("Redrawing prompt");
+ uberprompt_refresh();
+ }
+}
+
+sub _escape_prompt_special {
+ my $str = shift;
+ $str =~ s/\$/\$\$/g;
+ $str =~ s/\\/\\\\/g;
+ #$str =~ s/%/%%/g;
+ $str =~ s/{/\${lbrace}/g;
+ $str =~ s/}/\${rbrace}/g;
+
+ return $str;
+}
+
+sub uberprompt_render_prompt {
+
+ my $window = Irssi::active_win;
+ my $prompt_arg = '';
+
+ # default prompt sbar arguments (from config)
+ if (scalar( () = $window->items )) {
+ $prompt_arg = '$[.15]{itemname}';
+ } else {
+ $prompt_arg = '${winname}';
+ }
+
+ my $prompt = ''; # rendered content of the prompt.
+ my $theme = Irssi::current_theme;
+
+ my $arg = $use_replaces ? 0 : Irssi::EXPAND_FLAG_IGNORE_REPLACES;
+
+ if ($prompt_data && (!$trim_data || trim($prompt_data))) {
+ $prompt = $theme->format_expand("{uberprompt $prompt_arg}", $arg);
+ }
+ else {
+ $prompt = $theme->format_expand("{uberprompt_empty $prompt_arg}", $arg);
+ }
+
+ if ($prompt_data_pos eq 'UP_ONLY') {
+ $prompt =~ s/\$\$uber//; # no need for recursive prompting, I hope.
+
+ # TODO: only compute this if necessary?
+ my $prompt_nt = $prompt;
+ $prompt_nt =~ s/\s+$//;
+
+ my $pdata_copy = $prompt_data;
+
+ $pdata_copy =~ s/\$prompt_nt/$prompt_nt/;
+ $pdata_copy =~ s/\$prompt/$prompt/;
+
+ $prompt = $pdata_copy;
+
+ } elsif ($prompt_data_pos eq 'UP_INNER' && defined $prompt_data) {
+
+ my $esc = _escape_prompt_special($prompt_data);
+ $esc = $trim_data ? trim($esc) : $esc;
+ $prompt =~ s/\$\$uber/$esc/;
+
+ } else {
+ # remove the $uber marker
+ $prompt =~ s/\$\$uber//;
+
+ # and add the additional text at the appropriate position.
+ if ($prompt_data_pos eq 'UP_PRE') {
+ $prompt = $prompt_data . $prompt;
+ } elsif ($prompt_data_pos eq 'UP_POST') {
+ $prompt .= $prompt_data;
+ }
+ }
+
+ _debug_print("rendering with: $prompt");
+
+
+ if (($prompt ne $prompt_last) or $emit_request) {
+
+ # _debug_print("Emitting prompt changed signal");
+ # my $exp = Irssi::current_theme()->format_expand($text, 0);
+ my $ps = Irssi::parse_special($prompt);
+
+ Irssi::signal_emit('prompt changed', $ps, length($ps));
+ $prompt_last = $prompt;
+ }
+ return $prompt;
+}
+
+sub uberprompt_draw {
+ my ($sb_item, $get_size_only) = @_;
+
+ my $prompt = uberprompt_render_prompt();
+
+ my $ret = $sb_item->default_handler($get_size_only, $prompt, '', 0);
+ _debug_print("redrawing with: $prompt");
+ return $ret;
+}
+
+sub uberprompt_refresh {
+ Irssi::statusbar_items_redraw('uberprompt');
+}
+
+my $prompt_items_replaced;
+
+sub replace_prompt_items {
+ unless ($prompt_items_replaced) {
+ $prompt_items_replaced = 1;
+
+ # add the new one.
+ _sbar_command('prompt', 'add', 'uberprompt',
+ qw/-alignment left -after prompt_empty -priority '-1'/);
+
+ # remove existing ones.
+ _debug_print("Removing original prompt");
+
+ _sbar_command('prompt', 'remove', 'prompt');
+ _sbar_command('prompt', 'remove', 'prompt_empty');
+
+ }
+
+ my $load_hook = $init_callbacks->{load};
+ if (defined $load_hook and length $load_hook) {
+ eval {
+ Irssi::command($load_hook);
+ };
+ if ($@) {
+ _error("Uberprompt user load-hook command ($load_hook) failed: $@");
+ }
+ }
+
+}
+
+sub restore_prompt_items {
+ if ($prompt_items_replaced) {
+ $prompt_items_replaced = undef;
+
+ _debug_print("Restoring original prompt");
+
+ _sbar_command('prompt', 'add', 'prompt',
+ qw/-alignment left -after uberprompt -priority '-1'/);
+ _sbar_command('prompt', 'add', 'prompt_empty',
+ qw/-alignment left -after prompt -priority '-1'/);
+
+ _sbar_command('prompt', 'remove', 'uberprompt');
+
+ }
+
+ my $unload_hook = $init_callbacks->{unload};
+
+ if (defined $unload_hook and length $unload_hook) {
+ eval {
+ Irssi::command($unload_hook);
+ };
+ if ($@) {
+ _error("Uberprompt user unload-hook command ($unload_hook) failed: $@");
+ }
+ }
+}
+
+sub _sbar_command {
+ my ($bar, $cmd, $item, @args) = @_;
+
+ my $args_str = join ' ', @args;
+
+ $args_str .= ' ' if length $args_str && defined $item;
+
+ my $command = sprintf 'STATUSBAR %s %s %s%s',
+ $bar, $cmd, $args_str, defined $item ? $item : '';
+
+ _debug_print("Running command: $command");
+ Irssi::command($command);
+}
+
+sub trim {
+ my $string = shift;
+
+ $string =~ s/^\s*//;
+ $string =~ s/\s*$//;
+
+ return $string;
+}