Code

BUGS: document problem with scrolling in (u)xterm
[tig.git] / tig.c
diff --git a/tig.c b/tig.c
index c569afc52fcfdebc1ffb7a2dbf8e54b9025957c7..b4e4b596078919afdb620efb922590ab9f0e3620 100644 (file)
--- a/tig.c
+++ b/tig.c
@@ -1714,9 +1714,6 @@ 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++)
 
@@ -2007,6 +2004,32 @@ draw_date(struct view *view, struct tm *time)
        return draw_field(view, LINE_DATE, date, DATE_COLS, FALSE);
 }
 
+static bool
+draw_author(struct view *view, const char *author)
+{
+       bool trim = opt_author_cols == 0 || opt_author_cols > 5 || !author;
+
+       if (!trim) {
+               static char initials[10];
+               size_t pos;
+
+#define is_initial_sep(c) (isspace(c) || ispunct(c) || (c) == '@')
+
+               memset(initials, 0, sizeof(initials));
+               for (pos = 0; *author && pos < opt_author_cols - 1; author++, pos++) {
+                       while (is_initial_sep(*author))
+                               author++;
+                       strncpy(&initials[pos], author, sizeof(initials) - 1 - pos);
+                       while (*author && !is_initial_sep(author[1]))
+                               author++;
+               }
+
+               author = initials;
+       }
+
+       return draw_field(view, LINE_MAIN_AUTHOR, author, opt_author_cols, trim);
+}
+
 static bool
 draw_view_line(struct view *view, unsigned int lineno)
 {
@@ -2056,10 +2079,7 @@ redraw_view_dirty(struct view *view)
 
        if (!dirty)
                return;
-       if (input_mode)
-               wnoutrefresh(view->win);
-       else
-               wrefresh(view->win);
+       wnoutrefresh(view->win);
 }
 
 static void
@@ -2072,10 +2092,7 @@ redraw_view_from(struct view *view, int lineno)
                        break;
        }
 
-       if (input_mode)
-               wnoutrefresh(view->win);
-       else
-               wrefresh(view->win);
+       wnoutrefresh(view->win);
 }
 
 static void
@@ -2086,19 +2103,6 @@ redraw_view(struct view *view)
 }
 
 
-static void
-update_display_cursor(struct view *view)
-{
-       /* Move the cursor to the right-most column of the cursor line.
-        *
-        * XXX: This could turn out to be a bit expensive, but it ensures that
-        * the cursor does not jump around. */
-       if (view->lines) {
-               wmove(view->win, view->lineno - view->offset, view->width - 1);
-               wrefresh(view->win);
-       }
-}
-
 static void
 update_view_title(struct view *view)
 {
@@ -2151,12 +2155,7 @@ update_view_title(struct view *view)
 
        mvwaddnstr(view->title, 0, 0, buf, bufpos);
        wclrtoeol(view->title);
-       wmove(view->title, 0, view->width - 1);
-
-       if (input_mode)
-               wnoutrefresh(view->title);
-       else
-               wrefresh(view->title);
+       wnoutrefresh(view->title);
 }
 
 static void
@@ -2222,9 +2221,6 @@ redraw_display(bool clear)
                redraw_view(view);
                update_view_title(view);
        }
-
-       if (display[current_view])
-               update_display_cursor(display[current_view]);
 }
 
 static void
@@ -2279,12 +2275,7 @@ do_scroll_view(struct view *view, int lines)
 
                if (redraw_current_line)
                        draw_view_line(view, view->lineno - view->offset);
-               /* FIXME: Stupid hack to workaround bug where the message from
-                * scrolling up one line when impossible followed by scrolling
-                * down one line is not removed by the next action. */
-               if (lines > 0)
-                       report("");
-               wrefresh(view->win);
+               wnoutrefresh(view->win);
        }
 
        report("");
@@ -2419,7 +2410,7 @@ move_view(struct view *view, enum request request)
        /* Draw the current line */
        draw_view_line(view, view->lineno - view->offset);
 
-       wrefresh(view->win);
+       wnoutrefresh(view->win);
        report("");
 }
 
@@ -2446,7 +2437,7 @@ select_view_line(struct view *view, unsigned long lineno)
                if (view_is_displayed(view)) {
                        draw_view_line(view, old_lineno);
                        draw_view_line(view, view->lineno - view->offset);
-                       wrefresh(view->win);
+                       wnoutrefresh(view->win);
                } else {
                        view->ops->select(view, &view->line[view->lineno]);
                }
@@ -2778,7 +2769,7 @@ update_view(struct view *view)
                if (view->lines == 0) {
                        time_t secs = time(NULL) - view->start_time;
 
-                       if (secs > view->update_secs) {
+                       if (secs > 1 && secs > view->update_secs) {
                                if (view->update_secs == 0)
                                        redraw_view(view);
                                update_view_title(view);
@@ -2848,7 +2839,6 @@ update_view(struct view *view)
        /* Update the title _after_ the redraw so that if the redraw picks up a
         * commit reference in view->ref it'll be available here. */
        update_view_title(view);
-       update_display_cursor(view);
        return TRUE;
 }
 
@@ -3953,8 +3943,7 @@ tree_draw(struct view *view, struct line *line, unsigned int lineno)
                if (draw_field(view, LINE_TREE_MODE, mode, 11, TRUE))
                        return TRUE;
 
-               if (opt_author &&
-                   draw_field(view, LINE_MAIN_AUTHOR, entry->author, opt_author_cols, TRUE))
+               if (opt_author && draw_author(view, entry->author))
                        return TRUE;
 
                if (opt_date && draw_date(view, *entry->author ? &entry->time : NULL))
@@ -4373,8 +4362,7 @@ blame_draw(struct view *view, struct line *line, unsigned int lineno)
        if (opt_date && draw_date(view, time))
                return TRUE;
 
-       if (opt_author &&
-           draw_field(view, LINE_MAIN_AUTHOR, author, opt_author_cols, TRUE))
+       if (opt_author && draw_author(view, author))
                return TRUE;
 
        if (draw_field(view, LINE_BLAME_ID, id, ID_COLS, FALSE))
@@ -5714,8 +5702,7 @@ main_draw(struct view *view, struct line *line, unsigned int lineno)
        if (opt_date && draw_date(view, &commit->time))
                return TRUE;
 
-       if (opt_author &&
-           draw_field(view, LINE_MAIN_AUTHOR, commit->author, opt_author_cols, TRUE))
+       if (opt_author && draw_author(view, commit->author))
                return TRUE;
 
        if (opt_rev_graph && commit->graph_size &&
@@ -6116,6 +6103,9 @@ static bool cursed = FALSE;
 /* The status window is used for polling keystrokes. */
 static WINDOW *status_win;
 
+/* Reading from the prompt? */
+static bool input_mode = FALSE;
+
 static bool status_empty = FALSE;
 
 /* Update status and title window. */
@@ -6155,13 +6145,12 @@ report(const char *msg, ...)
                        status_empty = TRUE;
                }
                wclrtoeol(status_win);
-               wrefresh(status_win);
+               wnoutrefresh(status_win);
 
                va_end(args);
        }
 
        update_view_title(view);
-       update_display_cursor(view);
 }
 
 /* Controls when nodelay should be in effect when polling user input. */
@@ -6198,7 +6187,7 @@ init_display(void)
        nonl();         /* Tell curses not to do NL->CR/NL on output */
        cbreak();       /* Take input chars one at a time, no wait for \n */
        noecho();       /* Don't echo input */
-       leaveok(stdscr, TRUE);
+       leaveok(stdscr, FALSE);
 
        if (has_colors())
                init_colors();
@@ -6219,36 +6208,46 @@ init_display(void)
 }
 
 static int
-get_input(bool prompting)
+get_input(int prompt_position)
 {
        struct view *view;
-       int i, key;
+       int i, key, cursor_y, cursor_x;
 
-       if (prompting)
+       if (prompt_position)
                input_mode = TRUE;
 
-       while (true) {
+       while (TRUE) {
                foreach_view (view, i)
                        update_view(view);
 
+               /* Update the cursor position. */
+               if (prompt_position) {
+                       getbegyx(status_win, cursor_y, cursor_x);
+                       cursor_x = prompt_position;
+               } else {
+                       view = display[current_view];
+                       getbegyx(view->win, cursor_y, cursor_x);
+                       cursor_x = view->width - 1;
+                       cursor_y += view->lineno - view->offset;
+               }
+               setsyx(cursor_y, cursor_x);
+
                /* Refresh, accept single keystroke of input */
+               doupdate();
                key = wgetch(status_win);
 
                /* wgetch() with nodelay() enabled returns ERR when
                 * there's no input. */
                if (key == ERR) {
-                       doupdate();
 
                } else if (key == KEY_RESIZE) {
                        int height, width;
 
                        getmaxyx(stdscr, height, width);
 
-                       /* Resize the status view first so the cursor is
-                        * placed properly. */
                        wresize(status_win, 1, width);
                        mvwin(status_win, height - 1, 0);
-                       wrefresh(status_win);
+                       wnoutrefresh(status_win);
                        resize_display();
                        redraw_display(TRUE);
 
@@ -6274,7 +6273,7 @@ prompt_input(const char *prompt, input_handler handler, void *data)
                mvwprintw(status_win, 0, 0, "%s%.*s", prompt, pos, buf);
                wclrtoeol(status_win);
 
-               key = get_input(TRUE);
+               key = get_input(pos + 1);
                switch (key) {
                case KEY_RETURN:
                case KEY_ENTER:
@@ -6771,7 +6770,7 @@ main(int argc, const char *argv[])
        }
 
        while (view_driver(display[current_view], request)) {
-               int key = get_input(FALSE);
+               int key = get_input(0);
 
                view = display[current_view];
                request = get_keybinding(view->keymap, key);