Use wclrtoeol instead of werase
[tig] / tig.c
diff --git a/tig.c b/tig.c
index ef3fe0d..1f92114 100644 (file)
--- a/tig.c
+++ b/tig.c
@@ -451,6 +451,9 @@ parse_options(int argc, char *argv[])
        for (i = 1; i < argc; i++) {
                char *opt = argv[i];
 
+               if (opt[0] && opt[0] != '-')
+                       break;
+
                if (!strcmp(opt, "-l")) {
                        opt_request = REQ_VIEW_LOG;
                        continue;
@@ -494,9 +497,6 @@ parse_options(int argc, char *argv[])
                        break;
                }
 
-               if (opt[0] && opt[0] != '-')
-                       break;
-
                die("unknown option '%s'\n\n%s", opt, usage);
        }
 
@@ -767,9 +767,10 @@ static struct keybinding *keybindings[ARRAY_SIZE(keymap_table)];
 static void
 add_keybinding(enum keymap keymap, enum request request, int key)
 {
-       struct keybinding *keybinding;
+       struct keybinding *keybinding = keybindings[keymap];
 
-       keybinding = calloc(1, sizeof(*keybinding));
+       if (!keybinding)
+               keybinding = calloc(1, sizeof(*keybinding));
        if (!keybinding)
                die("Failed to allocate keybinding");
 
@@ -1164,6 +1165,9 @@ struct view_ops;
 static struct view *display[2];
 static unsigned int current_view;
 
+/* Reading from the prompt? */
+static bool input_mode = FALSE;
+
 #define foreach_displayed_view(view, i) \
        for (i = 0; i < ARRAY_SIZE(display) && (view = display[i]); i++)
 
@@ -1301,7 +1305,10 @@ redraw_view_from(struct view *view, int lineno)
        }
 
        redrawwin(view->win);
-       wrefresh(view->win);
+       if (input_mode)
+               wnoutrefresh(view->win);
+       else
+               wrefresh(view->win);
 }
 
 static void
@@ -1316,33 +1323,44 @@ static void
 update_view_title(struct view *view)
 {
        char buf[SIZEOF_STR];
-       size_t bufpos = 0;
+       char state[SIZEOF_STR];
+       size_t bufpos = 0, statelen = 0;
 
        assert(view_is_displayed(view));
 
-       string_format_from(buf, &bufpos, "[%s]", view->name);
-       if (*view->ref)
-               string_format_from(buf, &bufpos, " %s", view->ref);
-
        if (view->lines || view->pipe) {
                unsigned int view_lines = view->offset + view->height;
                unsigned int lines = view->lines
                                   ? MIN(view_lines, view->lines) * 100 / view->lines
                                   : 0;
 
-               string_format_from(buf, &bufpos, " - %s %d of %d (%d%%)",
+               string_format_from(state, &statelen, "- %s %d of %d (%d%%)",
                                   view->ops->type,
                                   view->lineno + 1,
                                   view->lines,
                                   lines);
+
+               if (view->pipe) {
+                       time_t secs = time(NULL) - view->start_time;
+
+                       /* Three git seconds are a long time ... */
+                       if (secs > 2)
+                               string_format_from(state, &statelen, " %lds", secs);
+               }
        }
 
-       if (view->pipe) {
-               time_t secs = time(NULL) - view->start_time;
+       string_format_from(buf, &bufpos, "[%s]", view->name);
+       if (*view->ref && bufpos < view->width) {
+               size_t refsize = strlen(view->ref);
+               size_t minsize = bufpos + 1 + /* abbrev= */ 7 + 1 + statelen;
 
-               /* Three git seconds are a long time ... */
-               if (secs > 2)
-                       string_format_from(buf, &bufpos, " %lds", secs);
+               if (minsize < view->width)
+                       refsize = view->width - minsize + 7;
+               string_format_from(buf, &bufpos, " %.*s", refsize, view->ref);
+       }
+
+       if (statelen && bufpos < view->width) {
+               string_format_from(buf, &bufpos, " %s", state);
        }
 
        if (view == display[current_view])
@@ -1350,10 +1368,14 @@ update_view_title(struct view *view)
        else
                wbkgdset(view->title, get_line_attr(LINE_TITLE_BLUR));
 
-       werase(view->title);
        mvwaddnstr(view->title, 0, 0, buf, bufpos);
+       wclrtoeol(view->title);
        wmove(view->title, 0, view->width - 1);
-       wrefresh(view->title);
+
+       if (input_mode)
+               wnoutrefresh(view->title);
+       else
+               wrefresh(view->title);
 }
 
 static void
@@ -3110,26 +3132,30 @@ static bool cursed = FALSE;
 /* The status window is used for polling keystrokes. */
 static WINDOW *status_win;
 
+static bool status_empty = TRUE;
+
 /* Update status and title window. */
 static void
 report(const char *msg, ...)
 {
-       static bool empty = TRUE;
        struct view *view = display[current_view];
 
-       if (!empty || *msg) {
+       if (input_mode)
+               return;
+
+       if (!status_empty || *msg) {
                va_list args;
 
                va_start(args, msg);
 
-               werase(status_win);
                wmove(status_win, 0, 0);
                if (*msg) {
                        vwprintw(status_win, msg, args);
-                       empty = FALSE;
+                       status_empty = FALSE;
                } else {
-                       empty = TRUE;
+                       status_empty = TRUE;
                }
+               wclrtoeol(status_win);
                wrefresh(status_win);
 
                va_end(args);
@@ -3199,10 +3225,16 @@ read_prompt(const char *prompt)
                struct view *view;
                int i, key;
 
+               input_mode = TRUE;
+
                foreach_view (view, i)
                        update_view(view);
 
-               report("%s%.*s", prompt, pos, buf);
+               input_mode = FALSE;
+
+               mvwprintw(status_win, 0, 0, "%s%.*s", prompt, pos, buf);
+               wclrtoeol(status_win);
+
                /* Refresh, accept single keystroke of input */
                key = wgetch(status_win);
                switch (key) {
@@ -3239,6 +3271,7 @@ read_prompt(const char *prompt)
 
        if (status == CANCEL) {
                /* Clear the status window */
+               status_empty = FALSE;
                report("");
                return NULL;
        }