summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog29
-rw-r--r--src/completions.c70
-rw-r--r--src/completions.h4
-rw-r--r--src/editor.c24
-rw-r--r--src/globals.h4
5 files changed, 104 insertions, 27 deletions
diff --git a/ChangeLog b/ChangeLog
index 85a015c..3b90e5b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,32 @@
+2003-05-28 Shawn Betts <sabetts@sfu.ca>
+
+ * src/globals.h (COMPLETION_NEXT): new define
+ (COMPLETION_PREVIOUS): likewise
+
+ * src/editor.c (editor_complete): remove prototype
+ (editor_complete_prev): new prototype
+ (editor_complete_next): likewise
+ (editor_insert): make it a static function. update prototype
+ (edit_bindings): add editor_complete_prev. replace editor_complete
+ with editor_complete_next.
+ (editor_complete): call completions_complete
+ (editor_complete_next): new function
+ (editor_complete_prev): likewise
+
+ * src/completions.h (completions_next_completion): remove prototype
+ (completions_update): likewise
+ (completions_assign): likewise
+ (completions_complete): new prototype
+
+ * src/completions.c (completions_assign): make it a static
+ function
+ (completions_update): likewise
+ (completions_prev_match): new function
+ (completions_next_match): likewise
+ (completions_complete): renamed from
+ completions_next_completion. call completions_next_match and
+ completions_prev_match.
+
2003-05-27 Shawn Betts <sabetts@sfu.ca>
* src/completions.c (completions_next_completion): check
diff --git a/src/completions.c b/src/completions.c
index 6f2ed12..314bd23 100644
--- a/src/completions.c
+++ b/src/completions.c
@@ -37,7 +37,7 @@ completions_free (rp_completions *c)
free (c->partial);
}
-void
+static void
completions_assign (rp_completions *c, struct list_head *new_list)
{
struct sbuf *cur;
@@ -58,7 +58,7 @@ completions_assign (rp_completions *c, struct list_head *new_list)
list_first (c->last_match, &c->completion_list, node);
}
-void
+static void
completions_update (rp_completions *c, char *partial)
{
struct list_head *new_list;
@@ -76,30 +76,33 @@ completions_update (rp_completions *c, char *partial)
free (new_list);
}
-/* Return a completed string that starts with partial. */
-char *
-completions_next_completion (rp_completions *c, char *partial)
+static char *
+completions_prev_match (rp_completions *c)
{
struct sbuf *cur;
- if (c->virgin)
+ /* search forward from our last match through the list looking for
+ another match. */
+ for (cur = list_prev_entry (c->last_match, &c->completion_list, node);
+ cur != c->last_match;
+ cur = list_prev_entry (cur, &c->completion_list, node))
{
- completions_update (c, partial);
-
- /* Since it's never been completed on and c->last_match points
- to the first element of the list which may be a match. So
- check it. FIXME: This is a bit of a hack. */
- if (c->last_match == NULL)
- return NULL;
-
- if (str_comp (sbuf_get (c->last_match), c->partial, strlen (c->partial)))
- return sbuf_get (c->last_match);
+ if (str_comp (sbuf_get (cur), c->partial, strlen (c->partial)))
+ {
+ /* We found a match so update our last_match pointer and
+ return the string. */
+ c->last_match = cur;
+ return sbuf_get (cur);
+ }
}
- if (c->last_match == NULL)
- return NULL;
+ return NULL;
+}
- /* */
+static char *
+completions_next_match (rp_completions *c)
+{
+ struct sbuf *cur;
/* search forward from our last match through the list looking for
another match. */
@@ -118,3 +121,32 @@ completions_next_completion (rp_completions *c, char *partial)
return NULL;
}
+
+/* Return a completed string that starts with partial. */
+char *
+completions_complete (rp_completions *c, char *partial, int direction)
+{
+ if (c->virgin)
+ {
+ completions_update (c, partial);
+
+ /* Since it's never been completed on and c->last_match points
+ to the first element of the list which may be a match. So
+ check it. FIXME: This is a bit of a hack. */
+ if (c->last_match == NULL)
+ return NULL;
+
+ if (str_comp (sbuf_get (c->last_match), c->partial, strlen (c->partial)))
+ return sbuf_get (c->last_match);
+ }
+
+ if (c->last_match == NULL)
+ return NULL;
+
+ /* Depending on the direction, find our "next" match. */
+ if (direction == COMPLETION_NEXT)
+ return completions_next_match (c);
+
+ /* Otherwise get the previous match */
+ return completions_prev_match (c);
+}
diff --git a/src/completions.h b/src/completions.h
index a0a262c..807bc97 100644
--- a/src/completions.h
+++ b/src/completions.h
@@ -4,9 +4,7 @@
#ifndef _RATPOISON_COMPLETIONS_H
#define _RATPOISON_COMPLETIONS_H 1
-char *completions_next_completion (rp_completions *c, char *partial);
-void completions_update (rp_completions *c, char *partial);
-void completions_assign (rp_completions *c, struct list_head *new_list);
+char *completions_complete (rp_completions *c, char *partial, int direction);
rp_completions *completions_new (completion_fn list_fn);
void completions_free (rp_completions *c);
diff --git a/src/editor.c b/src/editor.c
index eb3e443..a16b497 100644
--- a/src/editor.c
+++ b/src/editor.c
@@ -28,11 +28,12 @@ static edit_status editor_no_action (rp_input_line *line);
static edit_status editor_enter (rp_input_line *line);
static edit_status editor_history_previous (rp_input_line *line);
static edit_status editor_history_next (rp_input_line *line);
-static edit_status editor_complete (rp_input_line *line);
static edit_status editor_backward_kill_line (rp_input_line *line);
+static edit_status editor_complete_prev (rp_input_line *line);
+static edit_status editor_complete_next (rp_input_line *line);
/* default edit action */
-edit_status editor_insert (rp_input_line *line, char *keysym_buf);
+static edit_status editor_insert (rp_input_line *line, char *keysym_buf);
static char *saved_command = NULL;
@@ -73,7 +74,8 @@ static edit_binding edit_bindings[] =
{{XK_Down, 0}, editor_history_next},
{{XK_Return, 0}, editor_enter},
{{XK_KP_Enter, 0}, editor_enter},
- {{XK_Tab, 0}, editor_complete},
+ {{XK_Tab, 0}, editor_complete_next},
+ {{XK_ISO_Left_Tab, 0}, editor_complete_prev},
{ {0, 0}, 0} };
rp_input_line *
@@ -549,7 +551,7 @@ editor_paste_selection (rp_input_line *line)
}
static edit_status
-editor_complete (rp_input_line *line)
+editor_complete (rp_input_line *line, int direction)
{
char *tmp;
char *s;
@@ -562,7 +564,7 @@ editor_complete (rp_input_line *line)
/* We don't need to free s because it's a string from the completion
list. */
- s = completions_next_completion (line->compl, tmp);
+ s = completions_complete (line->compl, tmp, direction);
free (tmp);
if (s == NULL)
@@ -574,3 +576,15 @@ editor_complete (rp_input_line *line)
return EDIT_COMPLETE;
}
+
+static edit_status
+editor_complete_next (rp_input_line *line)
+{
+ return editor_complete (line, COMPLETION_NEXT);
+}
+
+static edit_status
+editor_complete_prev (rp_input_line *line)
+{
+ return editor_complete (line, COMPLETION_PREVIOUS);
+}
diff --git a/src/globals.h b/src/globals.h
index 57b6df3..cca5f27 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -41,6 +41,10 @@
#define WIN_NAME_RES_CLASS 1
#define WIN_NAME_RES_NAME 2
+/* Possible directions to traverse the completions list. */
+#define COMPLETION_NEXT 0
+#define COMPLETION_PREVIOUS 1
+
/* The list of groups. */
extern struct list_head rp_groups;