X-Git-Url: https://git.distorted.org.uk/~mdw/tig/blobdiff_plain/8fee6614be3b0fe4b1f65e5746be05b67737a22a..c9ca1ec34b48072886183a80442b1e5f2614a46d:/tig.c diff --git a/tig.c b/tig.c index b2e1a36..08cdd41 100644 --- a/tig.c +++ b/tig.c @@ -30,6 +30,10 @@ #include #include +#include +#include +#include + #include #if __GNUC__ >= 3 @@ -57,6 +61,8 @@ static size_t utf8_length(const char *string, size_t max_width, int *coloffset, /* This color name can be used to refer to the default term colors. */ #define COLOR_DEFAULT (-1) +#define ICONV_NONE ((iconv_t) -1) + /* The format and size of the date column in the main view. */ #define DATE_FORMAT "%Y-%m-%d %H:%M" #define DATE_COLS STRING_SIZE("2006-04-29 14:21 ") @@ -74,7 +80,7 @@ static size_t utf8_length(const char *string, size_t max_width, int *coloffset, "git ls-remote . 2>/dev/null" #define TIG_DIFF_CMD \ - "git show --patch-with-stat --find-copies-harder -B -C %s 2>/dev/null" + "git show --root --patch-with-stat --find-copies-harder -B -C %s 2>/dev/null" #define TIG_LOG_CMD \ "git log --cc --stat -n100 %s 2>/dev/null" @@ -361,9 +367,11 @@ static int opt_num_interval = NUMBER_INTERVAL; static int opt_tab_size = TABSIZE; static enum request opt_request = REQ_VIEW_MAIN; static char opt_cmd[SIZEOF_CMD] = ""; -static char opt_encoding[20] = ""; -static bool opt_utf8 = TRUE; static FILE *opt_pipe = NULL; +static char opt_encoding[20] = "UTF-8"; +static bool opt_utf8 = TRUE; +static char opt_codeset[20] = "UTF-8"; +static iconv_t opt_iconv = ICONV_NONE; enum option_type { OPT_NONE, @@ -679,7 +687,7 @@ static struct keybinding default_keybindings[] = { { 'v', REQ_SHOW_VERSION }, { 'r', REQ_SCREEN_REDRAW }, { 'n', REQ_TOGGLE_LINENO }, - { 'g', REQ_TOGGLE_REV_GRAPH}, + { 'g', REQ_TOGGLE_REV_GRAPH }, { ':', REQ_PROMPT }, /* wgetch() with nodelay() enabled returns ERR when there's no input. */ @@ -1616,7 +1624,8 @@ realloc_lines(struct view *view, size_t line_size) static bool update_view(struct view *view) { - char buffer[BUFSIZ]; + char in_buffer[BUFSIZ]; + char out_buffer[BUFSIZ * 2]; char *line; /* The number of lines to read. If too low it will cause too much * redrawing (and possible flickering), if too high responsiveness @@ -1634,12 +1643,28 @@ update_view(struct view *view) if (!realloc_lines(view, view->lines + lines)) goto alloc_error; - while ((line = fgets(buffer, sizeof(buffer), view->pipe))) { - int linelen = strlen(line); + while ((line = fgets(in_buffer, sizeof(in_buffer), view->pipe))) { + size_t linelen = strlen(line); if (linelen) line[linelen - 1] = 0; + if (opt_iconv != ICONV_NONE) { + char *inbuf = line; + size_t inlen = linelen; + + char *outbuf = out_buffer; + size_t outlen = sizeof(out_buffer); + + size_t ret; + + ret = iconv(opt_iconv, &inbuf, &inlen, &outbuf, &outlen); + if (ret != (size_t) -1) { + line = out_buffer; + linelen = strlen(out_buffer); + } + } + if (!view->ops->read(view, line)) goto alloc_error; @@ -2046,14 +2071,14 @@ static void add_pager_refs(struct view *view, struct line *line) { char buf[1024]; - char *data = line->data; + char *commit_id = line->data + STRING_SIZE("commit "); struct ref **refs; int bufpos = 0, refpos = 0; const char *sep = "Refs: "; assert(line->type == LINE_COMMIT); - refs = get_refs(data + STRING_SIZE("commit ")); + refs = get_refs(commit_id); if (!refs) return; @@ -2679,7 +2704,10 @@ read_prompt(void) buf[pos++] = 0; if (!string_format(opt_cmd, "git %s", buf)) return ERR; - opt_request = REQ_VIEW_PAGER; + if (strncmp(buf, "show", 4) && isspace(buf[4])) + opt_request = REQ_VIEW_DIFF; + else + opt_request = REQ_VIEW_PAGER; return OK; } @@ -2891,6 +2919,10 @@ main(int argc, char *argv[]) signal(SIGINT, quit); + if (setlocale(LC_ALL, "")) { + string_copy(opt_codeset, nl_langinfo(CODESET)); + } + if (load_options() == ERR) die("Failed to load user config."); @@ -2902,6 +2934,12 @@ main(int argc, char *argv[]) if (!parse_options(argc, argv)) return 0; + if (*opt_codeset && strcmp(opt_codeset, opt_encoding)) { + opt_iconv = iconv_open(opt_codeset, opt_encoding); + if (opt_iconv == (iconv_t) -1) + die("Failed to initialize character set conversion"); + } + if (load_refs() == ERR) die("Failed to load refs.");