aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Feist <shabble@cowu.be>2010-07-10 00:37:55 +0000
committerTom Feist <shabble@cowu.be>2010-07-10 00:37:55 +0000
commit243c4e2b34cedafb7b66c11af384090417b2cc06 (patch)
tree3aa655d6f775d774cb01ca5bb32004239df3aedf
parentadded a build script for POD to html (diff)
downloadirssi-scripts-243c4e2b34cedafb7b66c11af384090417b2cc06.tar.gz
irssi-scripts-243c4e2b34cedafb7b66c11af384090417b2cc06.zip
migrated quite a lot of the perl.txt into individual modules
-rw-r--r--docs/Irssi.pm286
-rw-r--r--docs/Signals.pm467
-rw-r--r--docs/perl.txt424
-rw-r--r--docs/signals.txt78
-rw-r--r--patches/irssi-svn-r5174-no_act_ignore.patch161
5 files changed, 908 insertions, 508 deletions
diff --git a/docs/Irssi.pm b/docs/Irssi.pm
index c52fbc5..263d124 100644
--- a/docs/Irssi.pm
+++ b/docs/Irssi.pm
@@ -2,6 +2,8 @@ __END__
=head1 NAME
+Irssi.pm
+
=head1 DESCRIPTION
=head1 CLASSES
@@ -14,23 +16,182 @@ __END__
=item C<Irssi::active_win> -- returns the currently active L<Irssi::Window> object.
+=item Window active_win() - return active window
+
+=item Server active_server() - return server in active window
+
+=item windows() - return list of all windows
+=item servers() - return list of all servers
+=item reconnects() - return list of all server reconnections
+=item channels() - return list of all channels
+
+=item queries() - return list of all queries
+
+=item commands() - return list of all commands
+
+=item logs() - return list of all log files
+
+=item ignores() - returns list of all ignores
+
=back
+
=head2 Signals
+Irssi is pretty much based on sending and handling different signals.
+Like when you receive a message from server, say:
+
+C<:nick!user@there.org PRIVMSG you :blahblah>
+
+Irssi will first send a signal:
+
+C<"server incoming", SERVER_REC, "nick!user@there PRIVMSG ...">
+
+You probably don't want to use this signal. Default handler for this
+signal interprets the header and sends a signal:
+
+C<"server event", SERVER_REC, "PRIVMSG ...", "nick", "user@there.org">
+
+You probably don't want to use this either, since this signal's default
+handler parses the event string and sends a signal:
+
+C<"event privmsg", SERVER_REC, "you :blahblah", "nick", "user@there.org">
+
+You can at any point grab the signal, do whatever you want to do with
+it and optionally stop it from going any further by calling
+L<Irssi::signal_stop()|Irssi/signal_stop>
+
+For example:
+
+ sub event_privmsg {
+ # $data = "nick/#channel :text"
+ my ($server, $data, $nick, $address) = @_;
+ my ($target, $text) = split(/ :/, $data, 2);
+
+ Irssi::signal_stop() if ($text =~ /free.*porn/ || $nick =~ /idiot/);
+ }
+
+ Irssi::signal_add("event privmsg", "event_privmsg");
+
+This will hide all public or private messages that match the regexp
+C<"free.*porn"> or the sender's nick contain the word "idiot". Yes, you
+could use /IGNORE instead for both of these C<:)>
+
+You can also use L<C<signal_add_last()>|/signal_add_last> if you wish to let the
+Irssi's internal functions be run before yours.
+
+A list of signals that irssi sends can be found in the L<Signals> documentation.
+
+
+
+
=head3 Handling Signals
+=head4 C<signal_add($sig_name, $func)>
+
+Bind C<$sig_name>' to function C<$func>. The C<$func> argument may be either
+a string containing the name of a function to call, or a coderef.
+
+For example:
+
+ Irssi::signal_add("default command", sub { ... });
+
+ Irssi::signal_add("default command", "my_function");
+
+ Irssi::signal_add("default command", \&my_function);
+
+In all cases, the specified function will be passed arguments in C<@_> as specified
+in L<Signals>.
+
+=head4 C<signal_add_first($sig_name, $func)>
+
+Bind `signal' to function `func'. Call `func' as soon as possible.
+
+=head4 C<signal_add_last(signal, func)>
+
+Bind `signal' to function `func'. Call `func' as late as possible.
+
+=head4 C<signal_remove(signal, func)>
+
+Unbind `signal' from function `func'.
+
=head3 Controlling Signal Propagation
+=head4 C<signal_emit(signal, ...)>
+
+Send signal `signal'. You can give 6 parameters at maximum.
+
+=head4 C<signal_continue(...)>
+
+Continue currently emitted signal with different parameters.
+
+=head4 C<signal_stop()>
+
+Stop the signal that's currently being emitted.
+
+=head4 C<signal_stop_by_name(signal)>
+
+Stop the signal with name `signal' that's currently being emitted.
+
=head3 Registering New Signals
+=head4 C<signal_register(%hashref)>
+
+Register parameter types for one or more signals.
+C<%hash> must map one or more signal names to references to arrays
+containing 0 to 6 type names. Some recognized type names include
+int for integers, intptr for references to integers and string for
+strings. For all standard signals see src/perl/perl-signals-list.h
+in the source code (this is generated by src/perl/get-signals.pl).
+
+For example:
+ my $signal_config_hash = { "new signal" => [ qw/string string integer/ ] };
+ Irssi::signal_register($signal_config_hash);
+Any signals that were already registered are unaffected.
+
+B<Signals are not persistent.> Once registered, a signal cannot be unregistered without
+restarting Irssi. B<TODO: True?>, including modifying the type signature.
+
+Registration is required to get any parameters to signals written in
+Perl and to emit and continue signals from Perl.
=head2 Commands
+See also L<Irssi::Command>
+
+command_bind(cmd, func[, category])
+ Bind command `cmd' to call function `func'. `category' is the
+ category where the command is displayed in /HELP.
+
+command_runsub(cmd, data, server, item)
+ Run subcommands for `cmd'. First word in `data' is parsed as
+ subcommand. `server' is Irssi::Server rec for current
+ Irssi::Windowitem `item'.
+
+ Call command_runsub in handler function for `cmd' and bind
+ with command_bind("`cmd' `subcmd'", subcmdfunc[, category]);
+
+command_unbind(cmd, func)
+ Unbind command `cmd' from function `func'.
+
+command_set_options(cmd, data)
+ Set options for command `cmd' to `data'. `data' is a string of
+ space separated words which specify the options. Each word can be
+ optionally prefixed with one of the following character:
+
+ '-': optional argument
+ '+': argument required
+ '@': optional numeric argument
+
+command_parse_options(cmd, data)
+ Parse options for command `cmd' in `data'. It returns a reference to
+ an hash table with the options and a string with the remaining part
+ of `data'. On error it returns the undefined value.
+
=head3 Registering Commands
=head3 Invoking Commands
@@ -41,12 +202,135 @@ __END__
=head2 Settings
+
=head3 Creating New Settings
+=head4 C<settings_add_str(section, key, def)>
+
+=head4 C<settings_add_int(section, key, def)>
+
+=head4 C<settings_add_bool(section, key, def)>
+
+=head4 C<settings_add_time(section, key, def)>
+
+=head4 C<settings_add_level(section, key, def)>
+
+=head4 C<settings_add_size(section, key, def)>
+
+
=head3 Retrieving Settings
+=head4 C<settings_get_str($key)>
+
+=head4 C<settings_get_int($key)>
+
+=head4 C<settings_get_bool($key)>
+
+=head4 C<settings_get_time($key)>
+
+=head4 C<settings_get_level($key)>
+
+=head4 C<settings_get_size($key)>
+
=head3 Modifying Settings
+Set value for setting.
+
+B<If you change the settings of another module/script with one of these, you
+must emit a C<"setup changed"> signal afterwards.>
+
+=head4 C<settings_set_str(key, value)>
+
+=head4 C<settings_set_int(key, value)>
+
+=head4 C<settings_set_bool(key, value)>
+
+=head4 C<settings_set_time(key, value)>
+
+=head4 C<settings_set_level(key, value)>
+
+=head4 C<settings_set_size(key, value)>
+
+=head4 C<settings_remove(key)>
+
+Remove a setting.
+
+
+=head2 IO and Process Management
+
+timeout_add(msecs, func, data)
+ Call `func' every `msecs' milliseconds (1000 = 1 second) with
+ parameter `data'. Returns tag which can be used to stop the timeout.
+
+timeout_add_once(msecs, func, data);
+ Call `func' once after `msecs' milliseconds (1000 = 1 second)
+ with parameter `data'. Returns tag which can be used to stop the timeout.
+
+timeout_remove(tag)
+ Remove timeout with tag.
+
+input_add(source, condition, func, data)
+ Call `func' with parameter `data' when specified IO happens.
+ `source' is the file handle that is being listened. `condition' can
+ be INPUT_READ, INPUT_WRITE or both. Returns tag which can be used to
+ remove the listener.
+
+input_remove(tag)
+ Remove listener with tag.
+
+pidwait_add(pid)
+ Adds `pid' to the list of processes to wait for. The pid must identify
+ a child process of the irssi process. When the process terminates, a
+ "pidwait" signal will be sent with the pid and the status from
+ waitpid(). This is useful to avoid zombies if your script forks.
+
+pidwait_remove(pid)
+ Removes `pid' from the list of processes to wait for. Terminated
+ processes are removed automatically, so it is usually not necessary
+ to call this function.
+
+
+
+=head2 Message Levels
+
+level2bits(level)
+ Level string -> number
+
+bits2level(bits)
+ Level number -> string
+
+combine_level(level, str)
+ Combine level number to level string ("+level -level").
+ Return new level number.
+
+
+=head2 Themes
+
+You can have user configurable texts in scripts that work just like
+irssi's internal texts that can be changed in themes.
+
+First you'll have to register the formats:
+
+Irssi::theme_register([
+ 'format_name', '{hilight my perl format!}',
+ 'format2', 'testing.. nick = $0, channel = $1'
+]);
+
+Printing happens with one of the functions:
+
+printformat(level, format, ...)
+Window::printformat(level, format, ...)
+Server::printformat(target, level, format, ...)
+Windowitem::printformat(level, format, ...)
+
+For example:
+
+ $channel->printformat(MSGLEVEL_CRAP, 'format2',
+ 'nick', $channel->{name});
+
+=head1 COPYRIGHT
+All the content of this site is copyright © 2000-2010 The Irssi project.
-=head2 blahblah
+Formatting to POD and linking by Tom Feist
+ L<shabble+irssi@metavore.org|mailto:shabble+irssi@metavore.org>
diff --git a/docs/Signals.pm b/docs/Signals.pm
index 0ea689f..d6d3ec9 100644
--- a/docs/Signals.pm
+++ b/docs/Signals.pm
@@ -20,29 +20,486 @@ have been revised to note Perl variable types and class names.
Arguments are passed to signal handlers in the usual way, via C<@_>.
+
+
=head2 Core
=over 4
-=item C<"gui exit"> I<None>
+=item C<"gui exit">
+I<None>
-=item C<"gui dialog" string $type, string $text>
+=item C<"gui dialog">
+ string C<$type>, string C<$text>
=item C<"send command">
-C<string $command, Irssi::Server $server, Irssi::Windowitem
-$window_item>
+ C<string $command> L<Irssi::Server> C<$server>, L<Irssi::Windowitem>
+ C<$window_item>
+
+=back
+
+=head3 F<chat-protocols.c>:
+
+B<TODO: What are CHAT_PROTOCOL_REC types?>
+
+=over 4
+
+=item C<"chat protocol created"> CHAT_PROTOCOL_REC
+
+=item C<"chat protocol updated"> CHAT_PROTOCOL_REC
+
+=item C<"chat protocol destroyed"> CHAT_PROTOCOL_REC
+
+=back
+
+=head3 F<channels.c>:
+
+=over 4
+
+=item C<"channel created"> L<Irssi::Channel>, int C<$automatic>
+
+=item C<"channel destroyed"> L<Irssi::Channel> C<$channel>
+
+=back
+
+=head3 F<chatnets.c>:
+
+=over 4
+
+=item C<"chatnet created"> CHATNET_REC
+
+=item C<"chatnet destroyed"> CHATNET_REC
+
+=back
+
+=head3 F<commands.c>:
+
+=over 4
+
+=item C<"commandlist new">, L<Irssi::Command> C<$cmd>
+
+=item C<"commandlist remove"> L<Irssi::Command> C<$cmd>
+
+=item C<"error command"> int C<$err>, string C<$cmd>
+
+=item C<"send command"> string C<$args>,
+ L<Irssi::Server> C<$server>, L<Irssi::Windowitem> C<$witem>
+
+=item C<"send text"> string C<$line>, L<Irssi::Server> C<$server>,
+ L<Irssi::Windowitem> C<$witem>
+
+=item C<"command "<cmd>> string C<$args>, L<Irssi::Server> C<$server>,
+ L<Irssi::Windowitem> C<$witem>
+
+B<TODO: check this "cmd" out?>
+
+=item C<"default command"> string C<$args>, L<Irssi::Server> C<$server>,
+ L<Irssi::Windowitem> C<$witem>
+
+=back
+
+=head3 F<ignore.c>:
+
+=over 4
+
+=item C<"ignore created"> L<Irssi::Ignore> C<$ignore>
+
+=item C<"ignore destroyed"> L<Irssi::Ignore> C<$ignore>
+
+=item C<"ignore changed"> L<Irssi::Ignore> C<$ignore>
+
+=back
+
+=head3 F<log.c>:
+
+=over 4
+
+=item C<"log new"> L<Irssi::Log> C<$log>
+
+=item C<"log remove"> L<Irssi::Log> C<$log>
+
+=item C<"log create failed"> L<Irssi::Log> C<$log>
+
+=item C<"log locked"> L<Irssi::Log> C<$log>
+
+=item C<"log started"> L<Irssi::Log> C<$log>
+
+=item C<"log stopped"> L<Irssi::Log> C<$log>
+
+=item C<"log rotated"> L<Irssi::Log> C<$log>
+
+=item C<"log written"> L<Irssi::Log> C<$log>, string C<$line>
+
+=back
+
+=head3 F<modules.c>:
+
+B<TODO: what are these types?>
+
+=over 4
+
+=item "module loaded", MODULE_REC, MODULE_FILE_REC
+
+=item "module unloaded", MODULE_REC, MODULE_FILE_REC
+
+=item "module error", int error, char *text, char *rootmodule, char *submodule
+
+=back
+
+=head3 F<nicklist.c>:
+
+=over 4
+
+=item C<"nicklist new"> L<Irssi::Channel> C<$channel>, L<Irssi::Nick> C<$nick>
+
+=item "nicklist remove", CHANNEL_REC, NICK_REC
+
+=item "nicklist changed", CHANNEL_REC, NICK_REC, char *old_nick
+
+=item "nicklist host changed", CHANNEL_REC, NICK_REC
+
+=item "nicklist gone changed", CHANNEL_REC, NICK_REC
+
+=item "nicklist serverop changed", CHANNEL_REC, NICK_REC
+
+=back
+
+=head3 pidwait.c:
+
+=over 4
+
+=item "pidwait", int pid, int status
+
+=back
+
+=head3 queries.c:
+
+=over 4
+
+=item "query created", QUERY_REC, int automatic
+
+=item "query destroyed", QUERY_REC
+
+=item "query nick changed", QUERY_REC, char *orignick
+
+=item "window item name changed", WI_ITEM_REC
+
+=item "query address changed", QUERY_REC
+
+=item "query server changed", QUERY_REC, SERVER_REC
+
+=back
+
+
+=head3 rawlog.c:
+
+=over 4
+
+=item "rawlog", RAWLOG_REC, char *data
+
+=back
+
+=head3 server.c:
+
+=over 4
+
+=item "server looking", SERVER_REC
+
+=item "server connected", SERVER_REC
+
+=item "server connecting", SERVER_REC, ulong *ip
+
+=item "server connect failed", SERVER_REC
+
+=item "server disconnected", SERVER_REC
+
+=item "server quit", SERVER_REC, char *msg
+
+=item "server sendmsg", SERVER_REC, char *target, char *msg, int target_type
+
+=back
+
+=head3 settings.c:
+
+=over 4
+
+=item "setup changed"
+
+=item "setup reread", char *fname
+
+=item "setup saved", char *fname, int autosaved
=back
=head2 IRC Core
-=head2 IRC Module
+=head3 bans.c:
+
+ "ban type changed", char *bantype
+
+=head3 channels, nicklist:
+
+ "channel joined", CHANNEL_REC
+ "channel wholist", CHANNEL_REC
+ "channel sync", CHANNEL_REC
+
+ "channel topic changed", CHANNEL_REC
+
+=head3 ctcp.c:
+
+ "ctcp msg", SERVER_REC, char *args, char *nick, char *addr, char *target
+ "ctcp msg "<cmd>, SERVER_REC, char *args, char *nick, char *addr, char *target
+ "default ctcp msg", SERVER_REC, char *args, char *nick, char *addr, char *target
+ "ctcp reply", SERVER_REC, char *args, char *nick, char *addr, char *target
+ "ctcp reply "<cmd>, SERVER_REC, char *args, char *nick, char *addr, char *target
+ "default ctcp reply", SERVER_REC, char *args, char *nick, char *addr, char *target
+ "ctcp action", SERVER_REC, char *args, char *nick, char *addr, char *target
+
+=head3 irc-log.c:
+
+ "awaylog show", LOG_REC, int away_msgs, int filepos
+
+=head3 irc-nicklist.c:
+
+ "server nick changed", SERVER_REC
+
+=head3 irc-servers.c:
+
+ "event connected", SERVER_REC
+
+=head3 irc.c:
+
+ "server event", SERVER_REC, char *data, char *sender_nick, char *sender_address
+ "event "<cmd>, SERVER_REC, char *args, char *sender_nick, char *sender_address
+ "default event", SERVER_REC, char *data, char *sender_nick, char *sender_address
+ "whois default event", SERVER_REC, char *args, char *sender_nick, char *sender_address
+
+ "server incoming", SERVER_REC, char *data
+
+(for perl parser..)
+ "redir "<cmd>, SERVER_REC, char *args, char *sender_nick, char *sender_address
+
+=head3 lag.c:
+
+ "server lag", SERVER_REC
+ "server lag disconnect", SERVER_REC
+
+=head3 massjoin.c:
+
+ "massjoin", CHANNEL_REC, GSList of NICK_RECs
+
+=head3 mode-lists.c:
+
+ "ban new", CHANNEL_REC, BAN_REC
+ "ban remove", CHANNEL_REC, BAN_REC, char *setby
+
+=head3 modes.c:
+
+ "channel mode changed", CHANNEL_REC, char *setby
+ "nick mode changed", CHANNEL_REC, NICK_REC, char *setby, char *mode, char *type
+ "user mode changed", SERVER_REC, char *old
+ "away mode changed", SERVER_REC
+
+=head3 netsplit.c:
+
+ "netsplit server new", SERVER_REC, NETSPLIT_SERVER_REC
+ "netsplit server remove", SERVER_REC, NETSPLIT_SERVER_REC
+ "netsplit new", NETSPLIT_REC
+ "netsplit remove", NETSPLIT_REC
+
+
+=head2 IRC Modules
+
+
+=head3 dcc*.c:
+
+ "dcc ctcp "<cmd>, char *args, DCC_REC
+ "default dcc ctcp", char *args, DCC_REC
+ "dcc unknown ctcp", char *args, char *sender, char *sendaddr
+
+ "dcc reply "<cmd>, char *args, DCC_REC
+ "default dcc reply", char *args, DCC_REC
+ "dcc unknown reply", char *args, char *sender, char *sendaddr
+
+ "dcc chat message", DCC_REC, char *msg
+
+ "dcc created", DCC_REC
+ "dcc destroyed", DCC_REC
+ "dcc connected", DCC_REC
+ "dcc rejecting", DCC_REC
+ "dcc closed", DCC_REC
+ "dcc request", DCC_REC, char *sendaddr
+ "dcc request send", DCC_REC
+ "dcc chat message", DCC_REC, char *msg
+ "dcc transfer update", DCC_REC
+ "dcc get receive", DCC_REC
+ "dcc error connect", DCC_REC
+ "dcc error file create", DCC_REC, char *filename
+ "dcc error file open", char *nick, char *filename, int errno
+ "dcc error get not found", char *nick
+ "dcc error send exists", char *nick, char *filename
+ "dcc error unknown type", char *type
+ "dcc error close not found", char *type, char *nick, char *filename
+
+=head3 autoignore.c:
+
+ "autoignore new", SERVER_REC, AUTOIGNORE_REC
+ "autoignore remove", SERVER_REC, AUTOIGNORE_REC
+
+=head3 flood.c:
+
+ "flood", SERVER_REC, char *nick, char *host, int level, char *target
+
+=head3 notifylist.c:
+
+ "notifylist new", NOTIFYLIST_REC
+ "notifylist remove", NOTIFYLIST_REC
+ "notifylist joined", SERVER_REC, char *nick, char *user, char *host, char *realname, char *awaymsg
+ "notifylist away changed", SERVER_REC, char *nick, char *user, char *host, char *realname, char *awaymsg
+ "notifylist left", SERVER_REC, char *nick, char *user, char *host, char *realname, char *awaymsg
+
+=head3 proxy/listen.c:
+
+ "proxy client connected", CLIENT_REC
+ "proxy client disconnected", CLIENT_REC
+ "proxy client command", CLIENT_REC, char *args, char *data
+ "proxy client dump", CLIENT_REC, char *data
+
=head2 Display (FE) Common
+B<Requires to work properly:>
+
+ "gui print text", WINDOW_REC, int fg, int bg, int flags, char *text, TEXT_DEST_REC
+
+(Can be used to determine when all "gui print text"s are sent (not required))
+ "gui print text finished", WINDOW_REC
+
+B<Provides signals:>
+
+=head3 completion.c:
+
+ "complete word", GList * of char*, WINDOW_REC, char *word, char *linestart, int *want_space
+
+=head3 fe-common-core.c:
+
+ "irssi init read settings"
+
+=head3 fe-exec.c:
+
+ "exec new", PROCESS_REC
+ "exec remove", PROCESS_REC, int status
+ "exec input", PROCESS_REC, char *text
+
+=head3 fe-messages.c:
+
+ "message public", SERVER_REC, char *msg, char *nick, char *address, char *target
+ "message private", SERVER_REC, char *msg, char *nick, char *address
+ "message own_public", SERVER_REC, char *msg, char *target
+ "message own_private", SERVER_REC, char *msg, char *target, char *orig_target
+ "message join", SERVER_REC, char *channel, char *nick, char *address
+ "message part", SERVER_REC, char *channel, char *nick, char *address, char *reason
+ "message quit", SERVER_REC, char *nick, char *address, char *reason
+ "message kick", SERVER_REC, char *channel, char *nick, char *kicker, char *address, char *reason
+ "message nick", SERVER_REC, char *newnick, char *oldnick, char *address
+ "message own_nick", SERVER_REC, char *newnick, char *oldnick, char *address
+ "message invite", SERVER_REC, char *channel, char *nick, char *address
+ "message topic", SERVER_REC, char *channel, char *topic, char *nick, char *address
+
+=head3 keyboard.c:
+
+ "keyinfo created", KEYINFO_REC
+ "keyinfo destroyed", KEYINFO_REC
+
+=head3 printtext.c:
+
+ "print text", TEXT_DEST_REC *dest, char *text, char *stripped
+
+=head3 themes.c:
+
+ "theme created", THEME_REC
+ "theme destroyed", THEME_REC
+
+=head3 window-activity.c:
+
+ "window hilight", WINDOW_REC
+ "window dehilight", WINDOW_REC
+ "window activity", WINDOW_REC, int old_level
+ "window item hilight", WI_ITEM_REC
+ "window item activity", WI_ITEM_REC, int old_level
+
+=head3 window-items.c:
+
+ "window item new", WINDOW_REC, WI_ITEM_REC
+ "window item remove", WINDOW_REC, WI_ITEM_REC
+ "window item moved", WINDOW_REC, WI_ITEM_REC, WINDOW_REC
+ "window item changed", WINDOW_REC, WI_ITEM_REC
+ "window item server changed", WINDOW_REC, WI_ITEM_REC
+
+=head3 windows.c:
+
+ "window created", WINDOW_REC
+ "window destroyed", WINDOW_REC
+ "window changed", WINDOW_REC, WINDOW_REC old
+ "window changed automatic", WINDOW_REC
+ "window server changed", WINDOW_REC, SERVER_REC
+ "window refnum changed", WINDOW_REC, int old
+ "window name changed", WINDOW_REC
+ "window history changed", WINDOW_REC, char *oldname
+ "window level changed", WINDOW_REC
+
=head2 Display (FE) IRC
+=head3 fe-events.c:
+
+ "default event numeric", SERVER_REC, char *data, char *nick, char *address
+
+=head3 fe-irc-messages.c:
+
+ "message irc op_public", SERVER_REC, char *msg, char *nick, char *address, char *target
+ "message irc own_wall", SERVER_REC, char *msg, char *target
+ "message irc own_action", SERVER_REC, char *msg, char *target
+ "message irc action", SERVER_REC, char *msg, char *nick, char *address, char *target
+ "message irc own_notice", SERVER_REC, char *msg, char *target
+ "message irc notice", SERVER_REC, char *msg, char *nick, char *address, char *target
+ "message irc own_ctcp", SERVER_REC, char *cmd, char *data, char *target
+ "message irc ctcp", SERVER_REC, char *cmd, char *data, char *nick, char *address, char *target
+
+=head3 fe-modes.c:
+
+ "message irc mode", SERVER_REC, char *channel, char *nick, char *addr, char *mode
+
+=head3 dcc/fe-dcc-chat-messages.c:
+
+ "message dcc own", DCC_REC *dcc, char *msg
+ "message dcc own_action", DCC_REC *dcc, char *msg
+ "message dcc own_ctcp", DCC_REC *dcc, char *cmd, char *data
+ "message dcc", DCC_REC *dcc, char *msg
+ "message dcc action", DCC_REC *dcc, char *msg
+ "message dcc ctcp", DCC_REC *dcc, char *cmd, char *data
+
=head2 Display (FE) Text
+=head3 F<gui-readline.c>:
+
+=over 4
+
+=item C<"gui key pressed"> int C<$key>
+
+=back
+
+=head3 F<gui-printtext.c>:
+
+=over 4
+
+=item C<"beep"> I<None>
+
+=back
+
=head2 Perl Scripting
+=over 4
+
+=item C<"script error"> PERL_SCRIPT_REC, string C<$errormsg>
+
+=back
diff --git a/docs/perl.txt b/docs/perl.txt
index dd72623..309a808 100644
--- a/docs/perl.txt
+++ b/docs/perl.txt
@@ -1,27 +1,3 @@
-
-
- * bugs
- * support
- * news
- * documentation
- * download
- * about
- * themes
- * scripts
-
-What's this?
-
-You are visiting the official website for the IRC client Irssi, for more information see the about section.
-Search this site
-
-Search function coming soon!
-
-
-What's new?
-
-Irssi 0.8.15 has been released and the new website will be released in a few weeks!
-Perl Scripting Reference
-
Installation problems
---------------------
@@ -43,54 +19,6 @@ installed) directories. After that /RUN script_name should work, you
don't need to add the .pl suffix.
- Irssi's signals
- ---------------
-
-Irssi is pretty much based on sending and handling different signals.
-Like when you receive a message from server, say
-
- :nick!user@there.org PRIVMSG you :blahblah
-
-Irssi will first send a signal:
-
- "server incoming", SERVER_REC, "nick!user@there PRIVMSG ..."
-
-You probably don't want to use this signal. Default handler for this
-signal interprets the header and sends a signal:
-
- "server event", SERVER_REC, "PRIVMSG ...", "nick", "user@there.org"
-
-You probably don't want to use this either, since this signal's default
-handler parses the event string and sends a signal:
-
- "event privmsg", SERVER_REC, "you :blahblah", "nick", "user@there.org"
-
-You can at any point grab the signal, do whatever you want to do with
-it and optionally stop it from going any further by calling
-Irssi::signal_stop();
-
-For example:
-
- sub event_privmsg {
- # $data = "nick/#channel :text"
- my ($server, $data, $nick, $address) = @_;
- my ($target, $text) = split(/ :/, $data, 2);
-
- Irssi::signal_stop() if ($text =~ /free.*porn/ || $nick =~ /idiot/);
- }
-
-Irssi::signal_add("event privmsg", "event_privmsg")
-
-This will hide all public or private messages that match the regexp
-"free.*porn" or the sender's nick contain the word "idiot". Yes, you
-could use /IGNORE instead for both of these :)
-
-You can also use signal_add_last() if you wish to let the Irssi's internal
-functions be run before yours.
-
-A list of signals that irssi sends can be found from signals.txt file.
-
-
Creating/replacing /COMMANDS
----------------------------
@@ -157,21 +85,6 @@ You can use them with a MSGLEVEL_ prefix, for example:
Writes text to #channel window with CLIENTCRAP level.
- Window items
- ------------
-
-Meaning of "window" should be pretty clear, but "window item" is
-something I couldn't really figure out a better name for :) They're
-simply something that's inside a window, a channel or a query usually.
-Windows can have multiple items inside them. It's possible to create
-non-channel/query window items too, currently the third possible window
-item is created by /EXEC -interactive.
-
-In scripts, I think you can quite safely assume that the window item is
-query or channel if the script is intended to be run in one of them.
-Stupid users won't probably have other window items, and smart users
-know where to run the script, or at least later figure out why it
-didn't work :)
Functions that you can use in Irssi's Perl scripts
@@ -199,289 +112,40 @@ listed after the generic ones.
*** General
-Window active_win() - return active window
-Server active_server() - return server in active window
-
-windows() - return list of all windows
-servers() - return list of all servers
-reconnects() - return list of all server reconnections
-channels() - return list of all channels
-queries() - return list of all queries
-commands() - return list of all commands
-logs() - return list of all log files
-ignores() - returns list of all ignores
-Server::channels() - return list of channels in server
-Server::queries() - return list of queries in server
print(str[, level])
-Server::print(channel, str[, level])
-Window::print(str[, level])
-Windowitem::print(str[, level])
Print `str'. Default level is MSGLEVEL_CLIENTNOTICE.
command(cmd)
-Server::command(cmd)
-Window::command(cmd)
-Windowitem::command(cmd)
Send a command `cmd' (in current channel). The '/' char isn't needed.
*** Themes
-You can have user configurable texts in scripts that work just like
-irssi's internal texts that can be changed in themes.
-
-First you'll have to register the formats:
-
-Irssi::theme_register([
- 'format_name', '{hilight my perl format!}',
- 'format2', 'testing.. nick = $0, channel = $1'
-]);
-
-Printing happens with one of the functions:
-
-printformat(level, format, ...)
-Window::printformat(level, format, ...)
-Server::printformat(target, level, format, ...)
-Windowitem::printformat(level, format, ...)
-
-For example:
-
- $channel->printformat(MSGLEVEL_CRAP, 'format2',
- 'nick', $channel->{name});
*** Settings
-settings_get_str(key)
-settings_get_int(key)
-settings_get_bool(key)
-settings_get_time(key)
-settings_get_level(key)
-settings_get_size(key)
- Return value for setting.
-
-settings_set_str(key, value)
-settings_set_int(key, value)
-settings_set_bool(key, value)
-settings_set_time(key, value)
-settings_set_level(key, value)
-settings_set_size(key, value)
- Set value for setting.
- If you change the settings of another module/script with one of these, you
- must emit a "setup changed" signal afterwards.
-
-settings_add_str(section, key, def)
-settings_add_int(section, key, def)
-settings_add_bool(section, key, def)
-settings_add_time(section, key, def)
-settings_add_level(section, key, def)
-settings_add_size(section, key, def)
- Create new setting.
-
-settings_remove(key)
- Remove a setting.
-
*** Signals
-signal_emit(signal, ...)
- Send signal `signal'. You can give 6 parameters at maximum.
-
-signal_continue(...)
- Continue currently emitted signal with different parameters.
-
-signal_add(signal, func)
- Bind `signal' to function `func'.
-
-signal_add_first(signal, func)
- Bind `signal' to function `func'. Call `func' as soon as possible.
-
-signal_add_last(signal, func)
- Bind `signal' to function `func'. Call `func' as late as possible.
-
-signal_remove(signal, func)
- Unbind `signal' from function `func'.
-
-signal_stop()
- Stop the signal that's currently being emitted.
-
-signal_stop_by_name(signal)
- Stop the signal with name `signal' that's currently being emitted.
-
-signal_register(hash)
- Register parameter types for one or more signals.
- `hash' must map one or more signal names to references to arrays
- containing 0 to 6 type names. Some recognized type names include
- int for integers, intptr for references to integers and string for
- strings. For all standard signals see src/perl/perl-signals-list.h
- in the source code (this is generated by src/perl/get-signals.pl).
-
- Any signals that were already registered are unaffected.
-
- Registration is required to get any parameters to signals written in
- Perl and to emit and continue signals from Perl.
-
*** timeouts / IO listener / pidwait
-timeout_add(msecs, func, data)
- Call `func' every `msecs' milliseconds (1000 = 1 second) with
- parameter `data'. Returns tag which can be used to stop the timeout.
-
-timeout_add_once(msecs, func, data);
- Call `func' once after `msecs' milliseconds (1000 = 1 second)
- with parameter `data'. Returns tag which can be used to stop the timeout.
-
-timeout_remove(tag)
- Remove timeout with tag.
-
-input_add(source, condition, func, data)
- Call `func' with parameter `data' when specified IO happens.
- `source' is the file handle that is being listened. `condition' can
- be INPUT_READ, INPUT_WRITE or both. Returns tag which can be used to
- remove the listener.
-
-input_remove(tag)
- Remove listener with tag.
-
-pidwait_add(pid)
- Adds `pid' to the list of processes to wait for. The pid must identify
- a child process of the irssi process. When the process terminates, a
- "pidwait" signal will be sent with the pid and the status from
- waitpid(). This is useful to avoid zombies if your script forks.
-pidwait_remove(pid)
- Removes `pid' from the list of processes to wait for. Terminated
- processes are removed automatically, so it is usually not necessary
- to call this function.
*** Message levels
-level2bits(level)
- Level string -> number
-
-bits2level(bits)
- Level number -> string
-
-combine_level(level, str)
- Combine level number to level string ("+level -level").
- Return new level number.
*** Commands
-Command->{}
- cmd - Command name
- category - Category
-
-command_bind(cmd, func[, category])
- Bind command `cmd' to call function `func'. `category' is the
- category where the command is displayed in /HELP.
-
-command_runsub(cmd, data, server, item)
- Run subcommands for `cmd'. First word in `data' is parsed as
- subcommand. `server' is Irssi::Server rec for current
- Irssi::Windowitem `item'.
-
- Call command_runsub in handler function for `cmd' and bind
- with command_bind("`cmd' `subcmd'", subcmdfunc[, category]);
-
-command_unbind(cmd, func)
- Unbind command `cmd' from function `func'.
-
-command_set_options(cmd, data)
- Set options for command `cmd' to `data'. `data' is a string of
- space separated words which specify the options. Each word can be
- optionally prefixed with one of the following character:
-
- '-': optional argument
- '+': argument required
- '@': optional numeric argument
-command_parse_options(cmd, data)
- Parse options for command `cmd' in `data'. It returns a reference to
- an hash table with the options and a string with the remaining part
- of `data'. On error it returns the undefined value.
*** Windows
-UI::Window->{}
- refnum - Reference number
- name - Name
-
- width - Width
- height - Height
-
- history_name - Name of named historylist for this window
-
- active - Active window item
- active_server - Active server
-
- servertag - active_server must be either undef or have this same tag
- (unless there's items in this window). This is used by
- /WINDOW SERVER -sticky
- level - Current window level
-
- sticky_refnum - 1 if reference number is sticky
-
- data_level - Current data level
- hilight_color - Current activity hilight color
- last_timestamp - Last time timestamp was written in window
- last_line - Last time text was written in window
-
- theme_name - Active theme in window, undef = default
-
-UI::TextDest->{}
- window - Window where the text will be written
- server - Target server
- target - Target channel/query/etc name
- level - Text level
-
- hilight_priority - Priority for the hilighted text
- hilight_color - Color for the hilighted text
-
-
-Window::items()
- Return a list of items in window.
-
-Window
-window_create(automatic)
-Windowitem::window_create(automatic)
- Create a new window.
-
-Window::destroy()
- Destroy the window.
-
-Irssi::Window
-Windowitem::window()
- Returns parent window for window item.
-
-Window
-window_find_name(name)
- Find window with name.
-
-Window
-window_find_refnum(refnum)
- Find window with reference number.
-
-Window
-window_find_level(level)
-Server::window_find_level(level)
- Find window with level.
-
-Window
-window_find_closest(name, level)
-Server::window_find_closest(name, level)
- Find window that matches best to given arguments. `name' can be either
- window name or name of one of the window items.
-
-Window
-window_find_item(name)
-Server::window_find_item(name)
- Find window which contains window item with specified name/server.
Windowitem
window_item_find(name)
@@ -496,27 +160,9 @@ window_refnum_next(refnum, wrap)
windows_refnum_last()
Return refnum for last window.
-Window::item_add(item, automatic)
-Window::item_remove(item)
-Window::item_destroy(item)
- Add/remove/destroy window item
-
-Window::set_active()
- Set window active.
-
-Window::change_server(server)
-Window::set_refnum(refnum)
-Window::set_name(name)
-Window::set_history(name)
-Window::set_level(level)
- Change server/refnum/name/history/level in window.
-
Windowitem::set_active()
Change window item active in parent window.
-Window::item_prev()
-Window::item_next()
- Change to previous/next window item.
Windowitem::change_server(server)
Change server in window item.
@@ -550,70 +196,10 @@ server_create_conn(address[, port=6667[, password=''[, nick=''[, channels='']]]]
*** Server functions
-Server->{}
- type - "SERVER" text
- chat_type - String ID of chat protocol, for example "IRC"
-
- (..contains all the same data as Connect above..)
-
- connect_time - Time when connect() to server finished
- real_connect_time - Time when server sent "connected" message
-
- tag - Unique server tag
- nick - Current nick
-
- connected - Is connection finished? 1|0
- connection_lost - Did we lose the connection (1) or was
- the connection just /DISCONNECTed (0)
-
- rawlog - Rawlog object for the server
-
- version - Server version
- last_invite - Last channel we were invited to
- server_operator - Are we server operator (IRC op) 1|0
- usermode_away - Are we marked as away? 1|0
- away_reason - Away reason message
- banned - Were we banned from this server? 1|0
- lag - Current lag to server in milliseconds
-
-Server
-Connect::connect()
- Connect to server.
-
-Server::disconnect()
- Disconnect from server.
-
-Server
-server_find_tag(tag)
- Find server with tag
-
-Server
-server_find_chatnet(chatnet)
- Find first server that is in `chatnet'
-
-Server::isnickflag(flag)
- Returns 1 if flag is a nick mode flag (@, + or % in IRC)
-
-Server::ischannel(data)
- Returns 1 if start of `data' seems to mean channel.
-
-Server::get_nick_flags()
- Returns nick flag characters in order: op, voice, halfop ("@+%" in IRC).
-
-Server::send_message(target, msg, target_type)
- Sends a message to nick/channel. target_type 0 = channel, 1 = nick
*** Server reconnections
-Reconnect->{}
- type - "RECONNECT" text
- chat_type - String ID of chat protocol, for example "IRC"
-
- (..contains all the same data as Connect above..)
-
- tag - Unique numeric tag
- next_connect - Unix time stamp when the next connection occurs
*** Chat networks
@@ -710,16 +296,6 @@ Server::redirect_event(command, count, arg, remote, failure_signal, signals)
*** Window items
-Windowitem->{}
- type - Type of the window item, for example "CHANNEL" or "QUERY"
- chat_type - String ID of chat protocol, for example "IRC"
-
- server - Active server for item
- name - Name of the item
-
- createtime - Time the window item was created
- data_level - 0=no new data, 1=text, 2=msg, 3=highlighted text
- hilight_color - Color of the last highlighted text
*** Channels
diff --git a/docs/signals.txt b/docs/signals.txt
index a9b07ec..27138e6 100644
--- a/docs/signals.txt
+++ b/docs/signals.txt
@@ -9,84 +9,6 @@ core
* Provides signals:
-chat-protocols.c:
- "chat protocol created", CHAT_PROTOCOL_REC
- "chat protocol updated", CHAT_PROTOCOL_REC
- "chat protocol destroyed", CHAT_PROTOCOL_REC
-
-channels.c:
- "channel created", CHANNEL_REC, int automatic
- "channel destroyed", CHANNEL_REC
-
-chatnets.c:
- "chatnet created", CHATNET_REC
- "chatnet destroyed", CHATNET_REC
-
-commands.c:
- "commandlist new", COMMAND_REC
- "commandlist remove", COMMAND_REC
- "error command", int err, char *cmd
-
- "send command", char *args, SERVER_REC, WI_ITEM_REC
- "send text", char *line, SERVER_REC, WI_ITEM_REC
- "command "<cmd>, char *args, SERVER_REC, WI_ITEM_REC
- "default command", char *args, SERVER_REC, WI_ITEM_REC
-
-ignore.c:
- "ignore created", IGNORE_REC
- "ignore destroyed", IGNORE_REC
- "ignore changed", IGNORE_REC
-
-log.c:
- "log new", LOG_REC
- "log remove", LOG_REC
- "log create failed", LOG_REC
- "log locked", LOG_REC
- "log started", LOG_REC
- "log stopped", LOG_REC
- "log rotated", LOG_REC
- "log written", LOG_REC, char *line
-
-modules.c:
- "module loaded", MODULE_REC, MODULE_FILE_REC
- "module unloaded", MODULE_REC, MODULE_FILE_REC
- "module error", int error, char *text, char *rootmodule, char *submodule
-
-nicklist.c:
- "nicklist new", CHANNEL_REC, NICK_REC
- "nicklist remove", CHANNEL_REC, NICK_REC
- "nicklist changed", CHANNEL_REC, NICK_REC, char *old_nick
- "nicklist host changed", CHANNEL_REC, NICK_REC
- "nicklist gone changed", CHANNEL_REC, NICK_REC
- "nicklist serverop changed", CHANNEL_REC, NICK_REC
-
-pidwait.c:
- "pidwait", int pid, int status
-
-queries.c:
- "query created", QUERY_REC, int automatic
- "query destroyed", QUERY_REC
- "query nick changed", QUERY_REC, char *orignick
- "window item name changed", WI_ITEM_REC
- "query address changed", QUERY_REC
- "query server changed", QUERY_REC, SERVER_REC
-
-rawlog.c:
- "rawlog", RAWLOG_REC, char *data
-
-server.c:
- "server looking", SERVER_REC
- "server connected", SERVER_REC
- "server connecting", SERVER_REC, ulong *ip
- "server connect failed", SERVER_REC
- "server disconnected", SERVER_REC
- "server quit", SERVER_REC, char *msg
- "server sendmsg", SERVER_REC, char *target, char *msg, int target_type
-
-settings.c:
- "setup changed"
- "setup reread", char *fname
- "setup saved", char *fname, int autosaved
IRC core
diff --git a/patches/irssi-svn-r5174-no_act_ignore.patch b/patches/irssi-svn-r5174-no_act_ignore.patch
new file mode 100644
index 0000000..dec68c0
--- /dev/null
+++ b/patches/irssi-svn-r5174-no_act_ignore.patch
@@ -0,0 +1,161 @@
+Index: src/fe-common/core/fe-messages.c
+===================================================================
+--- src/fe-common/core/fe-messages.c (revision 5174)
++++ src/fe-common/core/fe-messages.c (working copy)
+@@ -190,6 +190,9 @@
+ if (for_me)
+ level |= MSGLEVEL_HILIGHT;
+
++ if(ignore_check(server, nick, address, target, msg, MSGLEVEL_NO_ACT))
++ level |= MSGLEVEL_NO_ACT;
++
+ if (settings_get_bool("emphasis"))
+ msg = freemsg = expand_emphasis((WI_ITEM_REC *) chanrec, msg);
+
+@@ -325,7 +328,12 @@
+ static void sig_message_join(SERVER_REC *server, const char *channel,
+ const char *nick, const char *address)
+ {
+- printformat(server, channel, MSGLEVEL_JOINS,
++ int level = MSGLEVEL_JOINS;
++
++ if(ignore_check(server, nick, address, channel, NULL, MSGLEVEL_NO_ACT))
++ level |= MSGLEVEL_NO_ACT;
++
++ printformat(server, channel, level,
+ TXT_JOIN, nick, address, channel);
+ }
+
+@@ -333,7 +341,12 @@
+ const char *nick, const char *address,
+ const char *reason)
+ {
+- printformat(server, channel, MSGLEVEL_PARTS,
++ int level = MSGLEVEL_PARTS;
++
++ if(ignore_check(server, nick, address, channel, NULL, MSGLEVEL_NO_ACT))
++ level |= MSGLEVEL_NO_ACT;
++
++ printformat(server, channel, level,
+ TXT_PART, nick, address, channel, reason);
+ }
+
+@@ -344,17 +357,21 @@
+ GString *chans;
+ GSList *tmp, *windows;
+ char *print_channel;
+- int once, count;
++ int once, count, level = MSGLEVEL_QUITS;
+
+ if (ignore_check(server, nick, address, NULL, reason, MSGLEVEL_QUITS))
+ return;
+
++ if(ignore_check(server, nick, address, NULL, reason, MSGLEVEL_NO_ACT))
++ level |= MSGLEVEL_NO_ACT;
++
+ print_channel = NULL;
+ once = settings_get_bool("show_quit_once");
+
+ count = 0; windows = NULL;
+ chans = g_string_new(NULL);
+ for (tmp = server->channels; tmp != NULL; tmp = tmp->next) {
++ level = MSGLEVEL_QUITS;
+ CHANNEL_REC *rec = tmp->data;
+
+ if (!nicklist_find(rec, nick))
+@@ -366,6 +383,9 @@
+ continue;
+ }
+
++ if(ignore_check(server, nick, address, rec->visible_name, reason, MSGLEVEL_NO_ACT))
++ level |= MSGLEVEL_NO_ACT;
++
+ if (print_channel == NULL ||
+ active_win->active == (WI_ITEM_REC *) rec)
+ print_channel = rec->visible_name;
+@@ -377,7 +397,7 @@
+ if (g_slist_find(windows, window) == NULL) {
+ windows = g_slist_append(windows, window);
+ printformat(server, rec->visible_name,
+- MSGLEVEL_QUITS,
++ level,
+ TXT_QUIT, nick, address, reason,
+ rec->visible_name);
+ }
+@@ -391,7 +411,7 @@
+ display the quit there too */
+ QUERY_REC *query = query_find(server, nick);
+ if (query != NULL) {
+- printformat(server, nick, MSGLEVEL_QUITS,
++ printformat(server, nick, level,
+ TXT_QUIT, nick, address, reason, "");
+ }
+ }
+@@ -410,7 +430,12 @@
+ const char *nick, const char *kicker,
+ const char *address, const char *reason)
+ {
+- printformat(server, channel, MSGLEVEL_KICKS,
++ int level = MSGLEVEL_KICKS;
++
++ if(ignore_check(server, kicker, address, channel, reason, MSGLEVEL_NO_ACT))
++ level |= MSGLEVEL_NO_ACT;
++
++ printformat(server, channel, level,
+ TXT_KICK, nick, channel, kicker, reason, address);
+ }
+
+@@ -428,6 +453,9 @@
+ level = MSGLEVEL_NICKS;
+ if (ownnick) level |= MSGLEVEL_NO_ACT;
+
++ if(!(level & MSGLEVEL_NO_ACT) && ignore_check(server, oldnick, address, channel, newnick, MSGLEVEL_NO_ACT))
++ level |= MSGLEVEL_NO_ACT;
++
+ printformat(server, channel, level,
+ ownnick ? TXT_YOUR_NICK_CHANGED : TXT_NICK_CHANGED,
+ oldnick, newnick, channel, address);
+@@ -502,6 +530,11 @@
+ const char *topic,
+ const char *nick, const char *address)
+ {
++ int level = MSGLEVEL_TOPICS;
++
++ if(ignore_check(server, nick, address, channel, topic, MSGLEVEL_NO_ACT))
++ level |= MSGLEVEL_NO_ACT;
++
+ printformat(server, channel, MSGLEVEL_TOPICS,
+ *topic != '\0' ? TXT_NEW_TOPIC : TXT_TOPIC_UNSET,
+ nick, channel, topic, address);
+Index: src/core/levels.c
+===================================================================
+--- src/core/levels.c (revision 5174)
++++ src/core/levels.c (working copy)
+@@ -46,6 +46,7 @@
+ "HILIGHTS",
+
+ "NOHILIGHT",
++ "NO_ACT",
+ NULL
+ };
+
+@@ -59,6 +60,9 @@
+ if (g_ascii_strcasecmp(level, "NEVER") == 0)
+ return MSGLEVEL_NEVER;
+
++ if (g_strcasecmp(level, "NO_ACT") == 0)
++ return MSGLEVEL_NO_ACT;
++
+ len = strlen(level);
+ if (len == 0) return 0;
+
+@@ -139,6 +143,9 @@
+ if (bits & MSGLEVEL_NEVER)
+ g_string_append(str, "NEVER ");
+
++ if (bits & MSGLEVEL_NO_ACT)
++ g_string_append(str, "NO_ACT ");
++
+ for (n = 0; levels[n] != NULL; n++) {
+ if (bits & (1L << n))
+ g_string_append_printf(str, "%s ", levels[n]);