parse_option: check for '-' first and break if it is not an option
[tig] / tig.c
diff --git a/tig.c b/tig.c
index b0ce18f..18b4488 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
@@ -1315,20 +1322,11 @@ redraw_view(struct view *view)
 static void
 update_view_title(struct view *view)
 {
-       assert(view_is_displayed(view));
-
-       if (view == display[current_view])
-               wbkgdset(view->title, get_line_attr(LINE_TITLE_FOCUS));
-       else
-               wbkgdset(view->title, get_line_attr(LINE_TITLE_BLUR));
-
-       werase(view->title);
-       wmove(view->title, 0, 0);
+       char buf[SIZEOF_STR];
+       char state[SIZEOF_STR];
+       size_t bufpos = 0, statelen = 0;
 
-       if (*view->ref)
-               wprintw(view->title, "[%s] %s", view->name, view->ref);
-       else
-               wprintw(view->title, "[%s]", view->name);
+       assert(view_is_displayed(view));
 
        if (view->lines || view->pipe) {
                unsigned int view_lines = view->offset + view->height;
@@ -1336,23 +1334,48 @@ update_view_title(struct view *view)
                                   ? MIN(view_lines, view->lines) * 100 / view->lines
                                   : 0;
 
-               wprintw(view->title, " - %s %d of %d (%d%%)",
-                       view->ops->type,
-                       view->lineno + 1,
-                       view->lines,
-                       lines);
+               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)
-                       wprintw(view->title, " %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])
+               wbkgdset(view->title, get_line_attr(LINE_TITLE_FOCUS));
+       else
+               wbkgdset(view->title, get_line_attr(LINE_TITLE_BLUR));
+
+       werase(view->title);
+       mvwaddnstr(view->title, 0, 0, buf, bufpos);
        wmove(view->title, 0, view->width - 1);
-       wrefresh(view->title);
+
+       if (input_mode)
+               wnoutrefresh(view->title);
+       else
+               wrefresh(view->title);
 }
 
 static void
@@ -3116,6 +3139,9 @@ report(const char *msg, ...)
        static bool empty = TRUE;
        struct view *view = display[current_view];
 
+       if (input_mode)
+               return;
+
        if (!empty || *msg) {
                va_list args;
 
@@ -3198,10 +3224,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) {