*/
#ifndef VERSION
-#define VERSION "tig-0.3"
+#define VERSION "tig-0.4.git"
#endif
#ifndef DEBUG
#include <unistd.h>
#include <time.h>
+#include <locale.h>
+#include <langinfo.h>
+#include <iconv.h>
+
#include <curses.h>
#if __GNUC__ >= 3
/* 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 ")
"git ls-remote . 2>/dev/null"
#define TIG_DIFF_CMD \
- "git show --patch-with-stat --find-copies-harder -B -C %s"
+ "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"
+ "git log --cc --stat -n100 %s 2>/dev/null"
#define TIG_MAIN_CMD \
- "git log --topo-order --stat --pretty=raw %s"
+ "git log --topo-order --pretty=raw %s 2>/dev/null"
/* XXX: Needs to be defined to the empty string. */
#define TIG_HELP_CMD ""
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,
{ '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. */
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
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;
break;
if (end) {
+ char *email = end + 1;
+
for (; end > ident && isspace(end[-1]); end--) ;
+
+ if (end == ident && *email) {
+ ident = email;
+ end = strchr(ident, '>');
+ for (; end > ident && isspace(end[-1]); end--) ;
+ }
*end = 0;
}
+ /* End is NULL or ident meaning there's no author. */
+ if (end <= ident)
+ ident = "Unknown";
+
string_copy(commit->author, ident);
/* Parse epoch and timezone */
/* Leave stdin and stdout alone when acting as a pager. */
FILE *io = fopen("/dev/tty", "r+");
+ if (!io)
+ die("Failed to open /dev/tty");
cursed = !!newterm(NULL, io, io);
}
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;
}
signal(SIGINT, quit);
+ if (setlocale(LC_ALL, "")) {
+ string_copy(opt_codeset, nl_langinfo(CODESET));
+ }
+
if (load_options() == ERR)
die("Failed to load user config.");
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.");
[frame="none"]
`-----------------------`-----------------------------------------------------
endif::backend-xhtml11[]
-View switching::
+View switching:
------------------------------------------------------------------------------
view-main Show main view
view-diff Show diff view
[frame="none"]
`-----------------------`-----------------------------------------------------
endif::backend-xhtml11[]
-View manipulation::
+View manipulation:
------------------------------------------------------------------------------
enter Enter current line and scroll
next Move to next
[frame="none"]
`-----------------------`-----------------------------------------------------
endif::backend-xhtml11[]
-Cursor navigation::
+Cursor navigation:
------------------------------------------------------------------------------
move-up Move cursor one line up
move-down Move cursor one line down
[frame="none"]
`-----------------------`-----------------------------------------------------
endif::backend-xhtml11[]
-Scrolling::
+Scrolling:
------------------------------------------------------------------------------
scroll-line_up Scroll one line up
scroll-line_down Scroll one line down
[frame="none"]
`-----------------------`-----------------------------------------------------
endif::backend-xhtml11[]
-Misc::
+Misc:
------------------------------------------------------------------------------
prompt Bring up the prompt
screen-update Update the screen