Include autoconf file for 'make dist'
[tig] / tig.c
diff --git a/tig.c b/tig.c
index 82dbd23..24f84d4 100644 (file)
--- a/tig.c
+++ b/tig.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2006 Jonas Fonseca <fonseca@diku.dk>
+/* Copyright (c) 2006-2007 Jonas Fonseca <fonseca@diku.dk>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
  * GNU General Public License for more details.
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #ifndef TIG_VERSION
 #define TIG_VERSION "unknown-version"
 #endif
@@ -40,8 +44,6 @@
 
 #include <curses.h>
 
-#include "config.h"
-
 #if __GNUC__ >= 3
 #define __NORETURN __attribute__((__noreturn__))
 #else
@@ -78,6 +80,9 @@ static size_t utf8_length(const char *string, size_t max_width, int *coloffset,
 #define COLOR_DEFAULT  (-1)
 
 #define ICONV_NONE     ((iconv_t) -1)
+#ifndef ICONV_CONST
+#define ICONV_CONST    /* nothing */
+#endif
 
 /* The format and size of the date column in the main view. */
 #define DATE_FORMAT    "%Y-%m-%d %H:%M"
@@ -93,7 +98,7 @@ static size_t utf8_length(const char *string, size_t max_width, int *coloffset,
 #define        SCALE_SPLIT_VIEW(height)        ((height) * 2 / 3)
 
 #ifndef GIT_CONFIG
-#define "git config"
+#define GIT_CONFIG "git config"
 #endif
 
 #define TIG_LS_REMOTE \
@@ -346,7 +351,8 @@ sq_quote(char buf[SIZEOF_STR], size_t bufsize, const char *src)
        REQ_(TOGGLE_LINENO,     "Toggle line numbers"), \
        REQ_(TOGGLE_REV_GRAPH,  "Toggle revision graph visualization"), \
        REQ_(STATUS_UPDATE,     "Update file status"), \
-       REQ_(EDIT,              "Open in editor")
+       REQ_(EDIT,              "Open in editor"), \
+       REQ_(CHERRY_PICK,       "Cherry-pick commit to current branch")
 
 
 /* User action requests. */
@@ -621,10 +627,10 @@ LINE(MAIN_REMOTE,  "",                    COLOR_YELLOW,   COLOR_DEFAULT,  A_BOLD), \
 LINE(MAIN_REF,     "",                 COLOR_CYAN,     COLOR_DEFAULT,  A_BOLD), \
 LINE(TREE_DIR,     "",                 COLOR_DEFAULT,  COLOR_DEFAULT,  A_NORMAL), \
 LINE(TREE_FILE,    "",                 COLOR_DEFAULT,  COLOR_DEFAULT,  A_NORMAL), \
-LINE(STAT_SECTION, "",                 COLOR_DEFAULT,  COLOR_BLUE,     A_BOLD), \
+LINE(STAT_SECTION, "",                 COLOR_CYAN,     COLOR_DEFAULT,  0), \
 LINE(STAT_NONE,    "",                 COLOR_DEFAULT,  COLOR_DEFAULT,  0), \
-LINE(STAT_STAGED,  "",                 COLOR_CYAN,     COLOR_DEFAULT,  0), \
-LINE(STAT_UNSTAGED,"",                 COLOR_YELLOW,   COLOR_DEFAULT,  0), \
+LINE(STAT_STAGED,  "",                 COLOR_MAGENTA,  COLOR_DEFAULT,  0), \
+LINE(STAT_UNSTAGED,"",                 COLOR_MAGENTA,  COLOR_DEFAULT,  0), \
 LINE(STAT_UNTRACKED,"",                        COLOR_MAGENTA,  COLOR_DEFAULT,  0)
 
 enum line_type {
@@ -779,6 +785,7 @@ static struct keybinding default_keybindings[] = {
        { ':',          REQ_PROMPT },
        { 'u',          REQ_STATUS_UPDATE },
        { 'e',          REQ_EDIT },
+       { 'C',          REQ_CHERRY_PICK },
 
        /* Using the ncurses SIGWINCH handler. */
        { KEY_RESIZE,   REQ_SCREEN_RESIZE },
@@ -1938,7 +1945,7 @@ update_view(struct view *view)
                        line[linelen - 1] = 0;
 
                if (opt_iconv != ICONV_NONE) {
-                       ICONV_INBUF_TYPE inbuf = line;
+                       ICONV_CONST char *inbuf = line;
                        size_t inlen = linelen;
 
                        char *outbuf = out_buffer;
@@ -2136,11 +2143,12 @@ open_view(struct view *prev, enum request request, enum open_flags flags)
 }
 
 static void
-open_editor(struct view *view, char *file)
+open_editor(struct view *view, bool from_root, char *file)
 {
        char cmd[SIZEOF_STR];
        char file_sq[SIZEOF_STR];
        char *editor;
+       char *prefix = from_root ? opt_cdup : "";
 
        editor = getenv("GIT_EDITOR");
        if (!editor && *opt_editor)
@@ -2153,7 +2161,7 @@ open_editor(struct view *view, char *file)
                editor = "vi";
 
        if (sq_quote(file_sq, 0, file) < sizeof(file_sq) &&
-           string_format(cmd, "%s %s", editor, file_sq)) {
+           string_format(cmd, "%s %s%s", editor, prefix, file_sq)) {
                def_prog_mode();           /* save current tty modes */
                endwin();                  /* restore original tty modes */
                system(cmd);
@@ -2171,6 +2179,11 @@ view_driver(struct view *view, enum request request)
 {
        int i;
 
+       if (request == REQ_NONE) {
+               doupdate();
+               return TRUE;
+       }
+
        if (view && view->lines) {
                request = view->ops->request(view, request, &view->line[view->lineno]);
                if (request == REQ_NONE)
@@ -2321,13 +2334,14 @@ view_driver(struct view *view, enum request request)
                report("Nothing to edit");
                break;
 
+       case REQ_CHERRY_PICK:
+               report("Nothing to cherry-pick");
+               break;
+
        case REQ_ENTER:
                report("Nothing to enter");
                break;
 
-       case REQ_NONE:
-               doupdate();
-               return TRUE;
 
        case REQ_VIEW_CLOSE:
                /* XXX: Mark closed views by letting view->parent point to the
@@ -3038,12 +3052,14 @@ status_open(struct view *view)
        struct stat statbuf;
        char exclude[SIZEOF_STR];
        char cmd[SIZEOF_STR];
+       unsigned long prev_lineno = view->lineno;
        size_t i;
 
+
        for (i = 0; i < view->lines; i++)
                free(view->line[i].data);
        free(view->line);
-       view->lines = view->line_size = 0;
+       view->lines = view->line_size = view->lineno = 0;
        view->line = NULL;
 
        if (!realloc_lines(view, view->line_size + 6))
@@ -3067,6 +3083,13 @@ status_open(struct view *view)
            !status_run(view, cmd, FALSE, LINE_STAT_UNTRACKED))
                return FALSE;
 
+       /* If all went well restore the previous line number to stay in
+        * the context. */
+       if (prev_lineno < view->lines)
+               view->lineno = prev_lineno;
+       else
+               view->lineno = view->lines - 1;
+
        return TRUE;
 }
 
@@ -3296,7 +3319,7 @@ status_request(struct view *view, enum request request, struct line *line)
                if (!status)
                        return request;
 
-               open_editor(view, status->name);
+               open_editor(view, status->status != '?', status->name);
                break;
 
        case REQ_ENTER:
@@ -3530,7 +3553,7 @@ stage_request(struct view *view, enum request request, struct line *line)
                if (!stage_status.name[0])
                        return request;
 
-               open_editor(view, stage_status.name);
+               open_editor(view, stage_status.status != '?', stage_status.name);
                break;
 
        case REQ_ENTER:
@@ -3981,6 +4004,26 @@ main_read(struct view *view, char *line)
        return TRUE;
 }
 
+static void
+cherry_pick_commit(struct commit *commit)
+{
+       char cmd[SIZEOF_STR];
+       char *cherry_pick = getenv("TIG_CHERRY_PICK");
+
+       if (!cherry_pick)
+               cherry_pick = "git cherry-pick";
+
+       if (string_format(cmd, "%s %s", cherry_pick, commit->id)) {
+               def_prog_mode();           /* save current tty modes */
+               endwin();                  /* restore original tty modes */
+               system(cmd);
+               fprintf(stderr, "Press Enter to continue");
+               getc(stdin);
+               reset_prog_mode();
+               redraw_display();
+       }
+}
+
 static enum request
 main_request(struct view *view, enum request request, struct line *line)
 {
@@ -3988,6 +4031,8 @@ main_request(struct view *view, enum request request, struct line *line)
 
        if (request == REQ_ENTER)
                open_view(view, REQ_VIEW_DIFF, flags);
+       else if (request == REQ_CHERRY_PICK)
+               cherry_pick_commit(line->data);
        else
                return request;
 
@@ -4609,10 +4654,6 @@ main(int argc, char *argv[])
        if (load_repo_info() == ERR)
                die("Failed to load repo info.");
 
-       /* Require a git repository unless when running in pager mode. */
-       if (!opt_git_dir[0])
-               die("Not a git repository");
-
        if (load_options() == ERR)
                die("Failed to load user config.");
 
@@ -4624,6 +4665,10 @@ main(int argc, char *argv[])
        if (!parse_options(argc, argv))
                return 0;
 
+       /* Require a git repository unless when running in pager mode. */
+       if (!opt_git_dir[0])
+               die("Not a git repository");
+
        if (*opt_codeset && strcmp(opt_codeset, opt_encoding)) {
                opt_iconv = iconv_open(opt_codeset, opt_encoding);
                if (opt_iconv == ICONV_NONE)