# HG changeset patch
# Node ID a4f41a85e5264c993e08ad68ac7ef1a9804c0e83
# Parent  901838c196e367372059341898e0410abd11a6bf
diff --git a/ibis/ibisclient.c b/ibis/ibisclient.c
--- a/ibis/ibisclient.c
+++ b/ibis/ibisclient.c
@@ -1350,6 +1350,13 @@
 	return client->nick;
 }
 
+char
+ibis_client_get_prefix_for_mode(IbisClient *client, char mode) {
+	g_return_val_if_fail(IBIS_IS_CLIENT(client), '\0');
+
+	return ibis_features_get_prefix_for_mode(client->features, mode);
+}
+
 void
 ibis_client_set_nick(IbisClient *client, const char *nick) {
 	g_return_if_fail(IBIS_IS_CLIENT(client));
diff --git a/ibis/ibisclient.h b/ibis/ibisclient.h
--- a/ibis/ibisclient.h
+++ b/ibis/ibisclient.h
@@ -299,6 +299,22 @@
 const char *ibis_client_get_nick(IbisClient *client);
 
 /**
+ * ibis_client_get_prefix_for_mode:
+ * @mode: the mode
+ *
+ * Gets the prefix for the given mode.
+ *
+ * This is a helper method that calls [method@Features.get_prefix_for_mode]
+ * using [property@Client:features].
+ *
+ * Returns: The prefix if found, otherwise `\0`.
+ *
+ * Since: 0.12
+ */
+IBIS_AVAILABLE_IN_0_12
+char ibis_client_get_prefix_for_mode(IbisClient *client, char mode);
+
+/**
  * ibis_client_set_nick:
  * @nick: the new nick
  *
diff --git a/ibis/ibisfeatures.c b/ibis/ibisfeatures.c
--- a/ibis/ibisfeatures.c
+++ b/ibis/ibisfeatures.c
@@ -626,6 +626,30 @@
 	return ibis_features_get_string(features, IBIS_FEATURE_PREFIX);
 }
 
+char
+ibis_features_get_prefix_for_mode(IbisFeatures *features, char mode) {
+	const char *modes = NULL;
+	const char *prefixes = NULL;
+
+	g_return_val_if_fail(IBIS_IS_FEATURES(features), '\0');
+
+	modes = ibis_features_get_string(features, IBIS_FEATURE_PREFIX_MODES);
+	if(modes == NULL) {
+		return '\0';
+	}
+
+	prefixes = ibis_features_get_string(features,
+	                                    IBIS_FEATURE_PREFIX_PREFIXES);
+
+	for(int i = 0; modes[i] != '\0'; i++) {
+		if(modes[i] == mode) {
+			return prefixes[i];
+		}
+	}
+
+	return '\0';
+}
+
 const char *
 ibis_features_get_prefix_modes(IbisFeatures *features) {
 	g_return_val_if_fail(IBIS_IS_FEATURES(features), NULL);
diff --git a/ibis/ibisfeatures.h b/ibis/ibisfeatures.h
--- a/ibis/ibisfeatures.h
+++ b/ibis/ibisfeatures.h
@@ -352,6 +352,24 @@
 const char *ibis_features_get_prefix(IbisFeatures *features);
 
 /**
+ * ibis_features_get_prefix_for_mode:
+ * @mode: the mode
+ *
+ * Gets the prefix for the given mode.
+ *
+ * This is useful when a %MODE command comes in and you want to display the
+ * prefix for it.
+ *
+ * For example, on most network the `o` mode is tied to the `@` prefix.
+ *
+ * Returns: The prefix if found, otherwise '\0'.
+ *
+ * Since: 0.12
+ */
+IBIS_AVAILABLE_IN_0_12
+char ibis_features_get_prefix_for_mode(IbisFeatures *features, char mode);
+
+/**
  * ibis_features_get_prefix_modes:
  *
  * Gets the modes portion of the prefix feature.
diff --git a/ibis/tests/test_features.c b/ibis/tests/test_features.c
--- a/ibis/tests/test_features.c
+++ b/ibis/tests/test_features.c
@@ -446,6 +446,75 @@
 	g_assert_finalize_object(features);
 }
 
+static void
+test_ibis_features_get_prefix_for_mode_normal(void) {
+	IbisMessage *message = NULL;
+	IbisFeatures *features = NULL;
+	char prefix = '\0';
+
+	features = ibis_features_new();
+	message = ibis_message_new(IBIS_RPL_ISUPPORT);
+	ibis_message_set_params(message, "PREFIX=(qaohv)~&@%+", NULL);
+	ibis_features_parse(features, message);
+
+	prefix = ibis_features_get_prefix_for_mode(features, 'q');
+	g_assert_cmpint(prefix, ==, '~');
+
+	prefix = ibis_features_get_prefix_for_mode(features, 'a');
+	g_assert_cmpint(prefix, ==, '&');
+
+	prefix = ibis_features_get_prefix_for_mode(features, 'o');
+	g_assert_cmpint(prefix, ==, '@');
+
+	prefix = ibis_features_get_prefix_for_mode(features, 'h');
+	g_assert_cmpint(prefix, ==, '%');
+
+	prefix = ibis_features_get_prefix_for_mode(features, 'v');
+	g_assert_cmpint(prefix, ==, '+');
+
+	prefix = ibis_features_get_prefix_for_mode(features, '\0');
+	g_assert_cmpint(prefix, ==, 0);
+
+	prefix = ibis_features_get_prefix_for_mode(features, 'p');
+	g_assert_cmpint(prefix, ==, 0);
+
+	prefix = ibis_features_get_prefix_for_mode(features, 'i');
+	g_assert_cmpint(prefix, ==, 0);
+
+	g_assert_finalize_object(message);
+	g_assert_finalize_object(features);
+}
+
+static void
+test_ibis_features_get_prefix_for_mode_empty(void) {
+	IbisMessage *message = NULL;
+	IbisFeatures *features = NULL;
+	char prefix = '\0';
+
+	features = ibis_features_new();
+	message = ibis_message_new(IBIS_RPL_ISUPPORT);
+	ibis_message_set_params(message, "PREFIX=", NULL);
+	ibis_features_parse(features, message);
+
+	prefix = ibis_features_get_prefix_for_mode(features, 'o');
+	g_assert_cmpint(prefix, ==, '@');
+
+	prefix = ibis_features_get_prefix_for_mode(features, 'v');
+	g_assert_cmpint(prefix, ==, '+');
+
+	prefix = ibis_features_get_prefix_for_mode(features, '\0');
+	g_assert_cmpint(prefix, ==, 0);
+
+	prefix = ibis_features_get_prefix_for_mode(features, 'p');
+	g_assert_cmpint(prefix, ==, 0);
+
+	prefix = ibis_features_get_prefix_for_mode(features, 'i');
+	g_assert_cmpint(prefix, ==, 0);
+
+	g_assert_finalize_object(message);
+	g_assert_finalize_object(features);
+}
+
 /******************************************************************************
  * Main
  *****************************************************************************/
@@ -456,6 +525,7 @@
 	g_test_set_nonfatal_assertions();
 
 	g_test_add_func("/ibis/features/new", test_ibis_features_new);
+
 	g_test_add_func("/ibis/features/parse/fail", test_ibis_features_parse_fail);
 	g_test_add_func("/ibis/features/parse/all", test_ibis_features_parse_all);
 	g_test_add_func("/ibis/featuers/parse/multiple",
@@ -464,7 +534,9 @@
 	g_test_add_func("/ibis/features/parse/none", test_ibis_features_no_parse);
 	g_test_add_func("/ibis/features/parse/invalid-prefix",
 	                test_ibis_features_parse_invalid_prefix);
+
 	g_test_add_func("/ibis/features/clear", test_ibis_features_clear);
+
 	g_test_add_func("/ibis/features/client_tag_deny_none",
 	                test_ibis_features_client_tag_deny_none);
 	g_test_add_func("/ibis/features/client_tag_deny_single",
@@ -478,5 +550,10 @@
 	g_test_add_func("/ibis/features/client_tag_denied_query_with_prefix",
 	                test_ibis_features_client_tag_denied_query_with_prefix);
 
+	g_test_add_func("/ibis/features/get-prefix-for-mode/normal",
+	                test_ibis_features_get_prefix_for_mode_normal);
+	g_test_add_func("/ibis/features/get-prefix-for-mode/empty",
+	                test_ibis_features_get_prefix_for_mode_empty);
+
 	return g_test_run();
 }
