Index: src/core/misc.c
===================================================================
--- src/core/misc.c	(revision 4395)
+++ src/core/misc.c	(working copy)
@@ -615,7 +615,8 @@
 int get_max_column_count(GSList *items, COLUMN_LEN_FUNC len_func,
 			 int max_width, int max_columns,
 			 int item_extra, int item_min_size,
-			 int **save_column_widths, int *rows)
+			 int item_max_size, int **save_column_widths,
+			 int *rows)
 {
         GSList *tmp;
 	int **columns, *columns_width, *columns_rows;
@@ -634,6 +635,10 @@
 	if (max_columns <= 0 || len < max_columns)
                 max_columns = len;
 
+	if (item_max_size <= 0 || item_max_size < item_min_size)
+		item_max_size = max_width;
+	item_max_size += item_extra;
+
 	columns = g_new0(int *, max_columns);
 	columns_width = g_new0(int, max_columns);
 	columns_rows = g_new0(int, max_columns);
@@ -649,6 +654,8 @@
         item_pos = 0; max_len = 0;
 	for (tmp = items; tmp != NULL; tmp = tmp->next) {
 		len = item_extra+len_func(tmp->data);
+		if (len > item_max_size)
+			len = item_max_size;
 		if (max_len < len)
 			max_len = len;
 
Index: src/core/misc.h
===================================================================
--- src/core/misc.h	(revision 4395)
+++ src/core/misc.h	(working copy)
@@ -89,7 +89,8 @@
 int get_max_column_count(GSList *items, COLUMN_LEN_FUNC len_func,
 			 int max_width, int max_columns,
 			 int item_extra, int item_min_size,
-			 int **save_column_widths, int *rows);
+			 int item_max_size, int **save_column_widths,
+			 int *rows);
 
 /* Return a column sorted copy of a list. */
 GSList *columns_sort_list(GSList *list, int rows);
Index: src/fe-common/core/fe-channels.c
===================================================================
--- src/fe-common/core/fe-channels.c	(revision 4395)
+++ src/fe-common/core/fe-channels.c	(working copy)
@@ -346,20 +346,23 @@
 	GString *str;
 	GSList *tmp;
         char *format, *stripped, *prefix_format;
-	char *linebuf, nickmode[2] = { 0, 0 };
+	char *linebuf, nickmode[2] = { 0, 0 }, nickmode_empty;
 	int *columns, cols, rows, last_col_rows, col, row, max_width;
-        int item_extra, linebuf_size, formatnum;
+        int item_extra, linebuf_size, formatnum, nick_max_width;
 
 	window = window_find_closest(channel->server, channel->visible_name,
 				     MSGLEVEL_CLIENTCRAP);
         max_width = window->width;
+	nick_max_width = max_width;
 
+	nickmode_empty = settings_get_bool("show_nickmode_empty") ? ' ' : '\0';
+
         /* get the length of item extra stuff ("[ ] ") */
 	format = format_get_text(MODULE_NAME, NULL,
 				 channel->server, channel->visible_name,
 				 TXT_NAMES_NICK, " ", "");
 	stripped = strip_codes(format);
-	item_extra = strlen(stripped);
+	item_extra = strlen(stripped) + 1;
         g_free(stripped);
 	g_free(format);
 
@@ -367,6 +370,9 @@
 	    settings_get_int("names_max_width") < max_width)
 		max_width = settings_get_int("names_max_width");
 
+	if (settings_get_int("names_nick_max_width") > 0)
+		nick_max_width = settings_get_int("names_nick_max_width");
+
         /* remove width of the timestamp from max_width */
 	format_create_dest(&dest, channel->server, channel->visible_name,
 			   MSGLEVEL_CLIENTCRAP, NULL);
@@ -398,7 +404,8 @@
 	/* calculate columns */
 	cols = get_max_column_count(nicklist, get_nick_length, max_width,
 				    settings_get_int("names_max_columns"),
-				    item_extra, 3, &columns, &rows);
+				    item_extra, 3, nick_max_width, &columns,
+				    &rows);
 	nicklist = columns_sort_list(nicklist, rows);
 
         /* rows in last column */
@@ -412,6 +419,7 @@
         col = 0; row = 0;
 	for (tmp = nicklist; tmp != NULL; tmp = tmp->next) {
 		NICK_REC *rec = tmp->data;
+		int len, end = columns[col] - item_extra;
 
 		if (rec->other)
 			nickmode[0] = rec->other;
@@ -421,17 +429,22 @@
 			nickmode[0] = '%';
 		else if (rec->voice)
 			nickmode[0] = '+';
-		else
-			nickmode[0] = ' ';
-		
-		if (linebuf_size < columns[col]-item_extra+1) {
-			linebuf_size = (columns[col]-item_extra+1)*2;
-                        linebuf = g_realloc(linebuf, linebuf_size);
+		else {
+			nickmode[0] = nickmode_empty;
+			if (nickmode[0] == '\0')
+				end++;
 		}
-		memset(linebuf, ' ', columns[col]-item_extra);
-		linebuf[columns[col]-item_extra] = '\0';
-		memcpy(linebuf, rec->nick, strlen(rec->nick));
 
+		if (linebuf_size < end + 1) {
+			linebuf_size = (end + 1) * 2;
+			linebuf = g_realloc(linebuf, linebuf_size);
+		}
+
+		memset(linebuf, ' ', end);
+		len = strlen(rec->nick);
+		memcpy(linebuf, rec->nick, len < end ? len : end);
+		linebuf[end] = '\0';
+
 		formatnum = rec->op ? TXT_NAMES_NICK_OP :
 			rec->halfop ? TXT_NAMES_NICK_HALFOP :
 			rec->voice ? TXT_NAMES_NICK_VOICE :
@@ -636,6 +649,7 @@
 	settings_add_bool("lookandfeel", "show_names_on_join", TRUE);
 	settings_add_int("lookandfeel", "names_max_columns", 6);
 	settings_add_int("lookandfeel", "names_max_width", 0);
+	settings_add_int("lookandfeel", "names_nick_max_width", 20);
 
 	signal_add("channel created", (SIGNAL_FUNC) signal_channel_created);
 	signal_add("channel destroyed", (SIGNAL_FUNC) signal_channel_destroyed);
Index: src/fe-common/core/fe-help.c
===================================================================
--- src/fe-common/core/fe-help.c	(revision 4395)
+++ src/fe-common/core/fe-help.c	(working copy)
@@ -75,7 +75,7 @@
 
         /* calculate columns */
 	cols = get_max_column_count(cmdlist, get_cmd_length,
-				    max_width, 6, 1, 3, &columns, &rows);
+				    max_width, 6, 1, 3, 0, &columns, &rows);
 	cmdlist = columns_sort_list(cmdlist, rows);
 
         /* rows in last column */
