1
0
mirror of https://github.com/irssi/irssi.git synced 2024-06-23 06:35:36 +00:00

Merge pull request #80 from dgl/noact

Change NO_ACT so it can be combined with other levels
This commit is contained in:
Alexander Færøy 2014-07-04 23:48:41 +02:00
commit ed51629514
9 changed files with 139 additions and 51 deletions

View File

@ -40,6 +40,19 @@ Some suggestions for ignoring annoying public aways:
/IGNORE *afk* NICKS
/IGNORE *away* NICKS
The special level "NO_ACT" can be used to ignore activity ("Act:") but not
actually ignore the message entirely. It is somewhat special because it is
allowed in addition to another ignore for the same target.
Examples:
/IGNORE #channel NO_ACT JOINS PARTS QUITS - hide joins, etc from activity
/IGNORE nick NO_ACT -MSGS - ignore activity from nick, except for /MSG
/IGNORE -regexp -pattern . -except nick NO_ACT HILIGHT
- combined with the ignore above show hilights from this nick (needs to be
an except as "PUBLIC HILIGHT" still matches public, the regexp is used to
have more than one ignore for "nick").
For regular expressions, see `man 7 regex`.
See also: UNIGNORE, SILENCE, ACCEPT

View File

@ -58,30 +58,6 @@ static int ignore_check_replies_rec(IGNORE_REC *rec, CHANNEL_REC *channel,
return FALSE;
}
#define ignore_match_channel(rec, channel) \
((rec)->channels == NULL || ((channel) != NULL && \
strarray_find((rec)->channels, (channel)) != -1))
static int ignore_check_replies(CHANNEL_REC *chanrec, const char *text)
{
GSList *tmp;
if (text == NULL || chanrec == NULL)
return FALSE;
/* check reply ignores */
for (tmp = ignores; tmp != NULL; tmp = tmp->next) {
IGNORE_REC *rec = tmp->data;
if (rec->mask != NULL && rec->replies &&
ignore_match_channel(rec, chanrec->name) &&
ignore_check_replies_rec(rec, chanrec, text))
return TRUE;
}
return FALSE;
}
static int ignore_match_pattern(IGNORE_REC *rec, const char *text)
{
if (rec->pattern == NULL)
@ -104,8 +80,15 @@ static int ignore_match_pattern(IGNORE_REC *rec, const char *text)
stristr(text, rec->pattern) != NULL;
}
/* MSGLEVEL_NO_ACT is special in ignores, when provided to ignore_check() it's
* used as a flag to indicate it should only look at ignore items with NO_ACT.
* However we also want to allow NO_ACT combined with levels, so mask it out and
* match levels if set. */
#define ignore_match_level(rec, level) \
((level & (rec)->level) != 0)
(((level & MSGLEVEL_NO_ACT) != 0) ? \
((~MSGLEVEL_NO_ACT & level) & (rec)->level) != 0 : \
((rec)->level & MSGLEVEL_NO_ACT ? 0 : \
(level & (rec)->level) != 0))
#define ignore_match_nickmask(rec, nick, nickmask) \
((rec)->mask == NULL || \
@ -117,6 +100,31 @@ static int ignore_match_pattern(IGNORE_REC *rec, const char *text)
((rec)->servertag == NULL || \
g_ascii_strcasecmp((server)->tag, (rec)->servertag) == 0)
#define ignore_match_channel(rec, channel) \
((rec)->channels == NULL || ((channel) != NULL && \
strarray_find((rec)->channels, (channel)) != -1))
static int ignore_check_replies(CHANNEL_REC *chanrec, const char *text, int level)
{
GSList *tmp;
if (text == NULL || chanrec == NULL)
return FALSE;
/* check reply ignores */
for (tmp = ignores; tmp != NULL; tmp = tmp->next) {
IGNORE_REC *rec = tmp->data;
if (rec->mask != NULL && rec->replies &&
ignore_match_level(rec, level) &&
ignore_match_channel(rec, chanrec->name) &&
ignore_check_replies_rec(rec, chanrec, text))
return TRUE;
}
return FALSE;
}
int ignore_check(SERVER_REC *server, const char *nick, const char *host,
const char *channel, const char *text, int level)
{
@ -176,11 +184,18 @@ int ignore_check(SERVER_REC *server, const char *nick, const char *host,
if (best_match || (level & MSGLEVEL_PUBLIC) == 0)
return best_match;
return ignore_check_replies(chanrec, text);
return ignore_check_replies(chanrec, text, level);
}
IGNORE_REC *ignore_find(const char *servertag, const char *mask,
char **channels)
char **channels)
{
return ignore_find_noact(servertag, mask, channels, 0);
}
IGNORE_REC *ignore_find_noact(const char *servertag, const char *mask,
char **channels, int noact)
{
GSList *tmp;
char **chan;
@ -202,6 +217,12 @@ IGNORE_REC *ignore_find(const char *servertag, const char *mask,
continue;
}
if (noact && (rec->level & MSGLEVEL_NO_ACT) == 0)
continue;
if (!noact && (rec->level & MSGLEVEL_NO_ACT) != 0)
continue;
if ((rec->mask == NULL && mask != NULL) ||
(rec->mask != NULL && mask == NULL)) continue;

View File

@ -32,6 +32,7 @@ int ignore_check(SERVER_REC *server, const char *nick, const char *host,
const char *channel, const char *text, int level);
IGNORE_REC *ignore_find(const char *servertag, const char *mask, char **channels);
IGNORE_REC *ignore_find_noact(const char *servertag, const char *mask, char **channels, int noact);
void ignore_add_rec(IGNORE_REC *rec);
void ignore_update_rec(IGNORE_REC *rec);

View File

@ -136,19 +136,25 @@ char *bits2level(int bits)
if (bits == 0)
return g_strdup("");
if (bits == MSGLEVEL_ALL)
return g_strdup("ALL");
str = g_string_new(NULL);
if (bits & MSGLEVEL_NEVER)
if (bits & MSGLEVEL_NEVER) {
g_string_append(str, "NEVER ");
bits &= ~MSGLEVEL_NEVER;
}
if (bits & MSGLEVEL_NO_ACT)
if (bits & MSGLEVEL_NO_ACT) {
g_string_append(str, "NO_ACT ");
bits &= ~MSGLEVEL_NO_ACT;
}
for (n = 0; levels[n] != NULL; n++) {
if (bits & (1L << n))
g_string_append_printf(str, "%s ", levels[n]);
if (bits == MSGLEVEL_ALL) {
g_string_append(str, "ALL ");
} else {
for (n = 0; levels[n] != NULL; n++) {
if (bits & (1L << n))
g_string_append_printf(str, "%s ", levels[n]);
}
}
if (str->len > 0)
g_string_truncate(str, str->len-1);

View File

@ -120,7 +120,7 @@ static void cmd_ignore(const char *data)
char *patternarg, *chanarg, *mask, *levels, *timestr, *servertag;
char **channels;
void *free_arg;
int new_ignore, msecs;
int new_ignore, msecs, level;
if (*data == '\0') {
cmd_ignore_show();
@ -140,6 +140,7 @@ static void cmd_ignore(const char *data)
if (*mask == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
if (*levels == '\0') levels = "ALL";
level = level2bits(levels, NULL);
msecs = 0;
timestr = g_hash_table_lookup(optlist, "time");
@ -156,7 +157,8 @@ static void cmd_ignore(const char *data)
channels = (chanarg == NULL || *chanarg == '\0') ? NULL :
g_strsplit(chanarg, ",", -1);
rec = patternarg != NULL ? NULL: ignore_find(servertag, mask, channels);
rec = patternarg != NULL ? NULL: ignore_find_noact(servertag, mask, channels,
(level & MSGLEVEL_NO_ACT));
new_ignore = rec == NULL;
if (rec == NULL) {
@ -172,6 +174,12 @@ static void cmd_ignore(const char *data)
rec->level = combine_level(rec->level, levels);
if (rec->level == MSGLEVEL_NO_ACT) {
/* If only NO_ACT was specified add all levels; it makes no
* sense on its own. */
rec->level |= MSGLEVEL_ALL;
}
if (new_ignore && rec->level == 0) {
/* tried to unignore levels from nonexisting ignore */
printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE,
@ -228,7 +236,10 @@ static void cmd_unignore(const char *data)
chans[0] = mask;
mask = NULL;
}
rec = ignore_find("*", mask, (char **) chans);
rec = ignore_find_noact("*", mask, (char **) chans, 0);
if (rec == NULL) {
rec = ignore_find_noact("*", mask, (char **) chans, 1);
}
}
if (rec != NULL) {

View File

@ -190,7 +190,7 @@ static void sig_message_public(SERVER_REC *server, const char *msg,
if (for_me)
level |= MSGLEVEL_HILIGHT;
if (ignore_check(server, nick, address, target, msg, MSGLEVEL_NO_ACT))
if (ignore_check(server, nick, address, target, msg, level | MSGLEVEL_NO_ACT))
level |= MSGLEVEL_NO_ACT;
if (settings_get_bool("emphasis"))
@ -238,13 +238,17 @@ static void sig_message_private(SERVER_REC *server, const char *msg,
{
QUERY_REC *query;
char *freemsg = NULL;
int level = MSGLEVEL_MSGS;
query = query_find(server, nick);
if (settings_get_bool("emphasis"))
msg = freemsg = expand_emphasis((WI_ITEM_REC *) query, msg);
printformat(server, nick, MSGLEVEL_MSGS,
if (ignore_check(server, nick, address, NULL, msg, level | MSGLEVEL_NO_ACT))
level |= MSGLEVEL_NO_ACT;
printformat(server, nick, level,
query == NULL ? TXT_MSG_PRIVATE :
TXT_MSG_PRIVATE_QUERY, nick, address, msg);
@ -330,7 +334,7 @@ static void sig_message_join(SERVER_REC *server, const char *channel,
{
int level = MSGLEVEL_JOINS;
if (ignore_check(server, nick, address, channel, NULL, MSGLEVEL_NO_ACT))
if (ignore_check(server, nick, address, channel, NULL, level | MSGLEVEL_NO_ACT))
level |= MSGLEVEL_NO_ACT;
printformat(server, channel, level,
@ -343,7 +347,7 @@ static void sig_message_part(SERVER_REC *server, const char *channel,
{
int level = MSGLEVEL_PARTS;
if (ignore_check(server, nick, address, channel, NULL, MSGLEVEL_NO_ACT))
if (ignore_check(server, nick, address, channel, NULL, level | MSGLEVEL_NO_ACT))
level |= MSGLEVEL_NO_ACT;
printformat(server, channel, level,
@ -362,7 +366,7 @@ static void sig_message_quit(SERVER_REC *server, const char *nick,
if (ignore_check(server, nick, address, NULL, reason, MSGLEVEL_QUITS))
return;
if (ignore_check(server, nick, address, NULL, reason, MSGLEVEL_NO_ACT))
if (ignore_check(server, nick, address, NULL, reason, level | MSGLEVEL_NO_ACT))
level |= MSGLEVEL_NO_ACT;
print_channel = NULL;
@ -432,7 +436,7 @@ static void sig_message_kick(SERVER_REC *server, const char *channel,
{
int level = MSGLEVEL_KICKS;
if (ignore_check(server, kicker, address, channel, reason, MSGLEVEL_NO_ACT))
if (ignore_check(server, kicker, address, channel, reason, level | MSGLEVEL_NO_ACT))
level |= MSGLEVEL_NO_ACT;
printformat(server, channel, level,
@ -453,7 +457,7 @@ static void print_nick_change_channel(SERVER_REC *server, const char *channel,
level = MSGLEVEL_NICKS;
if (ownnick) level |= MSGLEVEL_NO_ACT;
if (!(level & MSGLEVEL_NO_ACT) && ignore_check(server, oldnick, address, channel, newnick, MSGLEVEL_NO_ACT))
if (!(level & MSGLEVEL_NO_ACT) && ignore_check(server, oldnick, address, channel, newnick, level | MSGLEVEL_NO_ACT))
level |= MSGLEVEL_NO_ACT;
printformat(server, channel, level,
@ -532,7 +536,7 @@ static void sig_message_topic(SERVER_REC *server, const char *channel,
{
int level = MSGLEVEL_TOPICS;
if (ignore_check(server, nick, address, channel, topic, MSGLEVEL_NO_ACT))
if (ignore_check(server, nick, address, channel, topic, level | MSGLEVEL_NO_ACT))
level |= MSGLEVEL_NO_ACT;
printformat(server, channel, level,

View File

@ -336,6 +336,12 @@ static void sig_print_text(TEXT_DEST_REC *dest, const char *text,
if (!nick_match || (dest->level & MSGLEVEL_HILIGHT)) {
/* update the level / hilight info */
hilight_update_text_dest(dest, hilight);
/* Remove NO_ACT, this means explicitly defined hilights will bypass
* /IGNORE ... NO_ACT.
* (It's still possible to use /hilight -actcolor %n to hide
* hilight/beep).
*/
dest->level &= ~MSGLEVEL_NO_ACT;
}
if (nick_match)

View File

@ -25,6 +25,7 @@
#include "irc-servers.h"
#include "irc-queries.h"
#include "dcc-chat.h"
#include "ignore.h"
#include "module-formats.h"
#include "printtext.h"
@ -86,12 +87,17 @@ static void sig_message_dcc(CHAT_DCC_REC *dcc, const char *msg)
TEXT_DEST_REC dest;
QUERY_REC *query;
char *tag;
int level = MSGLEVEL_DCCMSGS;
tag = g_strconcat("=", dcc->id, NULL);
query = query_find(NULL, tag);
if (ignore_check(SERVER(dcc->server), tag, dcc->addrstr, NULL, msg,
level | MSGLEVEL_NO_ACT))
level |= MSGLEVEL_NO_ACT;
format_create_dest_tag(&dest, dcc->server, dcc->servertag, tag,
MSGLEVEL_DCCMSGS, NULL);
level, NULL);
printformat_dest(&dest, query != NULL ? IRCTXT_DCC_MSG_QUERY :
IRCTXT_DCC_MSG, dcc->id, msg);
@ -103,12 +109,17 @@ static void sig_message_dcc_action(CHAT_DCC_REC *dcc, const char *msg)
TEXT_DEST_REC dest;
QUERY_REC *query;
char *tag;
int level = MSGLEVEL_DCCMSGS | MSGLEVEL_ACTIONS;
tag = g_strconcat("=", dcc->id, NULL);
query = query_find(NULL, tag);
if (ignore_check(SERVER(dcc->server), tag, dcc->addrstr, NULL, msg,
level | MSGLEVEL_NO_ACT))
level |= MSGLEVEL_NO_ACT;
format_create_dest_tag(&dest, dcc->server, dcc->servertag, tag,
MSGLEVEL_DCCMSGS | MSGLEVEL_ACTIONS, NULL);
level, NULL);
printformat_dest(&dest, query != NULL ? IRCTXT_ACTION_DCC_QUERY :
IRCTXT_ACTION_DCC, dcc->id, msg);
@ -120,11 +131,16 @@ static void sig_message_dcc_ctcp(CHAT_DCC_REC *dcc, const char *cmd,
{
TEXT_DEST_REC dest;
char *tag;
int level = MSGLEVEL_DCCMSGS | MSGLEVEL_CTCPS;
tag = g_strconcat("=", dcc->id, NULL);
if (ignore_check(SERVER(dcc->server), tag, dcc->addrstr, NULL, cmd,
level | MSGLEVEL_NO_ACT))
level |= MSGLEVEL_NO_ACT;
format_create_dest_tag(&dest, dcc->server, dcc->servertag, tag,
MSGLEVEL_DCC | MSGLEVEL_CTCPS, NULL);
level, NULL);
printformat_dest(&dest, IRCTXT_DCC_CTCP, dcc->id, cmd, data);
g_free(tag);

View File

@ -170,6 +170,10 @@ static void sig_message_irc_action(IRC_SERVER_REC *server, const char *msg,
if (ignore_check(SERVER(server), nick, address, target, msg, level))
return;
if (ignore_check(SERVER(server), nick, address, target, msg,
level | MSGLEVEL_NO_ACT))
level |= MSGLEVEL_NO_ACT;
if (ischannel(*target))
item = irc_channel_find(server, target);
else
@ -214,6 +218,7 @@ static void sig_message_irc_notice(SERVER_REC *server, const char *msg,
const char *target)
{
const char *oldtarget;
int level = MSGLEVEL_NOTICES;
oldtarget = target;
target = skip_target(IRC_SERVER(server), target);
@ -230,18 +235,23 @@ static void sig_message_irc_notice(SERVER_REC *server, const char *msg,
if (ignore_check(server, nick, address,
ischannel(*target) ? target : NULL,
msg, MSGLEVEL_NOTICES))
msg, level))
return;
if (ignore_check(server, nick, address,
ischannel(*target) ? target : NULL,
msg, level | MSGLEVEL_NO_ACT))
level |= MSGLEVEL_NO_ACT;
if (ischannel(*target)) {
/* notice in some channel */
printformat(server, target, MSGLEVEL_NOTICES,
printformat(server, target, level,
IRCTXT_NOTICE_PUBLIC, nick, oldtarget, msg);
} else {
/* private notice */
privmsg_get_query(SERVER(server), nick, FALSE,
MSGLEVEL_NOTICES);
printformat(server, nick, MSGLEVEL_NOTICES,
printformat(server, nick, level,
IRCTXT_NOTICE_PRIVATE, nick, address, msg);
}
}