index c1dd51366a2694bffe61de408c9e3f2c0ce37e61..54d99a721378cee897c49df99e728b61357dba55 100644 (file)
--- a/tig.c
+++ b/tig.c
-/* Copyright (c) 2006-2009 Jonas Fonseca <fonseca@diku.dk>
+/* Copyright (c) 2006-2010 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
static void __NORETURN die(const char *err, ...);
static void warn(const char *msg, ...);
static void report(const char *msg, ...);
-static void set_nonblocking_input(bool loading);
-static size_t utf8_length(const char **string, size_t col, int *width, size_t max_width, int *trimmed, bool reserve);
+static size_t utf8_length(const char **start, size_t skip, int *width, size_t max_width, int *trimmed, bool reserve, int tab_size);
static inline unsigned char utf8_char_length(const char *string, const char *end);
#define ABS(x) ((x) >= 0 ? (x) : -(x))
struct ref **refs; /* References for this ID. */
};
+static struct ref *get_ref_head();
static struct ref_list *get_ref_list(const char *id);
static void foreach_ref(bool (*visitor)(void *data, const struct ref *ref), void *data);
static int load_refs(void);
static char opt_file[SIZEOF_STR] = "";
static char opt_ref[SIZEOF_REF] = "";
static char opt_head[SIZEOF_REF] = "";
-static char opt_head_rev[SIZEOF_REV] = "";
static char opt_remote[SIZEOF_REF] = "";
static char opt_encoding[20] = "UTF-8";
-static char opt_codeset[20] = "UTF-8";
static iconv_t opt_iconv_in = ICONV_NONE;
static iconv_t opt_iconv_out = ICONV_NONE;
static char opt_search[SIZEOF_STR] = "";
static char opt_editor[SIZEOF_STR] = "";
static FILE *opt_tty = NULL;
-#define is_initial_commit() (!*opt_head_rev)
-#define is_head_commit(rev) (!strcmp((rev), "HEAD") || !strcmp(opt_head_rev, (rev)))
+#define is_initial_commit() (!get_ref_head())
+#define is_head_commit(rev) (!strcmp((rev), "HEAD") || (get_ref_head() && !strcmp(rev, get_ref_head()->id)))
#define mkdate(time) string_date(time, opt_date)
(view == display[0] || view == display[1])
-enum line_graphic {
- LINE_GRAPHIC_VLINE
-};
-
-static chtype line_graphics[] = {
- /* LINE_GRAPHIC_VLINE: */ '|'
-};
-
static inline void
set_view_attr(struct view *view, enum line_type type)
{
if (!view->curline->selected && view->curtype != type) {
- wattrset(view->win, get_line_attr(type));
+ (void) wattrset(view->win, get_line_attr(type));
wchgat(view->win, -1, 0, type, NULL);
view->curtype = type;
}
if (max_len <= 0)
return 0;
- len = utf8_length(&string, skip, &col, max_len, &trimmed, use_tilde);
+ len = utf8_length(&string, skip, &col, max_len, &trimmed, use_tilde, opt_tab_size);
set_view_attr(view, type);
if (len > 0) {
int digits3 = view->digits < 3 ? 3 : view->digits;
int max = MIN(view->width + view->yoffset - view->col, digits3);
char *text = NULL;
+ chtype separator = opt_line_graphics ? ACS_VLINE : '|';
lineno += view->offset + 1;
if (lineno == 1 || (lineno % opt_num_interval) == 0) {
view->col += draw_chars(view, LINE_LINE_NUMBER, text, max, TRUE);
else
view->col += draw_space(view, LINE_LINE_NUMBER, max, digits3);
- return draw_graphic(view, LINE_DEFAULT, &line_graphics[LINE_GRAPHIC_VLINE], 1);
+ return draw_graphic(view, LINE_DEFAULT, &separator, 1);
}
static bool
while (!view->ops->read(view, NULL))
if (!force)
return;
- set_nonblocking_input(FALSE);
if (force)
kill_io(view->pipe);
done_io(view->pipe);
static void
setup_update(struct view *view, const char *vid)
{
- set_nonblocking_input(TRUE);
reset_view(view);
string_copy_rev(view->vid, vid);
view->pipe = &view->io;
struct rev_filler *filler;
size_t i;
- if (opt_line_graphics)
- fillers[DEFAULT].line = line_graphics[LINE_GRAPHIC_VLINE];
-
+ fillers[DEFAULT].line = opt_line_graphics ? ACS_VLINE : '|';
filler = &fillers[DEFAULT];
for (i = 0; i < graph->pos; i++) {
*/
static inline int
-unicode_width(unsigned long c)
+unicode_width(unsigned long c, int tab_size)
{
if (c >= 0x1100 &&
(c <= 0x115f /* Hangul Jamo */
return 2;
if (c == '\t')
- return opt_tab_size;
+ return tab_size;
return 1;
}
*
* Returns the number of bytes to output from string to satisfy max_width. */
static size_t
-utf8_length(const char **start, size_t skip, int *width, size_t max_width, int *trimmed, bool reserve)
+utf8_length(const char **start, size_t skip, int *width, size_t max_width, int *trimmed, bool reserve, int tab_size)
{
const char *string = *start;
const char *end = strchr(string, '\0');
@@ -6891,7 +6878,7 @@ utf8_length(const char **start, size_t skip, int *width, size_t max_width, int *
if (!unicode)
break;
- ucwidth = unicode_width(unicode);
+ ucwidth = unicode_width(unicode, tab_size);
if (skip > 0) {
skip -= ucwidth <= skip ? ucwidth : skip;
*start += bytes;
update_view_title(view);
}
-/* Controls when nodelay should be in effect when polling user input. */
-static void
-set_nonblocking_input(bool loading)
-{
- static unsigned int loading_views;
-
- if ((loading == FALSE && loading_views-- == 1) ||
- (loading == TRUE && loading_views++ == 0))
- nodelay(status_win, loading);
-}
-
static void
init_display(void)
{
wbkgdset(status_win, get_line_attr(LINE_STATUS));
TABSIZE = opt_tab_size;
- if (opt_line_graphics) {
- line_graphics[LINE_GRAPHIC_VLINE] = ACS_VLINE;
- }
term = getenv("XTERM_VERSION") ? NULL : getenv("COLORTERM");
if (term && !strcmp(term, "gnome-terminal")) {
{
struct view *view;
int i, key, cursor_y, cursor_x;
+ bool loading = FALSE;
if (prompt_position)
input_mode = TRUE;
use_scroll_redrawwin)
redrawwin(view->win);
view->has_scrolled = FALSE;
+ if (view->pipe)
+ loading = TRUE;
}
/* Update the cursor position. */
/* Refresh, accept single keystroke of input */
doupdate();
+ nodelay(status_win, loading);
key = wgetch(status_win);
/* wgetch() with nodelay() enabled returns ERR when
@@ -7272,6 +7249,7 @@ static bool prompt_menu(const char *prompt, const struct menu_item *items, int *
static struct ref **refs = NULL;
static size_t refs_size = 0;
+static struct ref *refs_head = NULL;
static struct ref_list **ref_lists = NULL;
static size_t ref_lists_size = 0;
break;
}
+static struct ref *
+get_ref_head()
+{
+ return refs_head;
+}
+
static struct ref_list *
get_ref_list(const char *id)
{
} else if (!prefixcmp(name, "refs/heads/")) {
namelen -= STRING_SIZE("refs/heads/");
name += STRING_SIZE("refs/heads/");
- head = !strncmp(opt_head, name, namelen);
+ if (!strncmp(opt_head, name, namelen))
+ return OK;
} else if (!strcmp(name, "HEAD")) {
- string_ncopy(opt_head_rev, id, idlen);
- return OK;
+ head = TRUE;
+ if (*opt_head) {
+ namelen = strlen(opt_head);
+ name = opt_head;
+ }
}
/* If we are reloading or it's an annotated tag, replace the
ref->tracked = tracked;
string_copy_rev(ref->id, id);
+ if (head)
+ refs_head = ref;
return OK;
}
memmove(opt_head, offset, strlen(offset) + 1);
}
+ refs_head = NULL;
for (i = 0; i < refs_size; i++)
refs[i]->id[0] = 0;
int
main(int argc, const char *argv[])
{
+ const char *codeset = "UTF-8";
enum request request = parse_options(argc, argv);
struct view *view;
size_t i;
signal(SIGPIPE, SIG_IGN);
if (setlocale(LC_ALL, "")) {
- char *codeset = nl_langinfo(CODESET);
-
- string_ncopy(opt_codeset, codeset, strlen(codeset));
+ codeset = nl_langinfo(CODESET);
}
if (load_repo_info() == ERR)
if (!opt_git_dir[0] && request != REQ_VIEW_PAGER)
die("Not a git repository");
- if (*opt_encoding && strcmp(opt_codeset, "UTF-8")) {
+ if (*opt_encoding && strcmp(codeset, "UTF-8")) {
opt_iconv_in = iconv_open("UTF-8", opt_encoding);
if (opt_iconv_in == ICONV_NONE)
die("Failed to initialize character set conversion");
}
- if (*opt_codeset && strcmp(opt_codeset, "UTF-8")) {
- opt_iconv_out = iconv_open(opt_codeset, "UTF-8");
+ if (codeset && strcmp(codeset, "UTF-8")) {
+ opt_iconv_out = iconv_open(codeset, "UTF-8");
if (opt_iconv_out == ICONV_NONE)
die("Failed to initialize character set conversion");
}