about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/command/command.c77
-rw-r--r--src/command/commands.c23
-rw-r--r--src/config/preferences.c22
-rw-r--r--src/config/preferences.h3
-rw-r--r--src/ui/console.c161
-rw-r--r--src/ui/occupantswin.c12
-rw-r--r--src/ui/rosterwin.c25
-rw-r--r--src/ui/window.c6
-rw-r--r--src/ui/window.h2
9 files changed, 202 insertions, 129 deletions
diff --git a/src/command/command.c b/src/command/command.c
index 471fcd29..47cc7d9b 100644
--- a/src/command/command.c
+++ b/src/command/command.c
@@ -280,6 +280,7 @@ static struct cmd_t command_defs[] =
             "/roster order name|presence",
             "/roster char header <char>|none",
             "/roster char contact <char>|none",
+            "/roster indent contact <indent>",
             "/roster size <percent>",
             "/roster add <jid> [<nick>]",
             "/roster remove <jid>",
@@ -290,38 +291,39 @@ static struct cmd_t command_defs[] =
             "Manage your roster, and roster display settings. "
             "Passing no arguments lists all contacts in your roster.")
         CMD_ARGS(
-            { "online",              "Show all online contacts in your roster." },
-            { "show",                "Show the roster panel." },
-            { "show offline",        "Show offline contacts in the roster panel." },
-            { "show resource",       "Show contact's connected resources in the roster panel." },
-            { "show presence",       "Show contact's presence in the roster panel." },
-            { "show status",         "Show contact's status message in the roster panel." },
-            { "show empty",          "When grouping by presence, show empty presence groups." },
-            { "show count",          "Show number of contacts in group/presence." },
-            { "show priority",       "Show resource priority." },
-            { "hide",                "Hide the roster panel." },
-            { "hide offline",        "Hide offline contacts in the roster panel." },
-            { "hide resource",       "Hide contact's connected resources in the roster panel." },
-            { "hide presence",       "Hide contact's presence in the roster panel." },
-            { "hide status",         "Hide contact's status message in the roster panel." },
-            { "hide empty",          "When grouping by presence, hide empty presence groups." },
-            { "hide count",          "Hide number of contacts in group/presence." },
-            { "hide priority",       "Hide resource priority." },
-            { "by group",            "Group contacts in the roster panel by roster group." },
-            { "by presence",         "Group contacts in the roster panel by presence." },
-            { "by none",             "No grouping in the roster panel." },
-            { "order name",          "Order roster items by name only." },
-            { "order presence",      "Order roster items by presence, and then by name." },
-            { "char header <char>",  "Prefix roster headers with specificed character." },
-            { "char header none",    "Remove roster header character prefix." },
-            { "char contact <char>", "Prefix roster contacts with specificed character." },
-            { "char contact none",   "Remove roster contact character prefix." },
-            { "size <precent>",      "Percentage of the screen taken up by the roster (1-99)." },
-            { "add <jid> [<nick>]",  "Add a new item to the roster." },
-            { "remove <jid>",        "Removes an item from the roster." },
-            { "remove_all contacts", "Remove all items from roster." },
-            { "nick <jid> <nick>",   "Change a contacts nickname." },
-            { "clearnick <jid>",     "Removes the current nickname." })
+            { "online",                     "Show all online contacts in your roster." },
+            { "show",                       "Show the roster panel." },
+            { "show offline",               "Show offline contacts in the roster panel." },
+            { "show resource",              "Show contact's connected resources in the roster panel." },
+            { "show presence",              "Show contact's presence in the roster panel." },
+            { "show status",                "Show contact's status message in the roster panel." },
+            { "show empty",                 "When grouping by presence, show empty presence groups." },
+            { "show count",                 "Show number of contacts in group/presence." },
+            { "show priority",              "Show resource priority." },
+            { "hide",                       "Hide the roster panel." },
+            { "hide offline",               "Hide offline contacts in the roster panel." },
+            { "hide resource",              "Hide contact's connected resources in the roster panel." },
+            { "hide presence",              "Hide contact's presence in the roster panel." },
+            { "hide status",                "Hide contact's status message in the roster panel." },
+            { "hide empty",                 "When grouping by presence, hide empty presence groups." },
+            { "hide count",                 "Hide number of contacts in group/presence." },
+            { "hide priority",              "Hide resource priority." },
+            { "by group",                   "Group contacts in the roster panel by roster group." },
+            { "by presence",                "Group contacts in the roster panel by presence." },
+            { "by none",                    "No grouping in the roster panel." },
+            { "order name",                 "Order roster items by name only." },
+            { "order presence",             "Order roster items by presence, and then by name." },
+            { "char header <char>",         "Prefix roster headers with specificed character." },
+            { "char header none",           "Remove roster header character prefix." },
+            { "char contact <char>",        "Prefix roster contacts with specificed character." },
+            { "char contact none",          "Remove roster contact character prefix." },
+            { "indent contact <indent>",    "Indent contact line by <indent> spaces." },
+            { "size <precent>",             "Percentage of the screen taken up by the roster (1-99)." },
+            { "add <jid> [<nick>]",         "Add a new item to the roster." },
+            { "remove <jid>",               "Removes an item from the roster." },
+            { "remove_all contacts",        "Remove all items from roster." },
+            { "nick <jid> <nick>",          "Change a contacts nickname." },
+            { "clearnick <jid>",            "Removes the current nickname." })
         CMD_EXAMPLES(
             "/roster",
             "/roster add someone@contacts.org",
@@ -1784,6 +1786,7 @@ static Autocomplete wins_ac;
 static Autocomplete roster_ac;
 static Autocomplete roster_char_ac;
 static Autocomplete roster_char_none_ac;
+static Autocomplete roster_indent_ac;
 static Autocomplete roster_option_ac;
 static Autocomplete roster_by_ac;
 static Autocomplete roster_order_ac;
@@ -2033,6 +2036,7 @@ cmd_init(void)
     autocomplete_add(roster_ac, "order");
     autocomplete_add(roster_ac, "size");
     autocomplete_add(roster_ac, "char");
+    autocomplete_add(roster_ac, "indent");
 
     roster_char_ac = autocomplete_new();
     autocomplete_add(roster_char_ac, "header");
@@ -2041,6 +2045,9 @@ cmd_init(void)
     roster_char_none_ac = autocomplete_new();
     autocomplete_add(roster_char_none_ac, "none");
 
+    roster_indent_ac = autocomplete_new();
+    autocomplete_add(roster_indent_ac, "contact");
+
     roster_option_ac = autocomplete_new();
     autocomplete_add(roster_option_ac, "offline");
     autocomplete_add(roster_option_ac, "resource");
@@ -2313,6 +2320,7 @@ cmd_uninit(void)
     autocomplete_free(roster_ac);
     autocomplete_free(roster_char_ac);
     autocomplete_free(roster_char_none_ac);
+    autocomplete_free(roster_indent_ac);
     autocomplete_free(roster_option_ac);
     autocomplete_free(roster_by_ac);
     autocomplete_free(roster_order_ac);
@@ -2502,6 +2510,7 @@ cmd_reset_autocomplete(ProfWin *window)
     autocomplete_reset(roster_ac);
     autocomplete_reset(roster_char_ac);
     autocomplete_reset(roster_char_none_ac);
+    autocomplete_reset(roster_indent_ac);
     autocomplete_reset(roster_option_ac);
     autocomplete_reset(roster_by_ac);
     autocomplete_reset(roster_order_ac);
@@ -2934,6 +2943,10 @@ _roster_autocomplete(ProfWin *window, const char *const input)
     if (result) {
         return result;
     }
+    result = autocomplete_param_with_ac(input, "/roster indent", roster_indent_ac, TRUE);
+    if (result) {
+        return result;
+    }
     result = autocomplete_param_with_ac(input, "/roster", roster_ac, TRUE);
     if (result) {
         return result;
diff --git a/src/command/commands.c b/src/command/commands.c
index ca6a1003..37c54131 100644
--- a/src/command/commands.c
+++ b/src/command/commands.c
@@ -1781,6 +1781,29 @@ cmd_roster(ProfWin *window, const char *const command, gchar **args)
         }
         return TRUE;
 
+    // set indentations
+    } else if (g_strcmp0(args[0], "indent") == 0) {
+        if (g_strcmp0(args[1], "contact") == 0) {
+            if (!args[2]) {
+                cons_bad_cmd_usage(command);
+            } else {
+                int intval = 0;
+                char *err_msg = NULL;
+                gboolean res = strtoi_range(args[2], &intval, 0, 10, &err_msg);
+                if (res) {
+                    prefs_set_roster_contact_indent(intval);
+                    cons_show("Roster contact indent set to: %d", intval);
+                    rosterwin_roster();
+                } else {
+                    cons_show(err_msg);
+                    free(err_msg);
+                }
+            }
+        } else {
+            cons_bad_cmd_usage(command);
+        }
+        return TRUE;
+
     // show/hide roster
     } else if (g_strcmp0(args[0], "show") == 0) {
         if (args[1] == NULL) {
diff --git a/src/config/preferences.c b/src/config/preferences.c
index 414de9f4..0916cf86 100644
--- a/src/config/preferences.c
+++ b/src/config/preferences.c
@@ -506,6 +506,28 @@ prefs_clear_roster_contact_char(void)
     _save_prefs();
 }
 
+gint
+prefs_get_roster_contact_indent(void)
+{
+    if (!g_key_file_has_key(prefs, PREF_GROUP_UI, "roster.contact.indent", NULL)) {
+        return 2;
+    }
+
+    gint result = g_key_file_get_integer(prefs, PREF_GROUP_UI, "roster.contact.indent", NULL);
+    if (result < 0) {
+        result = 0;
+    }
+
+    return result;
+}
+
+void
+prefs_set_roster_contact_indent(gint value)
+{
+    g_key_file_set_integer(prefs, PREF_GROUP_UI, "roster.contact.indent", value);
+    _save_prefs();
+}
+
 gboolean
 prefs_add_alias(const char *const name, const char *const value)
 {
diff --git a/src/config/preferences.h b/src/config/preferences.h
index da4eef88..374f6947 100644
--- a/src/config/preferences.h
+++ b/src/config/preferences.h
@@ -172,6 +172,9 @@ char prefs_get_roster_contact_char(void);
 void prefs_set_roster_contact_char(char ch);
 void prefs_clear_roster_contact_char(void);
 
+gint prefs_get_roster_contact_indent(void);
+void prefs_set_roster_contact_indent(gint value);
+
 void prefs_add_login(const char *jid);
 
 gboolean prefs_add_alias(const char *const name, const char *const value);
diff --git a/src/ui/console.c b/src/ui/console.c
index ac63005e..0b9e18c4 100644
--- a/src/ui/console.c
+++ b/src/ui/console.c
@@ -960,9 +960,9 @@ cons_theme_setting(void)
 {
     char *theme = prefs_get_string(PREF_THEME);
     if (theme == NULL) {
-        cons_show("Theme (/theme)                : default");
+        cons_show("Theme (/theme)                  : default");
     } else {
-        cons_show("Theme (/theme)                : %s", theme);
+        cons_show("Theme (/theme)                  : %s", theme);
     }
     prefs_free_string(theme);
 }
@@ -971,58 +971,58 @@ void
 cons_privileges_setting(void)
 {
     if (prefs_get_boolean(PREF_MUC_PRIVILEGES))
-        cons_show("MUC privileges (/privileges)  : ON");
+        cons_show("MUC privileges (/privileges)    : ON");
     else
-        cons_show("MUC privileges (/privileges)  : OFF");
+        cons_show("MUC privileges (/privileges)    : OFF");
 }
 
 void
 cons_beep_setting(void)
 {
     if (prefs_get_boolean(PREF_BEEP))
-        cons_show("Terminal beep (/beep)         : ON");
+        cons_show("Terminal beep (/beep)           : ON");
     else
-        cons_show("Terminal beep (/beep)         : OFF");
+        cons_show("Terminal beep (/beep)           : OFF");
 }
 
 void
 cons_resource_setting(void)
 {
     if (prefs_get_boolean(PREF_RESOURCE_TITLE))
-        cons_show("Resource title (/resource)    : ON");
+        cons_show("Resource title (/resource)      : ON");
     else
-        cons_show("Resource title (/resource)    : OFF");
+        cons_show("Resource title (/resource)      : OFF");
     if (prefs_get_boolean(PREF_RESOURCE_MESSAGE))
-        cons_show("Resource message (/resource)  : ON");
+        cons_show("Resource message (/resource)    : ON");
     else
-        cons_show("Resource message (/resource)  : OFF");
+        cons_show("Resource message (/resource)    : OFF");
 }
 
 void
 cons_wrap_setting(void)
 {
     if (prefs_get_boolean(PREF_WRAP))
-        cons_show("Word wrap (/wrap)             : ON");
+        cons_show("Word wrap (/wrap)               : ON");
     else
-        cons_show("Word wrap (/wrap)             : OFF");
+        cons_show("Word wrap (/wrap)               : OFF");
 }
 
 void
 cons_winstidy_setting(void)
 {
     if (prefs_get_boolean(PREF_WINS_AUTO_TIDY))
-        cons_show("Window Auto Tidy (/wins)      : ON");
+        cons_show("Window Auto Tidy (/wins)        : ON");
     else
-        cons_show("Window Auto Tidy (/wins)      : OFF");
+        cons_show("Window Auto Tidy (/wins)        : OFF");
 }
 
 void
 cons_encwarn_setting(void)
 {
     if (prefs_get_boolean(PREF_ENC_WARN)) {
-        cons_show("Warn unencrypted (/encwarn)   : ON");
+        cons_show("Warn unencrypted (/encwarn)     : ON");
     } else {
-        cons_show("Warn unencrypted (/encwarn)   : OFF");
+        cons_show("Warn unencrypted (/encwarn)     : OFF");
     }
 }
 
@@ -1030,9 +1030,9 @@ void
 cons_tlsshow_setting(void)
 {
     if (prefs_get_boolean(PREF_TLS_SHOW)) {
-        cons_show("TLS show (/tls)               : ON");
+        cons_show("TLS show (/tls)                 : ON");
     } else {
-        cons_show("TLS show (/tls)               : OFF");
+        cons_show("TLS show (/tls)                 : OFF");
     }
 }
 
@@ -1040,44 +1040,44 @@ void
 cons_presence_setting(void)
 {
     if (prefs_get_boolean(PREF_PRESENCE))
-        cons_show("Contact presence (/presence)  : ON");
+        cons_show("Contact presence (/presence)    : ON");
     else
-        cons_show("Contact presence (/presence)  : OFF");
+        cons_show("Contact presence (/presence)    : OFF");
 }
 
 void
 cons_flash_setting(void)
 {
     if (prefs_get_boolean(PREF_FLASH))
-        cons_show("Terminal flash (/flash)       : ON");
+        cons_show("Terminal flash (/flash)         : ON");
     else
-        cons_show("Terminal flash (/flash)       : OFF");
+        cons_show("Terminal flash (/flash)         : OFF");
 }
 
 void
 cons_splash_setting(void)
 {
     if (prefs_get_boolean(PREF_SPLASH))
-        cons_show("Splash screen (/splash)       : ON");
+        cons_show("Splash screen (/splash)         : ON");
     else
-        cons_show("Splash screen (/splash)       : OFF");
+        cons_show("Splash screen (/splash)         : OFF");
 }
 
 void
 cons_occupants_setting(void)
 {
     if (prefs_get_boolean(PREF_OCCUPANTS))
-        cons_show("Occupants (/occupants)        : show");
+        cons_show("Occupants (/occupants)          : show");
     else
-        cons_show("Occupants (/occupants)        : hide");
+        cons_show("Occupants (/occupants)          : hide");
 
     if (prefs_get_boolean(PREF_OCCUPANTS_JID))
-        cons_show("Occupant jids (/occupants)    : show");
+        cons_show("Occupant jids (/occupants)      : show");
     else
-        cons_show("Occupant jids (/occupants)    : hide");
+        cons_show("Occupant jids (/occupants)      : hide");
 
     int size = prefs_get_occupants_size();
-    cons_show("Occupants size (/occupants)   : %d", size);
+    cons_show("Occupants size (/occupants)     : %d", size);
 }
 
 void
@@ -1097,55 +1097,55 @@ cons_time_setting(void)
 {
     char *pref_time_console = prefs_get_string(PREF_TIME_CONSOLE);
     if (g_strcmp0(pref_time_console, "off") == 0)
-        cons_show("Time console (/time)          : OFF");
+        cons_show("Time console (/time)            : OFF");
     else
-        cons_show("Time console (/time)          : %s", pref_time_console);
+        cons_show("Time console (/time)            : %s", pref_time_console);
     prefs_free_string(pref_time_console);
 
     char *pref_time_chat = prefs_get_string(PREF_TIME_CHAT);
     if (g_strcmp0(pref_time_chat, "off") == 0)
-        cons_show("Time chat (/time)             : OFF");
+        cons_show("Time chat (/time)               : OFF");
     else
-        cons_show("Time chat (/time)             : %s", pref_time_chat);
+        cons_show("Time chat (/time)               : %s", pref_time_chat);
     prefs_free_string(pref_time_chat);
 
     char *pref_time_muc = prefs_get_string(PREF_TIME_MUC);
     if (g_strcmp0(pref_time_muc, "off") == 0)
-        cons_show("Time MUC (/time)              : OFF");
+        cons_show("Time MUC (/time)                : OFF");
     else
-        cons_show("Time MUC (/time)              : %s", pref_time_muc);
+        cons_show("Time MUC (/time)                : %s", pref_time_muc);
     prefs_free_string(pref_time_muc);
 
     char *pref_time_mucconf = prefs_get_string(PREF_TIME_MUCCONFIG);
     if (g_strcmp0(pref_time_mucconf, "off") == 0)
-        cons_show("Time MUC config (/time)       : OFF");
+        cons_show("Time MUC config (/time)         : OFF");
     else
-        cons_show("Time MUC config (/time)       : %s", pref_time_mucconf);
+        cons_show("Time MUC config (/time)         : %s", pref_time_mucconf);
     prefs_free_string(pref_time_mucconf);
 
     char *pref_time_private = prefs_get_string(PREF_TIME_PRIVATE);
     if (g_strcmp0(pref_time_private, "off") == 0)
-        cons_show("Time private (/time)          : OFF");
+        cons_show("Time private (/time)            : OFF");
     else
-        cons_show("Time private (/time)          : %s", pref_time_private);
+        cons_show("Time private (/time)            : %s", pref_time_private);
     prefs_free_string(pref_time_private);
 
     char *pref_time_xml = prefs_get_string(PREF_TIME_XMLCONSOLE);
     if (g_strcmp0(pref_time_xml, "off") == 0)
-        cons_show("Time XML Console (/time)      : OFF");
+        cons_show("Time XML Console (/time)        : OFF");
     else
-        cons_show("Time XML Console (/time)      : %s", pref_time_xml);
+        cons_show("Time XML Console (/time)        : %s", pref_time_xml);
     prefs_free_string(pref_time_xml);
 
     char *pref_time_statusbar = prefs_get_string(PREF_TIME_STATUSBAR);
     if (g_strcmp0(pref_time_statusbar, "off") == 0)
-        cons_show("Time statusbar (/time)        : OFF");
+        cons_show("Time statusbar (/time)          : OFF");
     else
-        cons_show("Time statusbar (/time)        : %s", pref_time_statusbar);
+        cons_show("Time statusbar (/time)          : %s", pref_time_statusbar);
     prefs_free_string(pref_time_statusbar);
 
     char *pref_time_lastactivity = prefs_get_string(PREF_TIME_LASTACTIVITY);
-    cons_show("Time last activity (/time)    : %s", pref_time_lastactivity);
+    cons_show("Time last activity (/time)      : %s", pref_time_lastactivity);
     prefs_free_string(pref_time_lastactivity);
 }
 
@@ -1153,9 +1153,9 @@ void
 cons_vercheck_setting(void)
 {
     if (prefs_get_boolean(PREF_VERCHECK))
-        cons_show("Version checking (/vercheck)  : ON");
+        cons_show("Version checking (/vercheck)    : ON");
     else
-        cons_show("Version checking (/vercheck)  : OFF");
+        cons_show("Version checking (/vercheck)    : OFF");
 }
 
 void
@@ -1165,9 +1165,9 @@ cons_statuses_setting(void)
     char *chat = prefs_get_string(PREF_STATUSES_CHAT);
     char *muc = prefs_get_string(PREF_STATUSES_MUC);
 
-    cons_show("Console statuses (/statuses)  : %s", console);
-    cons_show("Chat statuses (/statuses)     : %s", chat);
-    cons_show("MUC statuses (/statuses)      : %s", muc);
+    cons_show("Console statuses (/statuses)    : %s", console);
+    cons_show("Chat statuses (/statuses)       : %s", chat);
+    cons_show("MUC statuses (/statuses)        : %s", muc);
 
     prefs_free_string(console);
     prefs_free_string(chat);
@@ -1178,14 +1178,14 @@ void
 cons_titlebar_setting(void)
 {
     if (prefs_get_boolean(PREF_TITLEBAR_SHOW)) {
-        cons_show("Titlebar show (/titlebar)     : ON");
+        cons_show("Titlebar show (/titlebar)       : ON");
     } else {
-        cons_show("Titlebar show (/titlebar)     : OFF");
+        cons_show("Titlebar show (/titlebar)       : OFF");
     }
     if (prefs_get_boolean(PREF_TITLEBAR_GOODBYE)) {
-        cons_show("Titlebar goodbye (/titlebar)  : ON");
+        cons_show("Titlebar goodbye (/titlebar)    : ON");
     } else {
-        cons_show("Titlebar goodbye (/titlebar)  : OFF");
+        cons_show("Titlebar goodbye (/titlebar)    : OFF");
     }
 }
 
@@ -1193,67 +1193,70 @@ void
 cons_roster_setting(void)
 {
     if (prefs_get_boolean(PREF_ROSTER))
-        cons_show("Roster (/roster)              : show");
+        cons_show("Roster (/roster)                : show");
     else
-        cons_show("Roster (/roster)              : hide");
+        cons_show("Roster (/roster)                : hide");
 
     if (prefs_get_boolean(PREF_ROSTER_OFFLINE))
-        cons_show("Roster offline (/roster)      : show");
+        cons_show("Roster offline (/roster)        : show");
     else
-        cons_show("Roster offline (/roster)      : hide");
+        cons_show("Roster offline (/roster)        : hide");
 
     if (prefs_get_boolean(PREF_ROSTER_RESOURCE))
-        cons_show("Roster resource (/roster)     : show");
+        cons_show("Roster resource (/roster)       : show");
     else
-        cons_show("Roster resource (/roster)     : hide");
+        cons_show("Roster resource (/roster)       : hide");
 
     if (prefs_get_boolean(PREF_ROSTER_PRESENCE))
-        cons_show("Roster presence (/roster)     : show");
+        cons_show("Roster presence (/roster)       : show");
     else
-        cons_show("Roster presence (/roster)     : hide");
+        cons_show("Roster presence (/roster)       : hide");
 
     if (prefs_get_boolean(PREF_ROSTER_STATUS))
-        cons_show("Roster status (/roster)       : show");
+        cons_show("Roster status (/roster)         : show");
     else
-        cons_show("Roster status (/roster)       : hide");
+        cons_show("Roster status (/roster)         : hide");
 
     if (prefs_get_boolean(PREF_ROSTER_EMPTY))
-        cons_show("Roster empty (/roster)        : show");
+        cons_show("Roster empty (/roster)          : show");
     else
-        cons_show("Roster empty (/roster)        : hide");
+        cons_show("Roster empty (/roster)          : hide");
 
     if (prefs_get_boolean(PREF_ROSTER_COUNT))
-        cons_show("Roster count (/roster)        : show");
+        cons_show("Roster count (/roster)          : show");
     else
-        cons_show("Roster count (/roster)        : hide");
+        cons_show("Roster count (/roster)          : hide");
 
     if (prefs_get_boolean(PREF_ROSTER_PRIORITY))
-        cons_show("Roster priority (/roster)     : show");
+        cons_show("Roster priority (/roster)       : show");
     else
-        cons_show("Roster priority (/roster)     : hide");
+        cons_show("Roster priority (/roster)       : hide");
 
     char *by = prefs_get_string(PREF_ROSTER_BY);
-    cons_show("Roster by (/roster)           : %s", by);
+    cons_show("Roster by (/roster)             : %s", by);
     prefs_free_string(by);
 
     char *order = prefs_get_string(PREF_ROSTER_ORDER);
-    cons_show("Roster order (/roster)        : %s", order);
+    cons_show("Roster order (/roster)          : %s", order);
     prefs_free_string(order);
 
     int size = prefs_get_roster_size();
-    cons_show("Roster size (/roster)         : %d", size);
+    cons_show("Roster size (/roster)           : %d", size);
 
     char header_ch = prefs_get_roster_header_char();
     if (header_ch)
-        cons_show("Roster header char (/roster)  : %c", header_ch);
+        cons_show("Roster header char (/roster)    : %c", header_ch);
     else
-        cons_show("Roster header char (/roster)  : none");
+        cons_show("Roster header char (/roster)    : none");
 
     char contact_ch = prefs_get_roster_contact_char();
     if (contact_ch)
-        cons_show("Roster contact char (/roster) : %c", contact_ch);
+        cons_show("Roster contact char (/roster)   : %c", contact_ch);
     else
-        cons_show("Roster contact char (/roster) : none");
+        cons_show("Roster contact char (/roster)   : none");
+
+    gint contact_indent = prefs_get_roster_contact_indent();
+    cons_show("Roster contact indent (/roster) : %d", contact_indent);
 }
 
 void
@@ -1457,11 +1460,11 @@ cons_show_chat_prefs(void)
 void
 cons_inpblock_setting(void)
 {
-    cons_show("Input timeout (/inpblock)     : %d milliseconds", prefs_get_inpblock());
+    cons_show("Input timeout (/inpblock)       : %d milliseconds", prefs_get_inpblock());
     if (prefs_get_boolean(PREF_INPBLOCK_DYNAMIC)) {
-        cons_show("Dynamic timeout (/inpblock)   : ON");
+        cons_show("Dynamic timeout (/inpblock)     : ON");
     } else {
-        cons_show("Dynamic timeout (/inpblock)   : OFF");
+        cons_show("Dynamic timeout (/inpblock)     : OFF");
     }
 }
 
diff --git a/src/ui/occupantswin.c b/src/ui/occupantswin.c
index 36447437..71474a80 100644
--- a/src/ui/occupantswin.c
+++ b/src/ui/occupantswin.c
@@ -48,13 +48,13 @@ _occuptantswin_occupant(ProfLayoutSplit *layout, Occupant *occupant, gboolean sh
 
     GString *msg = g_string_new("   ");
     g_string_append(msg, occupant->nick);
-    win_printline_nowrap(layout->subwin, msg->str);
+    win_print_nowrap(layout->subwin, msg->str, TRUE);
     g_string_free(msg, TRUE);
 
     if (showjid && occupant->jid) {
         GString *msg = g_string_new("     ");
         g_string_append(msg, occupant->jid);
-        win_printline_nowrap(layout->subwin, msg->str);
+        win_print_nowrap(layout->subwin, msg->str, TRUE);
         g_string_free(msg, TRUE);
     }
 
@@ -75,7 +75,7 @@ occupantswin_occupants(const char *const roomjid)
 
             if (prefs_get_boolean(PREF_MUC_PRIVILEGES)) {
                 wattron(layout->subwin, theme_attrs(THEME_OCCUPANTS_HEADER));
-                win_printline_nowrap(layout->subwin, " -Moderators");
+                win_print_nowrap(layout->subwin, " -Moderators", TRUE);
                 wattroff(layout->subwin, theme_attrs(THEME_OCCUPANTS_HEADER));
                 GList *roster_curr = occupants;
                 while (roster_curr) {
@@ -87,7 +87,7 @@ occupantswin_occupants(const char *const roomjid)
                 }
 
                 wattron(layout->subwin, theme_attrs(THEME_OCCUPANTS_HEADER));
-                win_printline_nowrap(layout->subwin, " -Participants");
+                win_print_nowrap(layout->subwin, " -Participants", TRUE);
                 wattroff(layout->subwin, theme_attrs(THEME_OCCUPANTS_HEADER));
                 roster_curr = occupants;
                 while (roster_curr) {
@@ -99,7 +99,7 @@ occupantswin_occupants(const char *const roomjid)
                 }
 
                 wattron(layout->subwin, theme_attrs(THEME_OCCUPANTS_HEADER));
-                win_printline_nowrap(layout->subwin, " -Visitors");
+                win_print_nowrap(layout->subwin, " -Visitors", TRUE);
                 wattroff(layout->subwin, theme_attrs(THEME_OCCUPANTS_HEADER));
                 roster_curr = occupants;
                 while (roster_curr) {
@@ -111,7 +111,7 @@ occupantswin_occupants(const char *const roomjid)
                 }
             } else {
                 wattron(layout->subwin, theme_attrs(THEME_OCCUPANTS_HEADER));
-                win_printline_nowrap(layout->subwin, " -Occupants\n");
+                win_print_nowrap(layout->subwin, " -Occupants\n", TRUE);
                 wattroff(layout->subwin, theme_attrs(THEME_OCCUPANTS_HEADER));
                 GList *roster_curr = occupants;
                 while (roster_curr) {
diff --git a/src/ui/rosterwin.c b/src/ui/rosterwin.c
index f13f5dc5..0dc1baed 100644
--- a/src/ui/rosterwin.c
+++ b/src/ui/rosterwin.c
@@ -64,7 +64,7 @@ _rosterwin_presence(ProfLayoutSplit *layout, int indent, theme_item_t colour, co
                 indent--;
             }
             g_string_append_printf(msg, "\"%s\"", status);
-            win_printline_nowrap(layout->subwin, msg->str);
+            win_print_nowrap(layout->subwin, msg->str, TRUE);
             g_string_free(msg, TRUE);
             wattroff(layout->subwin, theme_attrs(colour));
         }
@@ -85,7 +85,7 @@ _rosterwin_presence(ProfLayoutSplit *layout, int indent, theme_item_t colour, co
         } else if (status && prefs_get_boolean(PREF_ROSTER_STATUS)) {
             g_string_append_printf(msg, "\"%s\"", status);
         }
-        win_printline_nowrap(layout->subwin, msg->str);
+        win_print_nowrap(layout->subwin, msg->str, TRUE);
         g_string_free(msg, TRUE);
         wattroff(layout->subwin, theme_attrs(colour));
     }
@@ -108,7 +108,7 @@ _rosterwin_resource(ProfLayoutSplit *layout, PContact contact)
             if (prefs_get_boolean(PREF_ROSTER_PRIORITY)) {
                 g_string_append_printf(msg, " [%d]", resource->priority);
             }
-            win_printline_nowrap(layout->subwin, msg->str);
+            win_print_nowrap(layout->subwin, msg->str, TRUE);
             g_string_free(msg, TRUE);
             wattroff(layout->subwin, theme_attrs(resource_presence_colour));
 
@@ -138,13 +138,20 @@ _rosterwin_contact(ProfLayoutSplit *layout, PContact contact)
     theme_item_t presence_colour = theme_main_presence_attrs(presence);
 
     wattron(layout->subwin, theme_attrs(presence_colour));
-    GString *msg = g_string_new("   ");
+    GString *msg = g_string_new(" ");
+    int indent = prefs_get_roster_contact_indent();
+    if (indent > 0) {
+        while (indent > 0) {
+            g_string_append(msg, " ");
+            indent--;
+        }
+    }
     char ch = prefs_get_roster_contact_char();
     if (ch) {
         g_string_append_printf(msg, "%c", ch);
     }
     g_string_append(msg, name);
-    win_printline_nowrap(layout->subwin, msg->str);
+    win_print_nowrap(layout->subwin, msg->str, TRUE);
     g_string_free(msg, TRUE);
     wattroff(layout->subwin, theme_attrs(presence_colour));
 
@@ -172,7 +179,7 @@ _rosterwin_contacts_by_presence(ProfLayoutSplit *layout, const char *const prese
         if (prefs_get_boolean(PREF_ROSTER_COUNT)) {
             g_string_append_printf(title_str, " (%d)", g_slist_length(contacts));
         }
-        win_printline_nowrap(layout->subwin, title_str->str);
+        win_print_nowrap(layout->subwin, title_str->str, TRUE);
         g_string_free(title_str, TRUE);
         wattroff(layout->subwin, theme_attrs(THEME_ROSTER_HEADER));
     }
@@ -212,7 +219,7 @@ _rosterwin_contacts_by_group(ProfLayoutSplit *layout, char *group)
         if (prefs_get_boolean(PREF_ROSTER_COUNT)) {
             g_string_append_printf(title, " (%d)", g_slist_length(contacts));
         }
-        win_printline_nowrap(layout->subwin, title->str);
+        win_print_nowrap(layout->subwin, title->str, TRUE);
         g_string_free(title, TRUE);
         wattroff(layout->subwin, theme_attrs(THEME_ROSTER_HEADER));
 
@@ -251,7 +258,7 @@ _rosterwin_contacts_by_no_group(ProfLayoutSplit *layout)
         if (prefs_get_boolean(PREF_ROSTER_COUNT)) {
             g_string_append_printf(title, " (%d)", g_slist_length(contacts));
         }
-        win_printline_nowrap(layout->subwin, title->str);
+        win_print_nowrap(layout->subwin, title->str, TRUE);
         g_string_free(title, TRUE);
         wattroff(layout->subwin, theme_attrs(THEME_ROSTER_HEADER));
 
@@ -317,7 +324,7 @@ rosterwin_roster(void)
             if (prefs_get_boolean(PREF_ROSTER_COUNT)) {
                 g_string_append_printf(title, " (%d)", g_slist_length(contacts));
             }
-            win_printline_nowrap(layout->subwin, title->str);
+            win_print_nowrap(layout->subwin, title->str, TRUE);
             g_string_free(title, TRUE);
             wattroff(layout->subwin, theme_attrs(THEME_ROSTER_HEADER));
 
diff --git a/src/ui/window.c b/src/ui/window.c
index 91e8b6c2..3ca9b927 100644
--- a/src/ui/window.c
+++ b/src/ui/window.c
@@ -1266,12 +1266,14 @@ win_unread(ProfWin *window)
 }
 
 void
-win_printline_nowrap(WINDOW *win, char *msg)
+win_print_nowrap(WINDOW *win, char *msg, gboolean newline)
 {
     int maxx = getmaxx(win);
     int cury = getcury(win);
 
     waddnstr(win, msg, maxx);
 
-    wmove(win, cury+1, 0);
+    if (newline) {
+        wmove(win, cury+1, 0);
+    }
 }
diff --git a/src/ui/window.h b/src/ui/window.h
index 643cdf7b..24d71ad6 100644
--- a/src/ui/window.h
+++ b/src/ui/window.h
@@ -67,7 +67,7 @@ void win_newline(ProfWin *window);
 void win_redraw(ProfWin *window);
 int win_roster_cols(void);
 int win_occpuants_cols(void);
-void win_printline_nowrap(WINDOW *win, char *msg);
+void win_print_nowrap(WINDOW *win, char *msg, gboolean newline);
 void win_mark_received(ProfWin *window, const char *const id);
 
 gboolean win_has_active_subwin(ProfWin *window);