Code

Make prompt use internal user input reader
authorJonas Fonseca <fonseca@diku.dk>
Sat, 10 Jun 2006 22:49:17 +0000 (00:49 +0200)
committerJonas Fonseca <fonseca@antimatter.localdomain>
Sat, 10 Jun 2006 22:50:41 +0000 (00:50 +0200)
This allows it to be used while loading. Also, it will make it possible to
support more advanced editing facilities like history, completion etc.
needed for future search support at least.

It's still very primitive ...

BUGS
tig.c

diff --git a/BUGS b/BUGS
index 8a42e8072330dd5fdd7b2da3eba3a7025ef974cf..79aace6fd064e9af8808fae7f332aa27e36ecd63 100644 (file)
--- a/BUGS
+++ b/BUGS
@@ -10,5 +10,3 @@ Known bugs and problems:
 
  - The cursor can wrap-around on the last line and cause the
    window to scroll.
-
- - The prompt doesn't work while loading.
diff --git a/tig.c b/tig.c
index cf65447cb5320508af6147b38e27c3f3bc6df127..cda8a71e9a7d15882b82eb672c788257dfb00f09 100644 (file)
--- a/tig.c
+++ b/tig.c
@@ -2592,6 +2592,68 @@ init_display(void)
        wbkgdset(status_win, get_line_attr(LINE_STATUS));
 }
 
+static int
+read_prompt(void)
+{
+       enum { READING, STOP, CANCEL } status = READING;
+       char buf[sizeof(opt_cmd) - STRING_SIZE("git \0")];
+       int pos = 0;
+
+       while (status == READING) {
+               struct view *view;
+               int i, key;
+
+               foreach_view (view, i)
+                       update_view(view);
+
+               report(":%.*s", pos, buf);
+               /* Refresh, accept single keystroke of input */
+               key = wgetch(status_win);
+               switch (key) {
+               case KEY_RETURN:
+               case KEY_ENTER:
+               case '\n':
+                       status = pos ? STOP : CANCEL;
+                       break;
+
+               case KEY_BACKSPACE:
+                       if (pos > 0)
+                               pos--;
+                       else
+                               status = CANCEL;
+                       break;
+
+               case KEY_ESC:
+                       status = CANCEL;
+                       break;
+
+               case ERR:
+                       break;
+
+               default:
+                       if (pos >= sizeof(buf)) {
+                               report("Input string too long");
+                               return ERR;
+                       }
+
+                       if (isprint(key))
+                               buf[pos++] = (char) key;
+               }
+       }
+
+       if (status == CANCEL) {
+               /* Clear the status window */
+               report("");
+               return ERR;
+       }
+
+       buf[pos++] = 0;
+       if (!string_format(opt_cmd, "git %s", buf))
+               return ERR;
+       opt_request = REQ_VIEW_PAGER;
+
+       return OK;
+}
 
 /*
  * Repository references
@@ -2841,23 +2903,8 @@ main(int argc, char *argv[])
                 * status_win restricted. */
                switch (request) {
                case REQ_PROMPT:
-                       report(":");
-                       /* Temporarily switch to line-oriented and echoed
-                        * input. */
-                       nocbreak();
-                       echo();
-
-                       if (wgetnstr(status_win, opt_cmd + 4, sizeof(opt_cmd) - 4) == OK) {
-                               memcpy(opt_cmd, "git ", 4);
-                               opt_request = REQ_VIEW_PAGER;
-                       } else {
-                               report("Prompt interrupted by loading view, "
-                                      "press 'z' to stop loading views");
+                       if (read_prompt() == ERR)
                                request = REQ_SCREEN_UPDATE;
-                       }
-
-                       noecho();
-                       cbreak();
                        break;
 
                case REQ_SCREEN_RESIZE: