summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 4a2909a)
raw | patch | inline | side by side (parent: 4a2909a)
author | Jonas Fonseca <fonseca@diku.dk> | |
Mon, 1 May 2006 03:44:47 +0000 (05:44 +0200) | ||
committer | Jonas Fonseca <fonseca@antimatter.localdomain> | |
Mon, 1 May 2006 03:44:47 +0000 (05:44 +0200) |
tig.c | patch | blob | history |
index f189fc0181e961adaeaa347c6a13767b327955a6..4c2d56dd790b5be62ba3228d60f4660241d649a4 100644 (file)
--- a/tig.c
+++ b/tig.c
static void report(const char *msg, ...);
static void update_title(void);
-/* Size of symbolic or SHA1 ID. */
-#define SIZEOF_REF 256
+#define SIZEOF_REF 256 /* Size of symbolic or SHA1 ID. */
+#define SIZEOF_CMD 1024 /* Size of command buffer. */
/* This color name can be used to refer to the default term colors. */
#define COLOR_DEFAULT (-1)
/* User requests. */
enum request {
/* XXX: Keep the view request first and in sync with views[]. */
+ REQ_VIEW_MAIN,
REQ_VIEW_DIFF,
REQ_VIEW_LOG,
- REQ_VIEW_MAIN,
+ REQ_VIEW_HELP,
REQ_QUIT,
REQ_SHOW_VERSION,
* -------
**/
-static int opt_line_number;
-static int opt_request = REQ_VIEW_MAIN;
+static int opt_line_number = FALSE;
+static int opt_num_interval = NUMBER_INTERVAL;
+static int opt_request = REQ_VIEW_MAIN;
-char head_id[SIZEOF_REF] = "HEAD";
-char commit_id[SIZEOF_REF] = "HEAD";
+char ref_head[SIZEOF_REF] = "HEAD";
+char ref_commit[SIZEOF_REF] = "HEAD";
/* Returns the index of log or diff command or -1 to exit. */
static int
/**
* log [options]::
* git log options.
- **/
- if (!strcmp(opt, "log")) {
- opt_request = REQ_VIEW_LOG;
- return i;
-
- /**
+ *
* diff [options]::
* git diff options.
**/
- } else if (!strcmp(opt, "diff")) {
- opt_request = REQ_VIEW_DIFF;
+ if (!strcmp(opt, "log") ||
+ !strcmp(opt, "diff")) {
+ opt_request = opt[0] = 'l'
+ ? REQ_VIEW_LOG : REQ_VIEW_DIFF;
return i;
/**
opt_request = REQ_VIEW_DIFF;
/**
- * -n, --line-number::
+ * -n[INTERVAL], --line-number[=INTERVAL]::
* Prefix line numbers in log and diff view.
+ * Optionally, with interval different than each line.
**/
- } else if (!strcmp(opt, "-n") ||
- !strcmp(opt, "--line-number")) {
+ } else if (!strncmp(opt, "-n", 2) ||
+ !strncmp(opt, "--line-number", 13)) {
+ char *num = opt;
+
+ if (opt[1] == 'n') {
+ num = opt + 2;
+
+ } else if (opt[STRING_SIZE("--line-number")] == '=') {
+ num = opt + STRING_SIZE("--line-number=");
+ }
+
+ if (isdigit(*num))
+ opt_num_interval = atoi(num);
+
opt_line_number = 1;
/**
* Commit reference, symbolic or raw SHA1 ID.
**/
} else if (opt[0] && opt[0] != '-') {
- string_copy(head_id, opt);
- string_copy(commit_id, opt);
+ string_copy(ref_head, opt);
+ string_copy(ref_commit, opt);
} else {
die("unknown command '%s'", opt);
{ 'w', REQ_SCROLL_PAGE_UP }, /* scroll field backward a page */
/* View switching */
+ { 'm', REQ_VIEW_MAIN },
{ 'd', REQ_VIEW_DIFF },
{ 'l', REQ_VIEW_LOG },
- { 'm', REQ_VIEW_MAIN },
+ { 'h', REQ_VIEW_HELP },
/* Misc */
{ KEY_ESC, REQ_QUIT },
* Line-oriented content detection.
*/
+/* Line type String to match Foreground Background Attr
+ * --------- --------------- ---------- ---------- ---- */
+#define LINE_INFO \
+ /* Diff markup */ \
+ LINE(DIFF, "diff --git ", COLOR_YELLOW, COLOR_DEFAULT, 0), \
+ LINE(INDEX, "index ", COLOR_BLUE, COLOR_DEFAULT, 0), \
+ LINE(DIFF_CHUNK, "@@", COLOR_MAGENTA, COLOR_DEFAULT, 0), \
+ LINE(DIFF_ADD, "+", COLOR_GREEN, COLOR_DEFAULT, 0), \
+ LINE(DIFF_DEL, "-", COLOR_RED, COLOR_DEFAULT, 0), \
+ LINE(DIFF_OLDMODE, "old mode ", COLOR_YELLOW, COLOR_DEFAULT, 0), \
+ LINE(DIFF_NEWMODE, "new mode ", COLOR_YELLOW, COLOR_DEFAULT, 0), \
+ LINE(DIFF_COPY, "copy ", COLOR_YELLOW, COLOR_DEFAULT, 0), \
+ LINE(DIFF_RENAME, "rename ", COLOR_YELLOW, COLOR_DEFAULT, 0), \
+ LINE(DIFF_SIM, "similarity ", COLOR_YELLOW, COLOR_DEFAULT, 0), \
+ LINE(DIFF_DISSIM, "dissimilarity ", COLOR_YELLOW, COLOR_DEFAULT, 0), \
+ /* Pretty print commit header */ \
+ LINE(AUTHOR, "Author: ", COLOR_CYAN, COLOR_DEFAULT, 0), \
+ LINE(MERGE, "Merge: ", COLOR_BLUE, COLOR_DEFAULT, 0), \
+ LINE(DATE, "Date: ", COLOR_YELLOW, COLOR_DEFAULT, 0), \
+ /* Raw commit header */ \
+ 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_IDENT, "author ", COLOR_CYAN, COLOR_DEFAULT, 0), \
+ LINE(COMMITTER, "committer ", COLOR_MAGENTA, COLOR_DEFAULT, 0), \
+ /* Misc */ \
+ LINE(DIFF_TREE, "diff-tree ", COLOR_BLUE, COLOR_DEFAULT, 0), \
+ LINE(SIGNOFF, " Signed-off-by", COLOR_YELLOW, COLOR_DEFAULT, 0), \
+ /* UI colors */ \
+ LINE(DEFAULT, "", COLOR_DEFAULT, COLOR_DEFAULT, A_NORMAL), \
+ LINE(CURSOR, "", COLOR_WHITE, COLOR_GREEN, A_BOLD), \
+ LINE(STATUS, "", COLOR_GREEN, COLOR_DEFAULT, 0), \
+ LINE(TITLE, "", COLOR_WHITE, COLOR_BLUE, A_BOLD), \
+ LINE(MAIN_DATE, "", COLOR_BLUE, COLOR_DEFAULT, 0), \
+ LINE(MAIN_AUTHOR, "", COLOR_GREEN, COLOR_DEFAULT, 0), \
+ LINE(MAIN_COMMIT, "", COLOR_DEFAULT, COLOR_DEFAULT, 0), \
+ LINE(MAIN_DELIM, "", COLOR_MAGENTA, COLOR_DEFAULT, 0),
+
enum line_type {
- LINE_DEFAULT,
- LINE_AUTHOR,
- LINE_AUTHOR_IDENT,
- LINE_COMMIT,
- LINE_COMMITTER,
- LINE_CURSOR,
- LINE_DATE,
- LINE_DIFF,
- LINE_DIFF_ADD,
- LINE_DIFF_CHUNK,
- LINE_DIFF_COPY,
- LINE_DIFF_DEL,
- LINE_DIFF_DISSIM,
- LINE_DIFF_NEWMODE,
- LINE_DIFF_OLDMODE,
- LINE_DIFF_RENAME,
- LINE_DIFF_SIM,
- LINE_DIFF_TREE,
- LINE_INDEX,
- LINE_MAIN_AUTHOR,
- LINE_MAIN_COMMIT,
- LINE_MAIN_DATE,
- LINE_MAIN_DELIM,
- LINE_MERGE,
- LINE_PARENT,
- LINE_SIGNOFF,
- LINE_STATUS,
- LINE_TITLE,
- LINE_TREE,
+#define LINE(type, line, fg, bg, attr) \
+ LINE_##type
+ LINE_INFO
+#undef LINE
};
struct line_info {
- enum line_type type;
- char *line;
- int linelen;
-
- int fg;
- int bg;
- int attr;
+ enum line_type type; /* Returned when looking up line type. */
+ char *line; /* The start of line to match. */
+ int linelen; /* Size of string to match. */
+ int fg, bg, attr; /* Color and text attributes for the lines. */
};
+static struct line_info line_info[] = {
#define LINE(type, line, fg, bg, attr) \
{ LINE_##type, (line), STRING_SIZE(line), (fg), (bg), (attr) }
-
-static struct line_info line_info[] = {
- /* Diff markup */
- LINE(DIFF, "diff --git ", COLOR_YELLOW, COLOR_DEFAULT, 0),
- LINE(INDEX, "index ", COLOR_BLUE, COLOR_DEFAULT, 0),
- LINE(DIFF_CHUNK, "@@", COLOR_MAGENTA, COLOR_DEFAULT, 0),
- LINE(DIFF_ADD, "+", COLOR_GREEN, COLOR_DEFAULT, 0),
- LINE(DIFF_DEL, "-", COLOR_RED, COLOR_DEFAULT, 0),
- LINE(DIFF_OLDMODE, "old mode ", COLOR_YELLOW, COLOR_DEFAULT, 0),
- LINE(DIFF_NEWMODE, "new mode ", COLOR_YELLOW, COLOR_DEFAULT, 0),
- LINE(DIFF_COPY, "copy ", COLOR_YELLOW, COLOR_DEFAULT, 0),
- LINE(DIFF_RENAME, "rename ", COLOR_YELLOW, COLOR_DEFAULT, 0),
- LINE(DIFF_SIM, "similarity ", COLOR_YELLOW, COLOR_DEFAULT, 0),
- LINE(DIFF_DISSIM, "dissimilarity ", COLOR_YELLOW, COLOR_DEFAULT, 0),
-
- /* Pretty print commit header */
- LINE(AUTHOR, "Author: ", COLOR_CYAN, COLOR_DEFAULT, 0),
- LINE(MERGE, "Merge: ", COLOR_BLUE, COLOR_DEFAULT, 0),
- LINE(DATE, "Date: ", COLOR_YELLOW, COLOR_DEFAULT, 0),
-
- /* Raw commit header */
- 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_IDENT, "author ", COLOR_CYAN, COLOR_DEFAULT, 0),
- LINE(COMMITTER, "committer ", COLOR_MAGENTA, COLOR_DEFAULT, 0),
-
- /* Misc */
- LINE(DIFF_TREE, "diff-tree ", COLOR_BLUE, COLOR_DEFAULT, 0),
- LINE(SIGNOFF, " Signed-off-by", COLOR_YELLOW, COLOR_DEFAULT, 0),
-
- /* UI colors */
- LINE(DEFAULT, "", COLOR_DEFAULT, COLOR_DEFAULT, A_NORMAL),
- LINE(CURSOR, "", COLOR_WHITE, COLOR_GREEN, A_BOLD),
- LINE(STATUS, "", COLOR_GREEN, COLOR_DEFAULT, 0),
- LINE(TITLE, "", COLOR_WHITE, COLOR_BLUE, A_BOLD),
- LINE(MAIN_DATE, "", COLOR_BLUE, COLOR_DEFAULT, 0),
- LINE(MAIN_AUTHOR, "", COLOR_GREEN, COLOR_DEFAULT, 0),
- LINE(MAIN_COMMIT, "", COLOR_DEFAULT, COLOR_DEFAULT, 0),
- LINE(MAIN_DELIM, "", COLOR_MAGENTA, COLOR_DEFAULT, 0),
+ LINE_INFO
+#undef LINE
};
-static struct line_info *
-get_line_info(char *line)
+static enum line_type
+get_line_type(char *line)
{
int linelen = strlen(line);
int i;
- for (i = 0; i < ARRAY_SIZE(line_info); i++) {
- if (linelen < line_info[i].linelen
- || strncasecmp(line_info[i].line, line, line_info[i].linelen))
- continue;
-
- return &line_info[i];
- }
-
- return NULL;
-}
-
-static enum line_type
-get_line_type(char *line)
-{
- struct line_info *info = get_line_info(line);
+ for (i = 0; i < ARRAY_SIZE(line_info); i++)
+ /* Case insensitive search matches Signed-off-by lines better. */
+ if (linelen >= line_info[i].linelen &&
+ !strncasecmp(line_info[i].line, line, line_info[i].linelen))
+ return line_info[i].type;
- return info ? info->type : LINE_DEFAULT;
+ return LINE_DEFAULT;
}
-static int
+static inline int
get_line_attr(enum line_type type)
{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(line_info); i++)
- if (line_info[i].type == type)
- return COLOR_PAIR(line_info[i].type) | line_info[i].attr;
-
- return A_NORMAL;
+ assert(type < ARRAY_SIZE(line_info));
+ return COLOR_PAIR(type) | line_info[type].attr;
}
static void
char *cmd;
char *id;
-
/* Rendering */
int (*read)(struct view *, char *);
int (*draw)(struct view *, unsigned int);
size_t objsize; /* Size of objects in the line index */
+ char cmdbuf[SIZEOF_CMD];
+
WINDOW *win;
int height, width;
/* Loading */
FILE *pipe;
+ time_t start_time;
};
static int pager_draw(struct view *view, unsigned int lineno);
#define MAIN_CMD \
"git log --stat --pretty=raw %s"
+#define HELP_CMD \
+ "man tig 2> /dev/null"
+
/* The status window is used for polling keystrokes. */
static WINDOW *status_win;
static WINDOW *title_win;
static unsigned int nloading;
static struct view views[] = {
- { "diff", DIFF_CMD, commit_id, pager_read, pager_draw, sizeof(char) },
- { "log", LOG_CMD, head_id, pager_read, pager_draw, sizeof(char) },
- { "main", MAIN_CMD, head_id, main_read, main_draw, sizeof(struct commit) },
+ { "main", MAIN_CMD, ref_head, main_read, main_draw, sizeof(struct commit) },
+ { "diff", DIFF_CMD, ref_commit, pager_read, pager_draw, sizeof(char) },
+ { "log", LOG_CMD, ref_head, pager_read, pager_draw, sizeof(char) },
+ { "help", HELP_CMD, ref_head, pager_read, pager_draw, sizeof(char) },
};
/* The display array of active views and the index of the current view. */
} else {
view->win = newwin(lines - 2, 0, 0, 0);
if (!view->win) {
- report("failed to create %s view", view->name);
+ report("Failed to create %s view", view->name);
return;
}
scrollok(view->win, TRUE);
}
+/*
+ * Navigation
+ */
+
/* Scrolling backend */
static void
do_scroll_view(struct view *view, int lines)
lines = view->lines - view->offset;
if (lines == 0 || view->offset + view->height >= view->lines) {
- report("already at last line");
+ report("Already at last line");
return;
}
break;
lines = view->offset;
if (lines == 0) {
- report("already at first line");
+ report("Already at first line");
return;
}
}
if (steps <= 0 && view->lineno == 0) {
- report("already at first line");
+ report("Already at first line");
return;
} else if (steps >= 0 && view->lineno + 1 == view->lines) {
- report("already at last line");
+ report("Already at last line");
return;
}
assert(0 <= view->lineno && view->lineno < view->lines);
/* Repaint the old "current" line if we be scrolling */
- if (ABS(steps) < view->height)
+ if (ABS(steps) < view->height) {
+ int prev_lineno = view->lineno - steps - view->offset;
+
+ wmove(view->win, prev_lineno, 0);
+ wclrtoeol(view->win);
view->draw(view, view->lineno - steps - view->offset);
+ }
/* Check whether the view needs to be scrolled */
if (view->lineno < view->offset ||
}
+/*
+ * Incremental updating
+ */
static bool
begin_update(struct view *view)
{
- char buf[1024];
-
- if (view->cmd) {
- char *id = view->id;
+ char *id = view->id;
- if (snprintf(buf, sizeof(buf), view->cmd, id, id, id) < sizeof(buf))
- view->pipe = popen(buf, "r");
-
- if (!view->pipe)
- return FALSE;
+ if (snprintf(view->cmdbuf, sizeof(view->cmdbuf), view->cmd,
+ id, id, id) < sizeof(view->cmdbuf))
+ view->pipe = popen(view->cmdbuf, "r");
- if (nloading++ == 0)
- nodelay(status_win, TRUE);
- }
+ if (!view->pipe)
+ return FALSE;
- display[current_view] = view;
+ if (nloading++ == 0)
+ nodelay(status_win, TRUE);
view->offset = 0;
view->lines = 0;
view->lineno = 0;
+ if (view->line) {
+ int i;
+
+ for (i = 0; i < view->lines; i++)
+ if (view->line[i])
+ free(view->line[i]);
+
+ free(view->line);
+ view->line = NULL;
+ }
+
+ view->start_time = time(NULL);
+
return TRUE;
}
static void
end_update(struct view *view)
{
- wattrset(view->win, A_NORMAL);
- pclose(view->pipe);
- view->pipe = NULL;
-
if (nloading-- == 1)
nodelay(status_win, FALSE);
+
+ pclose(view->pipe);
+ view->pipe = NULL;
}
static int
}
if (ferror(view->pipe)) {
- report("failed to read %s: %s", view->cmd, strerror(errno));
+ report("Failed to read %s: %s", view->cmd, strerror(errno));
goto end;
} else if (feof(view->pipe)) {
- report("loaded %d lines", view->lines);
+ time_t secs = time(NULL) - view->start_time;
+
+ if (view == &views[REQ_VIEW_HELP]){
+ report(HELP);
+ goto end;
+ }
+
+ report("Loaded %d lines in %ld second%s", view->lines, secs,
+ secs == 1 ? "" : "s");
goto end;
}
return TRUE;
alloc_error:
- report("allocation failure");
+ report("Allocation failure");
end:
end_update(view);
return FALSE;
}
-
static struct view *
switch_view(struct view *prev, int request)
{
struct view *displayed;
int i;
+ if (prev && prev->pipe)
+ end_update(prev);
+
if (view == prev) {
foreach_view (displayed, i) ;
if (i == 1)
- report("already in %s view", view->name);
+ report("Already in %s view", view->name);
else
report("FIXME: Maximize");
/* Reload */
- if (view->line) {
- for (i = 0; i < view->lines; i++)
- if (view->line[i])
- free(view->line[i]);
-
- free(view->line);
- view->line = NULL;
- }
-
- if (prev && prev->pipe)
- end_update(prev);
-
if (begin_update(view)) {
- if (!view->cmd) {
- report("%s", HELP);
- } else {
- /* Clear the old view and let the incremental updating
- * refill the screen. */
- wclear(view->win);
- report("loading...");
- }
+ /* Clear the old view and let the incremental updating refill
+ * the screen. */
+ display[current_view] = view;
+ wclear(view->win);
+ report("Loading...");
}
return view;
break;
case REQ_VIEW_MAIN:
- case REQ_VIEW_LOG:
case REQ_VIEW_DIFF:
+ case REQ_VIEW_LOG:
+ case REQ_VIEW_HELP:
view = switch_view(view, request);
break;
break;
case REQ_STOP_LOADING:
- foreach_view (view, i) {
- if (view->pipe) {
+ foreach_view (view, i)
+ if (view->pipe)
end_update(view);
- //scroll_view(view, 0);
- }
- }
break;
case REQ_SHOW_VERSION:
- report("version %s", VERSION);
+ report("Version: %s", VERSION);
return TRUE;
case REQ_SCREEN_REDRAW:
return FALSE;
default:
+ /* An unknown key will show most commonly used commands. */
report(HELP);
return TRUE;
}
if (view->offset + lineno == view->lineno) {
if (type == LINE_COMMIT)
- string_copy(commit_id, line + 7);
+ string_copy(ref_commit, line + 7);
type = LINE_CURSOR;
}
unsigned int real_lineno = view->offset + lineno + 1;
int col = 1;
- if (real_lineno == 1 || (real_lineno % NUMBER_INTERVAL) == 0)
+ if (real_lineno == 1 || (real_lineno % opt_num_interval) == 0)
mvwprintw(view->win, lineno, 0, "%4d: ", real_lineno);
else
mvwaddstr(view->win, lineno, 0, " : ");
waddstr(view->win, line);
} else {
+#if 0
+ /* NOTE: Code for only highlighting the text on the cursor line.
+ * Kept since I've not yet decided whether to highlight the
+ * entire line or not. --fonseca */
/* No empty lines makes cursor drawing and clearing implicit. */
if (!*line)
line = " ", linelen = 1;
+#endif
mvwaddnstr(view->win, lineno, 0, line, linelen);
}
+ /* Paint the rest of the line if it's the cursor line. */
+ if (type == LINE_CURSOR)
+ wchgat(view->win, -1, 0, type, NULL);
+
return TRUE;
}
static int
main_draw(struct view *view, unsigned int lineno)
{
- char buf[21];
+ char buf[DATE_COLS + 1];
struct commit *commit;
enum line_type type;
int cols = 0;
return FALSE;
if (view->offset + lineno == view->lineno) {
- string_copy(commit_id, commit->id);
+ string_copy(ref_commit, commit->id);
type = LINE_CURSOR;
} else {
type = LINE_MAIN_COMMIT;
break;
}
default:
- /* Fill in the commit title */
+ /* We should only ever end up here if there has already been a
+ * commit line, however, be safe. */
+ if (view->lines == 0)
+ break;
+
+ /* Fill in the commit title if it has not already been set. */
commit = view->line[view->lines - 1];
- if (commit->title[0] ||
- strncmp(line, " ", 4) ||
+ if (commit->title[0])
+ break;
+
+ /* Require titles to start with a non-space character at the
+ * offset used by git log. */
+ if (strncmp(line, " ", 4) ||
isspace(line[5]))
break;
{
struct view *view = display[current_view];
+ assert(view);
+
werase(title_win);
wmove(title_win, 0, 0);
- if (view) {
- /* [main] ref: 334b506... - line 6 of 4383 (0%) */
- wprintw(title_win, "[%s] ref: %s", view->name, commit_id);
-
- if (view->lines) {
- wprintw(title_win, " - line %d of %d (%d%%)",
- view->lineno + 1,
- view->lines,
- view->lines ? (view->lineno + 1) * 100 / view->lines : 0);
- }
- } else {
- wprintw(title_win, "commit %s", commit_id);
+
+ /* [main] ref: 334b506... - line 6 of 4383 (0%) */
+ wprintw(title_win, "[%s] ref: %s", view->name, ref_commit);
+ if (view->lines) {
+ wprintw(title_win, " - line %d of %d (%d%%)",
+ view->lineno + 1,
+ view->lines,
+ (view->lineno + 1) * 100 / view->lines);
}
+
wrefresh(title_win);
}
-/* Status and title window updater. */
+/* Update status and title window. */
static void
report(const char *msg, ...)
{
va_start(args, msg);
+ /* Update the title window first, so the cursor ends up in the status
+ * window. */
update_title();
werase(status_win);
wmove(status_win, 0, 0);
-
-#if 0
- if (display[current_view])
- wprintw(status_win, "%s %4s: ", commit_id, display[current_view]->name);
-#endif
vwprintw(status_win, msg, args);
wrefresh(status_win);
if (git_cmd < 0)
return 0;
if (git_cmd < argc) {
- die("opts");
+ die("Too many options");
}
request = opt_request;
- initscr(); /* initialize the curses library */
- nonl(); /* tell curses not to do NL->CR/NL on output */
- cbreak(); /* take input chars one at a time, no wait for \n */
- noecho(); /* don't echo input */
+ initscr(); /* Initialize the curses library */
+ nonl(); /* Tell curses not to do NL->CR/NL on output */
+ cbreak(); /* Take input chars one at a time, no wait for \n */
+ noecho(); /* Don't echo input */
leaveok(stdscr, TRUE);
- /* curs_set(0); */
if (has_colors())
init_colors();