]> git.0d.be Git - empathy.git/commitdiff
Use /\b<nickname>\b/ to decide whether to highlight
authorWill Thompson <will@willthompson.co.uk>
Wed, 18 Jan 2012 15:41:07 +0000 (15:41 +0000)
committerWill Thompson <will@willthompson.co.uk>
Wed, 18 Jan 2012 17:47:21 +0000 (17:47 +0000)
The current highlighting code finds the first occurrence of the
nickname, then checks whether the characters before or after are a
space, a comma, a colon or a full stop (or the start or end of the
string). This means that someone saying “no! That's wjt’s coffee!”
didn’t highlight me, because the apostrophe isn't in the whitelist. It
also means that saying “borrow some Sudafed from daf” would not
highlight daf, since the first match is in the middle of a word.

We’re trying to check whether the nickname occurs as a complete word
within the message. The regex metacharacter \b matches word boundaries,
so /\b<nickname>\b/ is what we actually want. It gets the above cases
right, including Unicode punctuation.

https://bugzilla.gnome.org/show_bug.cgi?id=591667

libempathy/empathy-message.c

index 995f49ab7e299dda1e24e9e3f67f3dd2a0b6de6f..9841cbb618f24e3e7246be3eddf7d101aca0895c 100644 (file)
@@ -39,6 +39,9 @@
 # include <telepathy-logger/call-event.h>
 #endif
 
+#define DEBUG_FLAG EMPATHY_DEBUG_CHAT
+#include "empathy-debug.h"
+
 #include "empathy-client-factory.h"
 #include "empathy-message.h"
 #include "empathy-utils.h"
@@ -633,21 +636,42 @@ empathy_message_is_backlog (EmpathyMessage *message)
        return priv->is_backlog;
 }
 
-#define IS_SEPARATOR(ch) (ch == ' ' || ch == ',' || ch == '.' || ch == ':')
+static GRegex *
+get_highlight_regex_for (const gchar *name)
+{
+       GRegex *regex;
+       gchar *name_esc, *pattern;
+       GError *error = NULL;
+
+       name_esc = g_regex_escape_string (name, -1);
+       pattern = g_strdup_printf ("\\b%s\\b", name_esc);
+       regex = g_regex_new (pattern, G_REGEX_CASELESS | G_REGEX_OPTIMIZE, 0,
+               &error);
+
+       if (regex == NULL) {
+               DEBUG ("couldn't compile regex /%s/: %s", pattern,
+                       error->message);
+
+               g_error_free (error);
+       }
+
+       g_free (pattern);
+       g_free (name_esc);
+
+       return regex;
+}
+
 gboolean
 empathy_message_should_highlight (EmpathyMessage *message)
 {
        EmpathyContact *contact;
        const gchar   *msg, *to;
-       gchar         *cf_msg, *cf_to;
-       gchar         *ch;
-       gboolean       ret_val;
+       gboolean       ret_val = FALSE;
        TpChannelTextMessageFlags flags;
+       GRegex *regex;
 
        g_return_val_if_fail (EMPATHY_IS_MESSAGE (message), FALSE);
 
-       ret_val = FALSE;
-
        msg = empathy_message_get_body (message);
        if (!msg) {
                return FALSE;
@@ -670,34 +694,11 @@ empathy_message_should_highlight (EmpathyMessage *message)
                return FALSE;
        }
 
-       cf_msg = g_utf8_casefold (msg, -1);
-       cf_to = g_utf8_casefold (to, -1);
-
-       ch = strstr (cf_msg, cf_to);
-       if (ch == NULL) {
-               goto finished;
+       regex = get_highlight_regex_for (to);
+       if (regex != NULL) {
+               ret_val = g_regex_match (regex, msg, 0, NULL);
+               g_regex_unref (regex);
        }
-       if (ch != cf_msg) {
-               /* Not first in the message */
-               if (!IS_SEPARATOR (*(ch - 1))) {
-                       goto finished;
-               }
-       }
-
-       ch = ch + strlen (cf_to);
-       if (ch >= cf_msg + strlen (cf_msg)) {
-               ret_val = TRUE;
-               goto finished;
-       }
-
-       if (IS_SEPARATOR (*ch)) {
-               ret_val = TRUE;
-               goto finished;
-       }
-
-finished:
-       g_free (cf_msg);
-       g_free (cf_to);
 
        return ret_val;
 }