diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index b19e3ca..5ee18d0 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,26 @@
 2015-05-21  Andrew Burgess  <andrew.burgess@embecosm.com>
 
+	* completer.c (reg_or_group_completer_1): New function containing
+	old reg_or_group_completer.
+	(reg_or_group_completer): Call new reg_or_group_completer_1.
+	(reggroup_completer): Call new reg_or_group_completer_1.
+	* completer.h (reggroup_completer): Add declaration.
+	* tui/tui-regs.c: Add 'completer.h' include.
+	(tui_reg_next_command): Renamed to...
+	(tui_reg_name): ...this.  Adjust parameters.
+	(tui_reg_prev_command): Renamed to...
+	(tui_reg_prev): ...this.  Adjust parameters.
+	(tui_reg_float_command): Delete.
+	(tui_reg_general_command): Delete.
+	(tui_reg_system_command): Delete.
+	(tui_reg_command): Rewrite to perform switching of register group.
+	(tuireglist): Remove.
+	(tui_reggroup_completer): New function.
+	(_initialize_tui_regs): Remove 'tui reg' sub-commands, update
+	creation of 'tui reg' command.
+
+2015-05-21  Andrew Burgess  <andrew.burgess@embecosm.com>
+
 	* tui/tui-regs.c (tui_reg_prev_command): New function.
 	(_initialize_tui_regs): Add 'prev' command for 'tui reg'.
 	* reggroups.c (reggroup_prev): New function.
diff --git a/gdb/completer.c b/gdb/completer.c
index c8c0e4c..73f734e 100644
--- a/gdb/completer.c
+++ b/gdb/completer.c
@@ -971,9 +971,10 @@ signal_completer (struct cmd_list_element *ignore,
 
 /* Complete on a register or reggroup.  */
 
-VEC (char_ptr) *
-reg_or_group_completer (struct cmd_list_element *ignore,
-			const char *text, const char *word)
+static VEC (char_ptr) *
+reg_or_group_completer_1 (struct cmd_list_element *ignore,
+			  const char *text, const char *word,
+			  int add_registers, int add_reggroups)
 {
   VEC (char_ptr) *result = NULL;
   size_t len = strlen (word);
@@ -985,28 +986,46 @@ reg_or_group_completer (struct cmd_list_element *ignore,
   if (!target_has_registers)
     return result;
 
+  gdb_assert (add_registers || add_reggroups);
   gdbarch = get_frame_arch (get_selected_frame (NULL));
 
-  for (i = 0;
-       (name = user_reg_map_regnum_to_name (gdbarch, i)) != NULL;
-       i++)
-    {
-      if (*name != '\0' && strncmp (word, name, len) == 0)
-	VEC_safe_push (char_ptr, result, xstrdup (name));
-    }
-
-  for (group = reggroup_next (gdbarch, NULL);
-       group != NULL;
-       group = reggroup_next (gdbarch, group))
-    {
-      name = reggroup_name (group);
-      if (strncmp (word, name, len) == 0)
-	VEC_safe_push (char_ptr, result, xstrdup (name));
-    }
+  if (add_registers)
+    for (i = 0;
+	 (name = user_reg_map_regnum_to_name (gdbarch, i)) != NULL;
+	 i++)
+      {
+	if (*name != '\0' && strncmp (word, name, len) == 0)
+	  VEC_safe_push (char_ptr, result, xstrdup (name));
+      }
+
+  if (add_reggroups)
+    for (group = reggroup_next (gdbarch, NULL);
+	 group != NULL;
+	 group = reggroup_next (gdbarch, group))
+      {
+	name = reggroup_name (group);
+	if (strncmp (word, name, len) == 0)
+	  VEC_safe_push (char_ptr, result, xstrdup (name));
+      }
 
   return result;
 }
 
+VEC (char_ptr) *
+reg_or_group_completer (struct cmd_list_element *ignore,
+			const char *text, const char *word)
+{
+  /* Complete on both registers and reggroups.  */
+  return reg_or_group_completer_1 (ignore, text, word, 1, 1);
+}
+
+VEC (char_ptr) *
+reggroup_completer (struct cmd_list_element *ignore,
+		    const char *text, const char *word)
+{
+  /* Complete on reggroups only.  */
+  return reg_or_group_completer_1 (ignore, text, word, 0, 1);
+}
 
 /* Get the list of chars that are considered as word breaks
    for the current command.  */
diff --git a/gdb/completer.h b/gdb/completer.h
index 56e1a2b..6c1f257 100644
--- a/gdb/completer.h
+++ b/gdb/completer.h
@@ -96,6 +96,9 @@ extern VEC (char_ptr) *signal_completer (struct cmd_list_element *,
 extern VEC (char_ptr) *reg_or_group_completer (struct cmd_list_element *,
 					       const char *, const char *);
 
+extern VEC (char_ptr) *reggroup_completer (struct cmd_list_element *,
+					   const char *, const char *);
+
 extern char *get_gdb_completer_quote_characters (void);
 
 extern char *gdb_completion_word_break_characters (void);
diff --git a/gdb/tui/tui-regs.c b/gdb/tui/tui-regs.c
index 8dbcda1..685a896 100644
--- a/gdb/tui/tui-regs.c
+++ b/gdb/tui/tui-regs.c
@@ -39,6 +39,7 @@
 #include "tui/tui-io.h"
 #include "reggroups.h"
 #include "valprint.h"
+#include "completer.h"
 
 #include "gdb_curses.h"
 
@@ -557,10 +558,8 @@ tui_display_register (struct tui_data_element *data,
 }
 
 static void
-tui_reg_next_command (char *arg, int from_tty)
+tui_reg_next (struct gdbarch *gdbarch)
 {
-  struct gdbarch *gdbarch = get_current_arch ();
-
   if (TUI_DATA_WIN != NULL)
     {
       struct reggroup *group
@@ -576,10 +575,8 @@ tui_reg_next_command (char *arg, int from_tty)
 }
 
 static void
-tui_reg_prev_command (char *arg, int from_tty)
+tui_reg_prev (struct gdbarch *gdbarch)
 {
-  struct gdbarch *gdbarch = get_current_arch ();
-
   if (TUI_DATA_WIN != NULL)
     {
       struct reggroup *group
@@ -606,31 +603,84 @@ tui_reg_prev_command (char *arg, int from_tty)
 }
 
 static void
-tui_reg_float_command (char *arg, int from_tty)
+tui_reg_command (char *args, int from_tty)
 {
-  tui_show_registers (float_reggroup);
-}
+  struct gdbarch *gdbarch = get_current_arch ();
 
-static void
-tui_reg_general_command (char *arg, int from_tty)
-{
-  tui_show_registers (general_reggroup);
-}
+  if (args)
+    {
+      if (strcmp (args, "next") == 0)
+	tui_reg_next (gdbarch);
+      else if (strcmp (args, "prev") == 0)
+	tui_reg_prev (gdbarch);
+      else
+	{
+	  struct reggroup *group = NULL, *match = NULL;
+	  size_t len = strlen (args);
 
-static void
-tui_reg_system_command (char *arg, int from_tty)
-{
-  tui_show_registers (system_reggroup);
+	  for (group = reggroup_next (gdbarch, group);
+	       group != NULL;
+	       group = reggroup_next (gdbarch, group))
+	    {
+	      if (strncmp (reggroup_name (group), args, len) == 0)
+		{
+		  if (match != NULL)
+		    {
+		      match = NULL;
+		      break;
+		    }
+		  match = group;
+		}
+	    }
+
+	  if (match != NULL)
+	    tui_show_registers (match);
+	  else
+	    error (_("unknown register group '%s'"), args);
+	}
+    }
+  else
+    {
+      struct reggroup *group = NULL;
+
+      printf_unfiltered (_("\"tui reg\" must be followed by the name of "
+			   "either a register group,\nor one of 'next' "
+			   "or 'prev'.  Known register groups are:\n"));
+      for (group = reggroup_next (gdbarch, group); group != NULL; )
+	{
+	  printf_unfiltered ("%s", reggroup_name (group));
+	  group = reggroup_next (gdbarch, group);
+	  if (group != NULL)
+	    printf_unfiltered (", ");
+	}
+      printf_unfiltered ("\n");
+    }
 }
 
-static struct cmd_list_element *tuireglist;
+/* Complete names of register groups, and add the special "prev" and "next"
+   names.  */
 
-static void
-tui_reg_command (char *args, int from_tty)
+static VEC (char_ptr) *
+tui_reggroup_completer (struct cmd_list_element *ignore,
+			const char *text, const char *word)
 {
-  printf_unfiltered (_("\"tui reg\" must be followed by the name of a "
-                     "tui reg command.\n"));
-  help_list (tuireglist, "tui reg ", all_commands, gdb_stdout);
+  VEC (char_ptr) *result = NULL;
+  static const char *extra[] = { "next", "prev", NULL };
+  size_t len = strlen (word);
+  const char **tmp;
+
+  if (!target_has_registers)
+    return result;
+
+  result = reggroup_completer (ignore, text, word);
+
+  for (tmp = extra; *tmp; ++tmp)
+    {
+      if (strncmp (word, *tmp, len) == 0)
+	VEC_safe_push (char_ptr, result, xstrdup (*tmp));
+    }
+
+  return result;
 }
 
 /* Provide a prototype to silence -Wmissing-prototypes.  */
@@ -639,30 +689,13 @@ extern initialize_file_ftype _initialize_tui_regs;
 void
 _initialize_tui_regs (void)
 {
-  struct cmd_list_element **tuicmd;
+  struct cmd_list_element **tuicmd, *cmd;
 
   tuicmd = tui_get_cmd_list ();
 
-  add_prefix_cmd ("reg", class_tui, tui_reg_command,
-                  _("TUI commands to control the register window."),
-                  &tuireglist, "tui reg ", 0,
-                  tuicmd);
-
-  add_cmd ("float", class_tui, tui_reg_float_command,
-           _("Display only floating point registers."),
-           &tuireglist);
-  add_cmd ("general", class_tui, tui_reg_general_command,
-           _("Display only general registers."),
-           &tuireglist);
-  add_cmd ("system", class_tui, tui_reg_system_command,
-           _("Display only system registers."),
-           &tuireglist);
-  add_cmd ("next", class_tui, tui_reg_next_command,
-           _("Display next register group."),
-           &tuireglist);
-  add_cmd ("prev", class_tui, tui_reg_prev_command,
-           _("Display previous register group."),
-           &tuireglist);
+  cmd = add_cmd ("reg", class_tui, tui_reg_command, _("\
+TUI command to control the register window."), tuicmd);
+  set_cmd_completer (cmd, tui_reggroup_completer);
 }
 
 
