index df44fcf422cd6ad22b7b0d99aba63f789086ab8f..97794b0e6e0d85793b678537aff32e65902c5fe7 100644 (file)
--- a/tig.c
+++ b/tig.c
@@ -121,7 +121,7 @@ static size_t utf8_length(const char **string, size_t col, int *width, size_t ma
#define GIT_CONFIG "config"
#endif
-/* Some ascii-shorthands fitted into the ncurses namespace. */
+/* Some ASCII-shorthands fitted into the ncurses namespace. */
#define KEY_TAB '\t'
#define KEY_RETURN '\r'
#define KEY_ESC 27
static bool format_argv(const char *dst[], const char *src[], enum format_flags flags);
-struct int_map {
- const char *name;
- int namelen;
- int value;
-};
-
-static int
-set_from_int_map(struct int_map *map, size_t map_size,
- int *value, const char *name, int namelen)
-{
-
- int i;
-
- for (i = 0; i < map_size; i++)
- if (namelen == map[i].namelen &&
- !strncasecmp(name, map[i].name, namelen)) {
- *value = map[i].value;
- return OK;
- }
-
- return ERR;
-}
-
enum input_status {
INPUT_OK,
INPUT_SKIP,
{
size_t size, pos;
- for (pos = 0; line[pos]; pos++) {
+ for (size = pos = 0; line[pos]; pos++) {
if (line[pos] == '\t' && tabsize > 0)
size += tabsize - (size % tabsize);
else
return 0;
}
+struct enum_map {
+ const char *name;
+ int namelen;
+ int value;
+};
+
+#define ENUM_MAP(name, value) { name, STRING_SIZE(name), value }
+
+static bool
+map_enum_do(struct enum_map *map, size_t map_size, int *value, const char *name)
+{
+ size_t namelen = strlen(name);
+ int i;
+
+ for (i = 0; i < map_size; i++)
+ if (namelen == map[i].namelen &&
+ !string_enum_compare(name, map[i].name, namelen)) {
+ *value = map[i].value;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+#define map_enum(attr, map, name) \
+ map_enum_do(map, ARRAY_SIZE(map), attr, name)
+
#define prefixcmp(str1, str2) \
strncmp(str1, str2, STRING_SIZE(str2))
}
static bool
-run_io_buf(const char **argv, char buf[], size_t bufsize)
+io_read_buf(struct io *io, char buf[], size_t bufsize)
{
- struct io io = {};
bool error;
- if (!run_io_rd(&io, argv, FORMAT_NONE))
- return FALSE;
+ io->buf = io->bufpos = buf;
+ io->bufalloc = bufsize;
+ error = !io_get(io, '\n', TRUE) && io_error(io);
+ io->buf = NULL;
+
+ return done_io(io) || error;
+}
- io.buf = io.bufpos = buf;
- io.bufalloc = bufsize;
- error = !io_get(&io, '\n', TRUE) && io_error(&io);
- io.buf = NULL;
+static bool
+run_io_buf(const char **argv, char buf[], size_t bufsize)
+{
+ struct io io = {};
- return done_io(&io) || error;
+ return run_io_rd(&io, argv, FORMAT_NONE) && io_read_buf(&io, buf, bufsize);
}
static int
LINE(COMMIT, "commit ", COLOR_GREEN, COLOR_DEFAULT, 0), \
LINE(PARENT, "parent ", COLOR_BLUE, COLOR_DEFAULT, 0), \
LINE(TREE, "tree ", COLOR_BLUE, COLOR_DEFAULT, 0), \
-LINE(AUTHOR, "author ", COLOR_CYAN, COLOR_DEFAULT, 0), \
+LINE(AUTHOR, "author ", COLOR_GREEN, COLOR_DEFAULT, 0), \
LINE(COMMITTER, "committer ", COLOR_MAGENTA, COLOR_DEFAULT, 0), \
LINE(SIGNOFF, " Signed-off-by", COLOR_YELLOW, COLOR_DEFAULT, 0), \
LINE(ACKED, " Acked-by", COLOR_YELLOW, COLOR_DEFAULT, 0), \
LINE(STATUS, "", COLOR_GREEN, COLOR_DEFAULT, 0), \
LINE(DELIMITER, "", COLOR_MAGENTA, COLOR_DEFAULT, 0), \
LINE(DATE, "", COLOR_BLUE, COLOR_DEFAULT, 0), \
+LINE(MODE, "", COLOR_CYAN, COLOR_DEFAULT, 0), \
LINE(LINE_NUMBER, "", COLOR_CYAN, COLOR_DEFAULT, 0), \
LINE(TITLE_BLUR, "", COLOR_WHITE, COLOR_BLUE, 0), \
LINE(TITLE_FOCUS, "", COLOR_WHITE, COLOR_BLUE, A_BOLD), \
-LINE(MAIN_AUTHOR, "", COLOR_GREEN, COLOR_DEFAULT, 0), \
LINE(MAIN_COMMIT, "", COLOR_DEFAULT, COLOR_DEFAULT, 0), \
LINE(MAIN_TAG, "", COLOR_MAGENTA, COLOR_DEFAULT, A_BOLD), \
LINE(MAIN_LOCAL_TAG,"", COLOR_MAGENTA, COLOR_DEFAULT, 0), \
LINE(MAIN_REF, "", COLOR_CYAN, COLOR_DEFAULT, 0), \
LINE(MAIN_HEAD, "", COLOR_CYAN, COLOR_DEFAULT, A_BOLD), \
LINE(MAIN_REVGRAPH,"", COLOR_MAGENTA, COLOR_DEFAULT, 0), \
-LINE(TREE_PARENT, "", COLOR_DEFAULT, COLOR_DEFAULT, A_BOLD), \
-LINE(TREE_MODE, "", COLOR_CYAN, COLOR_DEFAULT, 0), \
+LINE(TREE_HEAD, "", COLOR_DEFAULT, COLOR_DEFAULT, A_BOLD), \
LINE(TREE_DIR, "", COLOR_YELLOW, COLOR_DEFAULT, A_NORMAL), \
LINE(TREE_FILE, "", COLOR_DEFAULT, COLOR_DEFAULT, A_NORMAL), \
LINE(STAT_HEAD, "", COLOR_YELLOW, COLOR_DEFAULT, 0), \
#undef KEYMAP_
};
-static struct int_map keymap_table[] = {
-#define KEYMAP_(name) { #name, STRING_SIZE(#name), KEYMAP_##name }
+static struct enum_map keymap_table[] = {
+#define KEYMAP_(name) ENUM_MAP(#name, KEYMAP_##name)
KEYMAP_INFO
#undef KEYMAP_
};
-#define set_keymap(map, name) \
- set_from_int_map(keymap_table, ARRAY_SIZE(keymap_table), map, name, strlen(name))
+#define set_keymap(map, name) map_enum(map, keymap_table, name)
struct keybinding_table {
struct keybinding *data;
* User config file handling.
*/
-static struct int_map color_map[] = {
-#define COLOR_MAP(name) { #name, STRING_SIZE(#name), COLOR_##name }
+static struct enum_map color_map[] = {
+#define COLOR_MAP(name) ENUM_MAP(#name, COLOR_##name)
COLOR_MAP(DEFAULT),
COLOR_MAP(BLACK),
COLOR_MAP(BLUE),
COLOR_MAP(YELLOW),
};
-#define set_color(color, name) \
- set_from_int_map(color_map, ARRAY_SIZE(color_map), color, name, strlen(name))
-
-static struct int_map attr_map[] = {
-#define ATTR_MAP(name) { #name, STRING_SIZE(#name), A_##name }
+static struct enum_map attr_map[] = {
+#define ATTR_MAP(name) ENUM_MAP(#name, A_##name)
ATTR_MAP(NORMAL),
ATTR_MAP(BLINK),
ATTR_MAP(BOLD),
ATTR_MAP(UNDERLINE),
};
-#define set_attribute(attr, name) \
- set_from_int_map(attr_map, ARRAY_SIZE(attr_map), attr, name, strlen(name))
+#define set_attribute(attr, name) map_enum(attr, attr_map, name)
+
+static int
+parse_int(int *opt, const char *arg, int min, int max)
+{
+ int value = atoi(arg);
+
+ if (min <= value && value <= max)
+ *opt = value;
+ return OK;
+}
+
+static bool
+set_color(int *color, const char *name)
+{
+ if (map_enum(color, color_map, name))
+ return TRUE;
+ if (!prefixcmp(name, "color"))
+ return parse_int(color, name + 5, 0, 255) == OK;
+ return FALSE;
+}
static int config_lineno;
static bool config_errors;
static const char *config_msg;
-/* Wants: object fgcolor bgcolor [attr] */
+/* Wants: object fgcolor bgcolor [attribute] */
static int
option_color_command(int argc, const char *argv[])
{
info = get_line_info(argv[0]);
if (!info) {
- if (!string_enum_compare(argv[0], "main-delim", strlen("main-delim"))) {
- info = get_line_info("delimiter");
-
- } else if (!string_enum_compare(argv[0], "main-date", strlen("main-date"))) {
- info = get_line_info("date");
+ static struct enum_map obsolete[] = {
+ ENUM_MAP("main-delim", LINE_DELIMITER),
+ ENUM_MAP("main-date", LINE_DATE),
+ ENUM_MAP("main-author", LINE_AUTHOR),
+ };
+ int index;
- } else {
+ if (!map_enum(&index, obsolete, argv[0])) {
config_msg = "Unknown color name";
return ERR;
}
+ info = &line_info[index];
}
- if (set_color(&info->fg, argv[1]) == ERR ||
- set_color(&info->bg, argv[2]) == ERR) {
+ if (!set_color(&info->fg, argv[1]) ||
+ !set_color(&info->bg, argv[2])) {
config_msg = "Unknown color";
return ERR;
}
- if (argc == 4 && set_attribute(&info->attr, argv[3]) == ERR) {
+ if (argc == 4 && !set_attribute(&info->attr, argv[3])) {
config_msg = "Unknown attribute";
return ERR;
}
return OK;
}
-static bool parse_bool(const char *s)
+static int parse_bool(bool *opt, const char *arg)
{
- return (!strcmp(s, "1") || !strcmp(s, "true") ||
- !strcmp(s, "yes")) ? TRUE : FALSE;
+ *opt = (!strcmp(arg, "1") || !strcmp(arg, "true") || !strcmp(arg, "yes"))
+ ? TRUE : FALSE;
+ return OK;
}
static int
-parse_int(const char *s, int default_value, int min, int max)
+parse_string(char *opt, const char *arg, size_t optsize)
{
- int value = atoi(s);
+ int arglen = strlen(arg);
- return (value < min || value > max) ? default_value : value;
+ switch (arg[0]) {
+ case '\"':
+ case '\'':
+ if (arglen == 1 || arg[arglen - 1] != arg[0]) {
+ config_msg = "Unmatched quotation";
+ return ERR;
+ }
+ arg += 1; arglen -= 2;
+ default:
+ string_ncopy_do(opt, optsize, arg, strlen(arg));
+ return OK;
+ }
}
/* Wants: name = value */
return ERR;
}
- if (!strcmp(argv[0], "show-author")) {
- opt_author = parse_bool(argv[2]);
- return OK;
- }
+ if (!strcmp(argv[0], "show-author"))
+ return parse_bool(&opt_author, argv[2]);
- if (!strcmp(argv[0], "show-date")) {
- opt_date = parse_bool(argv[2]);
- return OK;
- }
+ if (!strcmp(argv[0], "show-date"))
+ return parse_bool(&opt_date, argv[2]);
- if (!strcmp(argv[0], "show-rev-graph")) {
- opt_rev_graph = parse_bool(argv[2]);
- return OK;
- }
-
- if (!strcmp(argv[0], "show-refs")) {
- opt_show_refs = parse_bool(argv[2]);
- return OK;
- }
+ if (!strcmp(argv[0], "show-rev-graph"))
+ return parse_bool(&opt_rev_graph, argv[2]);
- if (!strcmp(argv[0], "show-line-numbers")) {
- opt_line_number = parse_bool(argv[2]);
- return OK;
- }
+ if (!strcmp(argv[0], "show-refs"))
+ return parse_bool(&opt_show_refs, argv[2]);
- if (!strcmp(argv[0], "line-graphics")) {
- opt_line_graphics = parse_bool(argv[2]);
- return OK;
- }
+ if (!strcmp(argv[0], "show-line-numbers"))
+ return parse_bool(&opt_line_number, argv[2]);
- if (!strcmp(argv[0], "line-number-interval")) {
- opt_num_interval = parse_int(argv[2], opt_num_interval, 1, 1024);
- return OK;
- }
+ if (!strcmp(argv[0], "line-graphics"))
+ return parse_bool(&opt_line_graphics, argv[2]);
- if (!strcmp(argv[0], "author-width")) {
- opt_author_cols = parse_int(argv[2], opt_author_cols, 0, 1024);
- return OK;
- }
+ if (!strcmp(argv[0], "line-number-interval"))
+ return parse_int(&opt_num_interval, argv[2], 1, 1024);
- if (!strcmp(argv[0], "tab-size")) {
- opt_tab_size = parse_int(argv[2], opt_tab_size, 1, 1024);
- return OK;
- }
+ if (!strcmp(argv[0], "author-width"))
+ return parse_int(&opt_author_cols, argv[2], 0, 1024);
- if (!strcmp(argv[0], "commit-encoding")) {
- const char *arg = argv[2];
- int arglen = strlen(arg);
+ if (!strcmp(argv[0], "tab-size"))
+ return parse_int(&opt_tab_size, argv[2], 1, 1024);
- switch (arg[0]) {
- case '"':
- case '\'':
- if (arglen == 1 || arg[arglen - 1] != arg[0]) {
- config_msg = "Unmatched quotation";
- return ERR;
- }
- arg += 1; arglen -= 2;
- default:
- string_ncopy(opt_encoding, arg, strlen(arg));
- return OK;
- }
- }
+ if (!strcmp(argv[0], "commit-encoding"))
+ return parse_string(opt_encoding, argv[2], sizeof(opt_encoding));
config_msg = "Unknown variable name";
return ERR;
request = get_request(argv[2]);
if (request == REQ_NONE) {
- struct {
- const char *name;
- enum request request;
- } obsolete[] = {
- { "cherry-pick", REQ_NONE },
- { "screen-resize", REQ_NONE },
- { "tree-parent", REQ_PARENT },
+ static struct enum_map obsolete[] = {
+ ENUM_MAP("cherry-pick", REQ_NONE),
+ ENUM_MAP("screen-resize", REQ_NONE),
+ ENUM_MAP("tree-parent", REQ_PARENT),
};
- size_t namelen = strlen(argv[2]);
- int i;
+ int alias;
- for (i = 0; i < ARRAY_SIZE(obsolete); i++) {
- if (namelen != strlen(obsolete[i].name) ||
- string_enum_compare(obsolete[i].name, argv[2], namelen))
- continue;
- if (obsolete[i].request != REQ_NONE)
- add_keybinding(keymap, obsolete[i].request, key);
+ if (map_enum(&alias, obsolete, argv[2])) {
+ if (alias != REQ_NONE)
+ add_keybinding(keymap, alias, key);
config_msg = "Obsolete request name";
return ERR;
}
{
struct io io = {};
- /* It's ok that the file doesn't exist. */
+ /* It's OK that the file doesn't exist. */
if (!io_open(&io, path))
return;
add_builtin_run_requests();
- if (!tigrc_system) {
- if (!string_format(buf, "%s/tigrc", SYSCONFDIR))
- return ERR;
- tigrc_system = buf;
- }
+ if (!tigrc_system)
+ tigrc_system = SYSCONFDIR "/tigrc";
load_option_file(tigrc_system);
if (!tigrc_user) {
/* Searching */
char grep[SIZEOF_STR]; /* Search string */
- regex_t *regex; /* Pre-compiled regex */
+ regex_t *regex; /* Pre-compiled regexp */
/* If non-NULL, points to the view that opened this view. If this view
* is closed tig will switch back to the parent view. */
bool (*draw)(struct view *view, struct line *line, unsigned int lineno);
/* Depending on view handle a special requests. */
enum request (*request)(struct view *view, enum request request, struct line *line);
- /* Search for regex in a line. */
+ /* Search for regexp in a line. */
bool (*grep)(struct view *view, struct line *line);
/* Select line */
void (*select)(struct view *view, struct line *line);
author = initials;
}
- return draw_field(view, LINE_MAIN_AUTHOR, author, opt_author_cols, trim);
+ return draw_field(view, LINE_AUTHOR, author, opt_author_cols, trim);
+}
+
+static bool
+draw_mode(struct view *view, mode_t mode)
+{
+ static const char dir_mode[] = "drwxr-xr-x";
+ static const char link_mode[] = "lrwxrwxrwx";
+ static const char exe_mode[] = "-rwxr-xr-x";
+ static const char file_mode[] = "-rw-r--r--";
+ const char *str;
+
+ if (S_ISDIR(mode))
+ str = dir_mode;
+ else if (S_ISLNK(mode))
+ str = link_mode;
+ else if (mode & S_IXUSR)
+ str = exe_mode;
+ else
+ str = file_mode;
+
+ return draw_field(view, LINE_MODE, str, sizeof(file_mode), FALSE);
}
static bool
enum open_flags {
OPEN_DEFAULT = 0, /* Use default view switching. */
OPEN_SPLIT = 1, /* Split current view. */
- OPEN_BACKGROUNDED = 2, /* Backgrounded. */
OPEN_RELOAD = 4, /* Reload view even if it is the current. */
- OPEN_NOMAXIMIZE = 8, /* Do not maximize the current view. */
OPEN_REFRESH = 16, /* Refresh view using previous command. */
OPEN_PREPARED = 32, /* Open already prepared command. */
};
static void
open_view(struct view *prev, enum request request, enum open_flags flags)
{
- bool backgrounded = !!(flags & OPEN_BACKGROUNDED);
bool split = !!(flags & OPEN_SPLIT);
bool reload = !!(flags & (OPEN_RELOAD | OPEN_REFRESH | OPEN_PREPARED));
- bool nomaximize = !!(flags & (OPEN_NOMAXIMIZE | OPEN_REFRESH));
+ bool nomaximize = !!(flags & OPEN_REFRESH);
struct view *view = VIEW(request);
int nviews = displayed_views();
struct view *base_view = display[0];
if (split) {
display[1] = view;
- if (!backgrounded)
- current_view = 1;
+ current_view = 1;
} else if (!nomaximize) {
/* Maximize the current view. */
memset(display, 0, sizeof(display));
}
if (prev && view != prev) {
- if (split && !backgrounded) {
+ if (split) {
/* "Blur" the previous view. */
update_view_title(prev);
}
redraw_view(view);
report("");
}
-
- /* If the view is backgrounded the above calls to report()
- * won't redraw the view title. */
- if (backgrounded)
- update_view_title(view);
}
static void
* View backend utilities
*/
+static void
+parse_timezone(time_t *time, const char *zone)
+{
+ long tz;
+
+ tz = ('0' - zone[1]) * 60 * 60 * 10;
+ tz += ('0' - zone[2]) * 60 * 60;
+ tz += ('0' - zone[3]) * 60;
+ tz += ('0' - zone[4]);
+
+ if (zone[0] == '-')
+ tz = -tz;
+
+ *time -= tz;
+}
+
/* Parse author lines where the name may be empty:
* author <email@address.tld> 1138474660 +0100
*/
@@ -3340,20 +3361,8 @@ parse_author_line(char *ident, char *author, size_t authorsize, struct tm *tm)
char *zone = strchr(secs, ' ');
time_t time = (time_t) atol(secs);
- if (zone && strlen(zone) == STRING_SIZE(" +0700")) {
- long tz;
-
- zone++;
- tz = ('0' - zone[1]) * 60 * 60 * 10;
- tz += ('0' - zone[2]) * 60 * 60;
- tz += ('0' - zone[3]) * 60;
- tz += ('0' - zone[4]) * 60;
-
- if (zone[0] == '-')
- tz = -tz;
-
- time -= tz;
- }
+ if (zone && strlen(zone) == STRING_SIZE(" +0700"))
+ parse_timezone(&time, zone + 1);
gmtime_r(&time, tm);
}
/* Parse output from git-ls-tree(1):
*
- * 100644 blob fb0e31ea6cc679b7379631188190e975f5789c26 Makefile
- * 100644 blob 5304ca4260aaddaee6498f9630e7d471b8591ea6 README
* 100644 blob f931e1d229c3e185caad4449bf5b66ed72462657 tig.c
- * 100644 blob ed09fe897f3c7c9af90bcf80cae92558ea88ae38 web.conf
*/
#define SIZEOF_TREE_ATTR \
- STRING_SIZE("100644 blob ed09fe897f3c7c9af90bcf80cae92558ea88ae38\t")
+ STRING_SIZE("100644 blob f931e1d229c3e185caad4449bf5b66ed72462657\t")
#define SIZEOF_TREE_MODE \
STRING_SIZE("100644 ")
struct io io = {};
if (!view->lines) {
- tree_entry(view, LINE_TREE_PARENT, opt_path, NULL, NULL);
+ tree_entry(view, LINE_TREE_HEAD, opt_path, NULL, NULL);
report("Tree is empty");
return TRUE;
}
if (textlen <= SIZEOF_TREE_ATTR)
return FALSE;
if (view->lines == 0 &&
- !tree_entry(view, LINE_TREE_PARENT, opt_path, NULL, NULL))
+ !tree_entry(view, LINE_TREE_HEAD, opt_path, NULL, NULL))
return FALSE;
/* Strip the path part ... */
{
struct tree_entry *entry = line->data;
- if (line->type == LINE_TREE_PARENT) {
+ if (line->type == LINE_TREE_HEAD) {
if (draw_text(view, line->type, "Directory path /", TRUE))
return TRUE;
} else {
- char mode[11] = "-r--r--r--";
-
- if (S_ISDIR(entry->mode)) {
- mode[3] = mode[6] = mode[9] = 'x';
- mode[0] = 'd';
- }
- if (S_ISLNK(entry->mode))
- mode[0] = 'l';
- if (entry->mode & S_IWUSR)
- mode[2] = 'w';
- if (entry->mode & S_IXUSR)
- mode[3] = 'x';
- if (entry->mode & S_IXGRP)
- mode[6] = 'x';
- if (entry->mode & S_IXOTH)
- mode[9] = 'x';
- if (draw_field(view, LINE_TREE_MODE, mode, 11, TRUE))
+ if (draw_mode(view, entry->mode))
return TRUE;
if (opt_author && draw_author(view, entry->author))
switch (line->type) {
case LINE_TREE_DIR:
- /* Depending on whether it is a subdir or parent (updir?) link
+ /* Depending on whether it is a subdirectory or parent link
* mangle the path buffer. */
if (line == &view->line[1] && *opt_path) {
pop_tree_stack_entry();
author_time = (time_t) atol(line);
} else if (match_blame_header("author-tz ", &line)) {
- long tz;
-
- tz = ('0' - line[1]) * 60 * 60 * 10;
- tz += ('0' - line[2]) * 60 * 60;
- tz += ('0' - line[3]) * 60;
- tz += ('0' - line[4]) * 60;
-
- if (line[0] == '-')
- tz = -tz;
-
- author_time -= tz;
+ parse_timezone(&author_time, line);
gmtime_r(&author_time, &commit->time);
} else if (match_blame_header("summary ", &line)) {
@@ -4645,8 +4625,8 @@ status_run(struct view *view, const char *argv[], char status, enum line_type ty
if (!buf)
break;
- /* Collapse all 'M'odified entries that follow a
- * associated 'U'nmerged entry. */
+ /* Collapse all modified entries that follow an
+ * associated unmerged entry. */
if (unmerged == file) {
unmerged->status = 'U';
unmerged = NULL;
view->p_restore = FALSE;
}
+static void
+status_update_onbranch(void)
+{
+ static const char *paths[][2] = {
+ { "rebase-apply/rebasing", "Rebasing" },
+ { "rebase-apply/applying", "Applying mailbox" },
+ { "rebase-apply/", "Rebasing mailbox" },
+ { "rebase-merge/interactive", "Interactive rebase" },
+ { "rebase-merge/", "Rebase merge" },
+ { "MERGE_HEAD", "Merging" },
+ { "BISECT_LOG", "Bisecting" },
+ { "HEAD", "On branch" },
+ };
+ char buf[SIZEOF_STR];
+ struct stat stat;
+ int i;
+
+ if (is_initial_commit()) {
+ string_copy(status_onbranch, "Initial commit");
+ return;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(paths); i++) {
+ char *head = opt_head;
+
+ if (!string_format(buf, "%s/%s", opt_git_dir, paths[i][0]) ||
+ lstat(buf, &stat) < 0)
+ continue;
+
+ if (!*opt_head) {
+ struct io io = {};
+
+ if (string_format(buf, "%s/rebase-merge/head-name", opt_git_dir) &&
+ io_open(&io, buf) &&
+ io_read_buf(&io, buf, sizeof(buf))) {
+ head = chomp_string(buf);
+ if (!prefixcmp(head, "refs/heads/"))
+ head += STRING_SIZE("refs/heads/");
+ }
+ }
+
+ if (!string_format(status_onbranch, "%s %s", paths[i][1], head))
+ string_copy(status_onbranch, opt_head);
+ return;
+ }
+
+ string_copy(status_onbranch, "Not currently on any branch");
+}
+
/* First parse staged info using git-diff-index(1), then parse unstaged
* info using git-diff-files(1), and finally untracked files using
* git-ls-files(1). */
reset_view(view);
add_line_data(view, NULL, LINE_STAT_HEAD);
- if (is_initial_commit())
- string_copy(status_onbranch, "Initial commit");
- else if (!*opt_head)
- string_copy(status_onbranch, "Not currently on any branch");
- else if (!string_format(status_onbranch, "On branch %s", opt_head))
- return FALSE;
+ status_update_onbranch();
run_io_bg(update_index_argv);
}
VIEW(REQ_VIEW_STATUS)->p_restore = TRUE;
- open_view(view, REQ_VIEW_STATUS, OPEN_RELOAD | OPEN_NOMAXIMIZE);
+ open_view(view, REQ_VIEW_STATUS, OPEN_REFRESH);
/* Check whether the staged entry still exists, and close the
* stage view if it doesn't. */
/*
* Unicode / UTF-8 handling
*
- * NOTE: Much of the following code for dealing with unicode is derived from
+ * NOTE: Much of the following code for dealing with Unicode is derived from
* ELinks' UTF-8 code developed by Scrool <scroolik@gmail.com>. Origin file is
- * src/intl/charset.c from the utf8 branch commit elinks-0.11.0-g31f2c28.
+ * src/intl/charset.c from the UTF-8 branch commit elinks-0.11.0-g31f2c28.
*/
-/* I've (over)annotated a lot of code snippets because I am not entirely
- * confident that the approach taken by this small UTF-8 interface is correct.
- * --jonas */
-
static inline int
unicode_width(unsigned long c)
{
3,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3, 4,4,4,4,4,4,4,4, 5,5,5,5,6,6,1,1,
};
-/* Decode UTF-8 multi-byte representation into a unicode character. */
+/* Decode UTF-8 multi-byte representation into a Unicode character. */
static inline unsigned long
utf8_to_unicode(const char *string, size_t length)
{
unicode += (string[5] & 0x3f);
break;
default:
- die("Invalid unicode length");
+ die("Invalid Unicode length");
}
/* Invalid characters could return the special 0xfffd value but NUL
@@ -6110,7 +6130,7 @@ utf8_length(const char **start, size_t skip, int *width, size_t max_width, int *
* it is a single- or double-width character. */
unicode = utf8_to_unicode(string, bytes);
- /* FIXME: Graceful handling of invalid unicode character. */
+ /* FIXME: Graceful handling of invalid Unicode character. */
if (!unicode)
break;
if (!cursed)
die("Failed to initialize curses");
- nonl(); /* Tell curses not to do NL->CR/NL on output */
+ nonl(); /* Disable conversion and detect newlines from input. */
cbreak(); /* Take input chars one at a time, no wait for \n */
noecho(); /* Don't echo input */
leaveok(stdscr, FALSE);
}
if (check_replace && !strcmp(name, refs[refs_size - 1].name)) {
- /* it's an annotated tag, replace the previous sha1 with the
+ /* it's an annotated tag, replace the previous SHA1 with the
* resolved commit id; relies on the fact git-ls-remote lists
* the commit id of an annotated tag right before the commit id
* it points to. */
return run_io_load(ls_remote_argv, "\t", read_ref);
}
+static void
+set_repo_config_option(char *name, char *value, int (*cmd)(int, const char **))
+{
+ const char *argv[SIZEOF_ARG] = { name, "=" };
+ int argc = 1 + (cmd == option_set_command);
+ int error = ERR;
+
+ if (!argv_from_string(argv, &argc, value))
+ config_msg = "Too many option arguments";
+ else
+ error = cmd(argc, argv);
+
+ if (error == ERR)
+ warn("Option 'tig.%s': %s", name, config_msg);
+}
+
static int
read_repo_config_option(char *name, size_t namelen, char *value, size_t valuelen)
{
@@ -6618,6 +6654,15 @@ read_repo_config_option(char *name, size_t namelen, char *value, size_t valuelen
if (!strcmp(name, "core.editor"))
string_ncopy(opt_editor, value, valuelen);
+ if (!prefixcmp(name, "tig.color."))
+ set_repo_config_option(name + 10, value, option_color_command);
+
+ else if (!prefixcmp(name, "tig.bind."))
+ set_repo_config_option(name + 9, value, option_bind_command);
+
+ else if (!prefixcmp(name, "tig."))
+ set_repo_config_option(name + 4, value, option_set_command);
+
/* branch.<head>.remote */
if (*opt_head &&
!strncmp(name, "branch.", 7) &&