=== modified file 'lib/widgets/ephy-location-entry.c'
--- lib/widgets/ephy-location-entry.c	2008-03-31 00:03:45 +0000
+++ lib/widgets/ephy-location-entry.c	2008-05-27 00:41:03 +0000
@@ -71,6 +71,7 @@
 	GdkColor secure_fg_colour;
 
 	GtkCellRenderer *extracell;
+	GRegex *regex;
 
 	char *before_completion;
 	char *saved_text;
@@ -79,9 +80,9 @@
 	guint action_col;
 	guint keywords_col;
 	guint relevance_col;
+	guint url_col;
 	guint extra_col;
 	guint favicon_col;
-	guint url_col;
 
 	guint hash;
 
@@ -114,6 +115,12 @@
 				GtkTreeIter *iter,
 				gpointer data);
 
+static void textcell_data_func (GtkCellLayout *cell_layout,
+			GtkCellRenderer *cell,
+			GtkTreeModel *tree_model,
+			GtkTreeIter *iter,
+			gpointer data);
+
 static GObjectClass *parent_class = NULL;
 
 enum signalsEnum
@@ -231,6 +238,12 @@
 	{
 		g_object_unref (priv->favicon);
 	}
+	
+	if (priv->regex)
+	{
+		g_regex_unref (priv->regex);
+		priv->regex = NULL;
+	}
 
 	parent_class->finalize (object);
 }
@@ -345,6 +358,8 @@
 		     EphyLocationEntry *entry)
 {
 	EphyLocationEntryPrivate *priv = entry->priv;
+	const char *text;
+	char *pattern;
 
 	update_address_state (entry);
 
@@ -355,6 +370,24 @@
 		priv->user_changed = TRUE;
 		priv->can_redo = FALSE;
 	}	
+	
+	if (priv->regex)
+	{
+		g_regex_unref (priv->regex);
+		priv->regex = NULL;
+	}
+	
+	text = gtk_entry_get_text (GTK_ENTRY (editable));
+
+	if (g_str_has_prefix (text, "re:"))
+		pattern = g_strdup (text+3);
+	else
+		pattern = g_regex_escape_string (text, -1);
+
+	priv->regex = g_regex_new (pattern, 
+				G_REGEX_CASELESS, G_REGEX_MATCH_NOTEMPTY, NULL);
+
+	g_free (pattern);
 
 	update_favicon (entry);
 
@@ -516,7 +549,7 @@
 	{
 		g_signal_stop_emission_by_name (widget, "drag_motion");
 	}
-    
+
 	return FALSE;
 }
 
@@ -925,7 +958,8 @@
 	p->user_changed = FALSE;
 	p->block_update = FALSE;
 	p->saved_text = NULL;
-
+	p->regex = NULL;
+	
 	ephy_location_entry_construct_contents (le);
 
 	gtk_tool_item_set_expand (GTK_TOOL_ITEM (le), TRUE);
@@ -966,10 +1000,15 @@
 	gtk_tree_model_get (model, iter,
 			    le->priv->url_col,
 			    &item, -1);
-	
 	entry = gtk_entry_completion_get_entry (completion);
+
+	/* Prevent the update so we keep the highlight from our input.
+	 * See textcell_data_func().
+	 */
+	le->priv->block_update = TRUE;
 	gtk_entry_set_text (GTK_ENTRY (entry), item);
 	gtk_editable_set_position (GTK_EDITABLE (entry), -1);
+	le->priv->block_update = FALSE;
 
 	g_free (item);
 
@@ -1002,16 +1041,59 @@
 	g_value_unset (&visible);
 }
 
+static void
+textcell_data_func (GtkCellLayout *cell_layout,
+			GtkCellRenderer *cell,
+			GtkTreeModel *tree_model,
+			GtkTreeIter *iter,
+			gpointer data)
+{
+	EphyLocationEntryPrivate *priv;
+	PangoAttrList *list;
+	PangoAttribute *att;
+	GMatchInfo *match;
+	int start, end;
+	char *text;
+	
+	priv = EPHY_LOCATION_ENTRY (data)->priv;
+	gtk_tree_model_get (tree_model, iter, priv->text_col, &text, -1);
+
+	list = pango_attr_list_new ();
+
+	g_regex_match (priv->regex, text, G_REGEX_MATCH_NOTEMPTY, &match);
+
+	while (g_match_info_matches (match)) {
+		g_match_info_fetch_pos (match, 0, &start, &end);
+
+		att = pango_attr_weight_new(PANGO_WEIGHT_BOLD);
+		att->start_index = start;
+		att->end_index = end;
+
+		pango_attr_list_insert (list, att);
+		g_match_info_next (match, NULL);
+	}
+
+	g_object_set (G_OBJECT (cell), 
+			"attributes", list,
+			NULL);
+
+	pango_attr_list_unref (list);
+	g_match_info_free (match);
+	g_free (text);
+}
+
+
 void
-ephy_location_entry_set_completion_func (EphyLocationEntry *le, 
-					GtkEntryCompletionMatchFunc completion_func,
-					gpointer user_data)
+ephy_location_entry_set_match_func (EphyLocationEntry *le, 
+				GtkEntryCompletionMatchFunc match_func,
+				gpointer user_data,
+				GDestroyNotify notify)
 {
 	EphyLocationEntryPrivate *priv = le->priv;
 	GtkEntryCompletion *completion;
 	
 	completion = gtk_entry_get_completion (GTK_ENTRY (priv->icon_entry->entry));
-	gtk_entry_completion_set_match_func (completion, completion_func, user_data, NULL);
+	gtk_entry_completion_set_match_func (completion, match_func, user_data, notify);
 }
 
 void
@@ -1021,9 +1103,9 @@
 				    guint action_col,
 				    guint keywords_col,
 				    guint relevance_col,
+				    guint url_col,
 				    guint extra_col,
-				    guint favicon_col,
-				    guint url_col)
+				    guint favicon_col)
 {
 	EphyLocationEntryPrivate *priv = le->priv;
 	GtkTreeModel *sort_model;
@@ -1034,9 +1116,9 @@
 	le->priv->action_col = action_col;
 	le->priv->keywords_col = keywords_col;
 	le->priv->relevance_col = relevance_col;
+	le->priv->url_col = url_col;
 	le->priv->extra_col = extra_col;
 	le->priv->favicon_col = favicon_col;
-	le->priv->url_col = url_col;
 
 	sort_model = gtk_tree_model_sort_new_with_model (model);
 	g_object_unref (model);
@@ -1084,6 +1166,11 @@
 					GUINT_TO_POINTER (extra_col),
 					NULL);
 
+	gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (completion),
+					cell, textcell_data_func, 
+					le,
+					NULL);
+
 	g_object_set (completion, "inline-selection", TRUE, NULL);
 	g_signal_connect (completion, "cursor-on-match",
 			  G_CALLBACK (cursor_on_match_cb), le);
@@ -1327,3 +1414,11 @@
 
 	gtk_widget_set_tooltip_text (priv->lock_ebox, tooltip);
 }
+
+GRegex *
+ephy_location_entry_get_regex (EphyLocationEntry *entry)
+{
+	EphyLocationEntryPrivate *priv = entry->priv;
+	
+	return priv->regex;
+}

=== modified file 'lib/widgets/ephy-location-entry.h'
--- lib/widgets/ephy-location-entry.h	2008-04-12 15:22:57 +0000
+++ lib/widgets/ephy-location-entry.h	2008-05-26 17:52:02 +0000
@@ -77,17 +77,18 @@
 							 guint action_col,
 							 guint keywords_col,
 							 guint relevance_col,
+							 guint url_col,
 							 guint extra_col,
-							 guint favicon_col,
-							 guint url_col);
+							 guint favicon_col);
 
 void		ephy_location_entry_set_location	(EphyLocationEntry *le,
 							 const char *address,
 							 const char *typed_address);
 
-void		ephy_location_entry_set_completion_func (EphyLocationEntry *le, 
-							 GtkEntryCompletionMatchFunc completion_func,
-							 gpointer user_data);
+void		ephy_location_entry_set_match_func	(EphyLocationEntry *le, 
+							 GtkEntryCompletionMatchFunc match_func,
+							 gpointer user_data,
+							 GDestroyNotify notify);
 					
 const char     *ephy_location_entry_get_location	(EphyLocationEntry *le);
 
@@ -95,6 +96,8 @@
 
 gboolean	ephy_location_entry_get_can_redo	(EphyLocationEntry *entry);
 
+GRegex *	ephy_location_entry_get_regex		(EphyLocationEntry *entry);
+
 gboolean	ephy_location_entry_reset		(EphyLocationEntry *entry);
 
 void		ephy_location_entry_undo_reset		(EphyLocationEntry *entry);

=== modified file 'src/ephy-completion-model.h'
--- src/ephy-completion-model.h	2008-04-11 20:05:25 +0000
+++ src/ephy-completion-model.h	2008-05-26 17:50:52 +0000
@@ -44,9 +44,9 @@
 	EPHY_COMPLETION_ACTION_COL,
 	EPHY_COMPLETION_KEYWORDS_COL,
 	EPHY_COMPLETION_RELEVANCE_COL,
+	EPHY_COMPLETION_URL_COL,
 	EPHY_COMPLETION_EXTRA_COL,
 	EPHY_COMPLETION_FAVICON_COL,
-	EPHY_COMPLETION_URL_COL,
 	N_COL
 } EphyCompletionColumn;
 

=== modified file 'src/ephy-location-action.c'
--- src/ephy-location-action.c	2008-05-19 19:36:47 +0000
+++ src/ephy-location-action.c	2008-05-26 23:59:55 +0000
@@ -92,73 +92,34 @@
 
 G_DEFINE_TYPE (EphyLocationAction, ephy_location_action, EPHY_TYPE_LINK_ACTION)
 
-static const struct
-{
-	const char *prefix;
-	int len;
-}
-web_prefixes [] =
-{
-	{ "http://www.", 11 },
-	{ "http://ftp.", 11 },
-	{ "http://", 7 },
-	{ "https://www.", 12 },
-	{ "https://", 8 },
-	{ "ftp://", 6},
-	{ "ftp://ftp.", 10},
-	{ "www.", 4 },
-	{ "ftp.", 4}
-};
-
-
-static gboolean
-keyword_match (const char *list,
-	       const char *keyword)
-{
-	const char *p;
-	gsize keyword_len;
-
-	p = list;
-	keyword_len = strlen (keyword);
-
-	while (*p)
-	{
-		int i;
-
-		for (i = 0; i < keyword_len; i++)
-		{
-			if (p[i] != keyword[i])
-			{
-				goto next_token;
-			}
-		}
-	  
-		return TRUE;
-	  
-		next_token:
-
-		while (*p && !g_ascii_ispunct(*p) && !g_ascii_isspace(*p)) p++;
-		while (*p && (g_ascii_ispunct(*p) || g_ascii_isspace(*p))) p++;
-	}
-
-	return FALSE;
-}
-
-static gboolean
-completion_func (GtkEntryCompletion *completion,
-		 const char *key,
-		 GtkTreeIter *iter,
-		 gpointer data)
-{
-	int i, len_key, len_prefix;
+typedef struct
+{
+	EphyLocationEntry *entry;
+	EphyLocationAction *action;
+} LocationEntryAction;
+
+static void
+destroy_match_func (gpointer data)
+{
+	g_slice_free (LocationEntryAction, data);
+}
+
+static gboolean
+match_func (GtkEntryCompletion *completion,
+		const char *key,
+		GtkTreeIter *iter,
+		gpointer data)
+{
 	char *item = NULL;
 	char *url = NULL;
 	char *keywords = NULL;
+
 	gboolean ret = FALSE;
+	EphyLocationActionPrivate *priv;
 	GtkTreeModel *model;
-	EphyLocationActionPrivate *priv;
-	
-	priv = EPHY_LOCATION_ACTION (data)->priv;
+	GRegex *regex;
+
+	priv = EPHY_LOCATION_ACTION (((LocationEntryAction *) data)->action)->priv;
 
 	model = gtk_entry_completion_get_model (completion);
 
@@ -167,41 +128,17 @@
 			    EPHY_COMPLETION_URL_COL, &url,
 			    EPHY_COMPLETION_KEYWORDS_COL, &keywords,
 			    -1);
-
-	len_key = strlen (key);
-	if (!strncasecmp (key, item, len_key))
-	{
-		ret = TRUE;
-	}
-	else if (keyword_match (keywords, key))
-	{
-		ret = TRUE;
-	}
-	else if (!strncasecmp (key, url, len_key))
-	{
-		ret = TRUE;
-	}
-	else
-	{
-		for (i = 0; i < G_N_ELEMENTS (web_prefixes); i++)
-		{
-			len_prefix = web_prefixes[i].len;
-			if (!strncmp (web_prefixes[i].prefix, item, len_prefix) &&
-			    !strncasecmp (key, item + len_prefix, len_key))
-			{
-				ret = TRUE;
-				break;
-			}
-			else if (!strncmp (web_prefixes[i].prefix, url, len_prefix) &&
-			        !strncasecmp (key, url + len_prefix, len_key))
-			{
-				ret = TRUE;
-				break;
-			}
-
-		}
-	}
-	
+	
+	if (!key)
+		return FALSE;
+	
+	regex = ephy_location_entry_get_regex (((LocationEntryAction *) data)->entry);
+	
+	ret = (g_regex_match (regex, item, G_REGEX_MATCH_NOTEMPTY, NULL)
+		|| g_regex_match (regex, url, G_REGEX_MATCH_NOTEMPTY, NULL)
+		|| g_regex_match (regex, keywords, G_REGEX_MATCH_NOTEMPTY, NULL)
+		);
+
 	g_free (item);
 	g_free (url);
 	g_free (keywords);
@@ -502,6 +439,7 @@
 		EphyLocationEntry *lentry = EPHY_LOCATION_ENTRY (proxy);
 		EphyCompletionModel *model;
 		GtkWidget *entry;
+		LocationEntryAction *lea;
 
 		model = ephy_completion_model_new ();
 		ephy_location_entry_set_completion (EPHY_LOCATION_ENTRY (proxy),
@@ -510,13 +448,18 @@
 						    EPHY_COMPLETION_ACTION_COL,
 						    EPHY_COMPLETION_KEYWORDS_COL,
 						    EPHY_COMPLETION_RELEVANCE_COL,
+						    EPHY_COMPLETION_URL_COL,
 						    EPHY_COMPLETION_EXTRA_COL,
-						    EPHY_COMPLETION_FAVICON_COL,
-						    EPHY_COMPLETION_URL_COL);
-
-		ephy_location_entry_set_completion_func (EPHY_LOCATION_ENTRY (proxy), 
-							completion_func, 
-							EPHY_LOCATION_ACTION (action));
+						    EPHY_COMPLETION_FAVICON_COL);
+		
+		lea = g_slice_new (LocationEntryAction);
+		lea->entry = EPHY_LOCATION_ENTRY (proxy);
+		lea->action = EPHY_LOCATION_ACTION (action);
+		
+		ephy_location_entry_set_match_func (EPHY_LOCATION_ENTRY (proxy), 
+							match_func, 
+							lea,
+							destroy_match_func);
 
 		add_completion_actions (action, proxy);
 

