Add -Werror to the cc debug flags
[tig] / tig.c
diff --git a/tig.c b/tig.c
index a4aaa0e..da2af8f 100644 (file)
--- a/tig.c
+++ b/tig.c
@@ -68,7 +68,7 @@ static void set_nonblocking_input(bool loading);
 /* This color name can be used to refer to the default term colors. */
 #define COLOR_DEFAULT  (-1)
 
-#define TIG_HELP       "(d)iff, (l)og, (m)ain, (q)uit, (h)elp, (Enter) show diff"
+#define TIG_HELP       "(d)iff, (l)og, (m)ain, (q)uit, (h)elp"
 
 /* The format and size of the date column in the main view. */
 #define DATE_FORMAT    "%Y-%m-%d %H:%M"
@@ -591,37 +591,51 @@ init_colors(void)
 #define TIG_PAGER_CMD \
        ""
 
+
 /**
  * The viewer
  * ----------
+ * The display consists of a status window on the last line of the screen and
+ * one or more views. The default is to only show one view at the time but it
+ * is possible to split both the main and log view to also show the commit
+ * diff.
  *
- * tig(1) presents various 'views' of a repository. Each view is based on output
- * from an external command, most often 'git log', 'git diff', or 'git show'.
+ * If you are in the log view and press 'Enter' when the current line is a
+ * commit line, such as:
  *
- * The main view::
- *     Is the default view, and it shows a one line summary of each commit
- *     in the chosen list of revisions. The summary includes commit date,
- *     author, and the first line of the log message. Additionally, any
- *     repository references, such as tags, will be shown.
+ *     commit 4d55caff4cc89335192f3e566004b4ceef572521
  *
- * The log view::
- *     Presents a more rich view of the revision log showing the whole log
- *     message and the diffstat.
- *
- * The diff view::
- *     Shows either the diff of the current working tree, that is, what
- *     has changed since the last commit, or the commit diff complete
- *     with log message, diffstat and diff.
- *
- * The pager view::
- *     Is used for displaying both input from stdin and output from git
- *     commands entered in the internal prompt.
+ * You will split the view so that the log view is displayed in the top window
+ * and the diff view in the bottom window. You can switch between the two
+ * views by pressing 'Tab'. To maximize the log view again, simply press 'l'.
+ **/
+
+struct view;
+
+/* The display array of active views and the index of the current view. */
+static struct view *display[2];
+static unsigned int current_view;
+
+#define foreach_view(view, i) \
+       for (i = 0; i < ARRAY_SIZE(display) && (view = display[i]); i++)
+
+
+/**
+ * Current head and commit ID
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * The viewer keeps track of both what head and commit ID you are currently
+ * viewing. The commit ID will follow the cursor line and change everytime time
+ * you highlight a different commit. Whenever you reopen the diff view it
+ * will be reloaded, if the commit ID changed.
  *
- * The help view::
- *     Displays the information from the tig(1) man page. For the help view
- *     to work you need to have the tig(1) man page installed.
+ * The head ID is used when opening the main and log view to indicate from
+ * what revision to show history.
  **/
 
+static char ref_commit[SIZEOF_REF]     = "HEAD";
+static char ref_head[SIZEOF_REF]       = "HEAD";
+
+
 struct view {
        const char *name;       /* View name */
        const char *cmd_fmt;    /* Default command line format */
@@ -666,32 +680,52 @@ struct view {
 static struct view_ops pager_ops;
 static struct view_ops main_ops;
 
-static char ref_head[SIZEOF_REF]       = "HEAD";
-static char ref_commit[SIZEOF_REF]     = "HEAD";
-
 #define VIEW_STR(name, cmd, env, ref, objsize, ops) \
        { name, cmd, #env, ref, objsize, ops }
 
 #define VIEW_(id, name, ops, ref, objsize) \
        VIEW_STR(name, TIG_##id##_CMD,  TIG_##id##_CMD, ref, objsize, ops)
 
+/**
+ * Views
+ * ~~~~~
+ * tig(1) presents various 'views' of a repository. Each view is based on output
+ * from an external command, most often 'git log', 'git diff', or 'git show'.
+ *
+ * The main view::
+ *     Is the default view, and it shows a one line summary of each commit
+ *     in the chosen list of revisions. The summary includes commit date,
+ *     author, and the first line of the log message. Additionally, any
+ *     repository references, such as tags, will be shown.
+ *
+ * The log view::
+ *     Presents a more rich view of the revision log showing the whole log
+ *     message and the diffstat.
+ *
+ * The diff view::
+ *     Shows either the diff of the current working tree, that is, what
+ *     has changed since the last commit, or the commit diff complete
+ *     with log message, diffstat and diff.
+ *
+ * The pager view::
+ *     Is used for displaying both input from stdin and output from git
+ *     commands entered in the internal prompt.
+ *
+ * The help view::
+ *     Displays the information from the tig(1) man page. For the help view
+ *     to work you need to have the tig(1) man page installed.
+ **/
+
 static struct view views[] = {
        VIEW_(MAIN,  "main",  &main_ops,  ref_head,   sizeof(struct commit)),
        VIEW_(DIFF,  "diff",  &pager_ops, ref_commit, sizeof(char)),
        VIEW_(LOG,   "log",   &pager_ops, ref_head,   sizeof(char)),
-       VIEW_(HELP,  "help",  &pager_ops, ref_head,   sizeof(char)),
+       VIEW_(HELP,  "help",  &pager_ops, "static",   sizeof(char)),
        VIEW_(PAGER, "pager", &pager_ops, "static",   sizeof(char)),
 };
 
 #define VIEW(req) (&views[(req) - REQ_OFFSET - 1])
 
-/* The display array of active views and the index of the current view. */
-static struct view *display[2];
-static unsigned int current_view;
-
-#define foreach_view(view, i) \
-       for (i = 0; i < ARRAY_SIZE(display) && (view = display[i]); i++)
-
 
 static void
 redraw_view_from(struct view *view, int lineno)
@@ -714,6 +748,45 @@ redraw_view(struct view *view)
        redraw_view_from(view, 0);
 }
 
+
+/**
+ * Title windows
+ * ~~~~~~~~~~~~~
+ * Each view has a title window which shows the name of the view, current
+ * commit ID if available, and where the view is positioned:
+ *
+ *     [main] c622eefaa485995320bc743431bae0d497b1d875 - commit 1 of 61 (1%)
+ *
+ * By default, the title of the current view is highlighted using bold font.
+ **/
+
+static void
+update_view_title(struct view *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);
+
+       if (*view->ref)
+               wprintw(view->title, "[%s] %s", view->name, view->ref);
+       else
+               wprintw(view->title, "[%s]", view->name);
+
+       if (view->lines) {
+               wprintw(view->title, " - %s %d of %d (%d%%)",
+                       view->ops->type,
+                       view->lineno + 1,
+                       view->lines,
+                       (view->lineno + 1) * 100 / view->lines);
+       }
+
+       wrefresh(view->title);
+}
+
 static void
 resize_display(void)
 {
@@ -744,9 +817,9 @@ resize_display(void)
        offset = 0;
 
        foreach_view (view, i) {
-               /* Keep the size of the all view windows one lager than is
-                * required. This makes current line management easier when the
-                * cursor will go outside the window. */
+               /* Keep the height of all view->win windows one larger than is
+                * required so that the cursor can wrap-around on the last line
+                * without scrolling the window. */
                if (!view->win) {
                        view->win = newwin(view->height + 1, 0, offset, 0);
                        if (!view->win)
@@ -770,34 +843,18 @@ resize_display(void)
 }
 
 static void
-update_view_title(struct view *view)
+redraw_display(void)
 {
-       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);
-
-       /* [main] ref: 334b506... - commit 6 of 4383 (0%) */
-
-       if (*view->ref)
-               wprintw(view->title, "[%s] %s", view->name, view->ref);
-       else
-               wprintw(view->title, "[%s]", view->name);
+       struct view *view;
+       int i;
 
-       if (view->lines) {
-               wprintw(view->title, " - %s %d of %d (%d%%)",
-                       view->ops->type,
-                       view->lineno + 1,
-                       view->lines,
-                       (view->lineno + 1) * 100 / view->lines);
+       foreach_view (view, i) {
+               redraw_view(view);
+               update_view_title(view);
        }
-
-       wrefresh(view->title);
 }
 
+
 /*
  * Navigation
  */
@@ -1310,8 +1367,7 @@ view_driver(struct view *view, enum request request)
        }
        case REQ_TOGGLE_LINE_NUMBERS:
                opt_line_number = !opt_line_number;
-               redraw_view(view);
-               update_view_title(view);
+               redraw_display();
                break;
 
        case REQ_PROMPT:
@@ -1335,10 +1391,7 @@ view_driver(struct view *view, enum request request)
                resize_display();
                /* Fall-through */
        case REQ_SCREEN_REDRAW:
-               foreach_view (view, i) {
-                       redraw_view(view);
-                       update_view_title(view);
-               }
+               redraw_display();
                break;
 
        case REQ_SCREEN_UPDATE:
@@ -1468,6 +1521,11 @@ pager_enter(struct view *view)
 {
        char *line = view->line[view->lineno];
 
+       if (view == VIEW(REQ_VIEW_DIFF)) {
+               scroll_view(view, REQ_SCROLL_LINE_DOWN);
+               return TRUE;
+       }
+
        if (get_line_type(line) == LINE_COMMIT) {
                if (view == VIEW(REQ_VIEW_LOG))
                        open_view(view, REQ_VIEW_DIFF, OPEN_SPLIT | OPEN_BACKGROUNDED);
@@ -1707,10 +1765,11 @@ static struct keymap keymap[] = {
         *      Switch to pager view.
         * h::
         *      Show man page.
-        * Return::
-        *      If on a commit line show the commit diff. Additionally, if in
-        *      main or log view this will split the view. To open the commit
-        *      diff in full size view either use 'd' or press Return twice.
+        * Enter::
+        *      This key is "context sensitive" depending on what view you are
+        *      currently in. When in log view on a commit line or in the main
+        *      view, split the view and show the commit diff. In the diff view
+        *      pressing Enter will simply scroll the view one line down.
         * Tab::
         *      Switch to next view.
         **/
@@ -1737,8 +1796,10 @@ static struct keymap keymap[] = {
         * j::
         *      Move cursor one line down and enter.
         * PgUp::
+        * b::
         *      Move cursor one page up.
         * PgDown::
+        * Space::
         *      Move cursor one page down.
         * Home::
         *      Jump to first line.
@@ -1752,7 +1813,9 @@ static struct keymap keymap[] = {
        { KEY_HOME,     REQ_MOVE_FIRST_LINE },
        { KEY_END,      REQ_MOVE_LAST_LINE },
        { KEY_NPAGE,    REQ_MOVE_PAGE_DOWN },
+       { ' ',          REQ_MOVE_PAGE_DOWN },
        { KEY_PPAGE,    REQ_MOVE_PAGE_UP },
+       { 'b',          REQ_MOVE_PAGE_UP },
 
        /**
         * Scrolling