From 7282cb4be8fa742e87b14a5c530eaf67dc72e2f0 Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Sun, 18 Jul 2010 13:07:49 +0200 Subject: [PATCH] Implemented incremental search --- cm.c | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 129 insertions(+), 11 deletions(-) diff --git a/cm.c b/cm.c index 12ff25e..2d8c6ce 100644 --- a/cm.c +++ b/cm.c @@ -744,15 +744,19 @@ static void x11_cleanup(void) { } static int cursor_at, cursor_max; +static unsigned is_active, is_pos; // incremental search +static char is_buf[64]; + enum { M_IDLE, M_SCAN, M_NEW, M_FLAG, M_BAD, + M_INCSEARCH, M_MAX }; -static int attrs[2][2][M_MAX]; // active, hilite, status +static int attrs[3][2][M_MAX]; // active (2=incsearch), hilite, status static void redraw_line(int i) @@ -761,8 +765,10 @@ redraw_line(int i) if (i < cursor_max) { struct mbox *b = mbox_array[i]; - int cc = (cursor_at == i); + int cc = (cursor_at == i ? (is_active ? 2 : 1) : 0); int hi = b->o.highlight; + unsigned namepos = 0; + unsigned namelen = strlen(b->name); attrset(attrs[cc][hi][M_IDLE]); if (b->o.hotkey) @@ -771,11 +777,22 @@ redraw_line(int i) printw("> "); else printw(" "); + if (cc == 2) + { + attrset(attrs[cc][hi][M_INCSEARCH]); + for (namepos=0; namepos < is_pos && namepos < 20; namepos++) + addch(is_buf[namepos]); + } if (b->new) attrset(attrs[cc][hi][M_NEW]); else if (b->flagged && b->o.show_flagged) attrset(attrs[cc][hi][M_FLAG]); - printw("%-20s ", b->name); + else + attrset(attrs[cc][hi][M_IDLE]); + while (namepos < namelen) + addch(b->name[namepos++]); + while (namepos++ < 20) + addch(' '); if (b->scanning < 0) ; else if (b->scanning) @@ -915,20 +932,31 @@ term_init(void) curs_set(0); static const int attrs_mono[2][M_MAX] = { - [0] = { [M_IDLE] = 0, [M_SCAN] = A_BOLD, [M_NEW] = A_BOLD, [M_FLAG] = 0, [M_BAD] = A_DIM }, - [1] = { [M_IDLE] = 0, [M_SCAN] = A_BOLD, [M_NEW] = A_REVERSE | A_BOLD, [M_FLAG] = A_REVERSE, [M_BAD] = A_DIM }, + [0] = { [M_IDLE] = 0, + [M_SCAN] = A_BOLD, + [M_NEW] = A_BOLD, + [M_FLAG] = 0, + [M_BAD] = A_DIM, + [M_INCSEARCH] = A_REVERSE }, + [1] = { [M_IDLE] = 0, + [M_SCAN] = A_BOLD, + [M_NEW] = A_REVERSE | A_BOLD, + [M_FLAG] = A_REVERSE, + [M_BAD] = A_DIM, + [M_INCSEARCH] = A_REVERSE }, }; for (int i=0; i<2; i++) for (int j=0; j= 5) + if (COLOR_PAIRS >= 12) { init_pair(1, COLOR_YELLOW, COLOR_BLACK); init_pair(2, COLOR_RED, COLOR_BLACK); @@ -937,11 +965,44 @@ term_init(void) init_pair(5, COLOR_RED, COLOR_BLUE); init_pair(6, COLOR_GREEN, COLOR_BLACK); init_pair(7, COLOR_GREEN, COLOR_BLUE); - static const int attrs_color[2][2][M_MAX] = { - [0][0] = { [M_IDLE] = 0, [M_SCAN] = COLOR_PAIR(1), [M_NEW] = COLOR_PAIR(1), [M_FLAG] = COLOR_PAIR(6), [M_BAD] = COLOR_PAIR(2) }, - [0][1] = { [M_IDLE] = A_BOLD, [M_SCAN] = COLOR_PAIR(1), [M_NEW] = COLOR_PAIR(1) | A_BOLD, [M_FLAG] = COLOR_PAIR(6) | A_BOLD, [M_BAD] = COLOR_PAIR(2) | A_BOLD }, - [1][0] = { [M_IDLE] = COLOR_PAIR(3), [M_SCAN] = COLOR_PAIR(4), [M_NEW] = COLOR_PAIR(4), [M_FLAG] = COLOR_PAIR(7), [M_BAD] = COLOR_PAIR(5) }, - [1][1] = { [M_IDLE] = COLOR_PAIR(3) | A_BOLD, [M_SCAN] = COLOR_PAIR(4), [M_NEW] = COLOR_PAIR(4) | A_BOLD, [M_FLAG] = COLOR_PAIR(7) | A_BOLD, [M_BAD] = COLOR_PAIR(5) | A_BOLD }, + init_pair(8, COLOR_WHITE, COLOR_MAGENTA); + init_pair(9, COLOR_YELLOW, COLOR_MAGENTA); + init_pair(10, COLOR_GREEN, COLOR_MAGENTA); + init_pair(11, COLOR_RED, COLOR_MAGENTA); + init_pair(12, COLOR_BLACK, COLOR_YELLOW); + static const int attrs_color[3][2][M_MAX] = { + [0][0] = { [M_IDLE] = 0, + [M_SCAN] = COLOR_PAIR(1), + [M_NEW] = COLOR_PAIR(1), + [M_FLAG] = COLOR_PAIR(6), + [M_BAD] = COLOR_PAIR(2) }, + [0][1] = { [M_IDLE] = A_BOLD, + [M_SCAN] = COLOR_PAIR(1), + [M_NEW] = COLOR_PAIR(1) | A_BOLD, + [M_FLAG] = COLOR_PAIR(6) | A_BOLD, + [M_BAD] = COLOR_PAIR(2) | A_BOLD }, + [1][0] = { [M_IDLE] = COLOR_PAIR(3), + [M_SCAN] = COLOR_PAIR(4), + [M_NEW] = COLOR_PAIR(4), + [M_FLAG] = COLOR_PAIR(7), + [M_BAD] = COLOR_PAIR(5) }, + [1][1] = { [M_IDLE] = COLOR_PAIR(3) | A_BOLD, + [M_SCAN] = COLOR_PAIR(4), + [M_NEW] = COLOR_PAIR(4) | A_BOLD, + [M_FLAG] = COLOR_PAIR(7) | A_BOLD, + [M_BAD] = COLOR_PAIR(5) | A_BOLD }, + [2][0] = { [M_IDLE] = COLOR_PAIR(8), + [M_SCAN] = COLOR_PAIR(9), + [M_NEW] = COLOR_PAIR(9), + [M_FLAG] = COLOR_PAIR(10), + [M_BAD] = COLOR_PAIR(11), + [M_INCSEARCH] = COLOR_PAIR(12) | A_DIM }, + [2][1] = { [M_IDLE] = COLOR_PAIR(8) | A_BOLD, + [M_SCAN] = COLOR_PAIR(9), + [M_NEW] = COLOR_PAIR(9) | A_BOLD, + [M_FLAG] = COLOR_PAIR(10) | A_BOLD, + [M_BAD] = COLOR_PAIR(11) | A_BOLD, + [M_INCSEARCH] = COLOR_PAIR(12) }, }; memcpy(attrs, attrs_color, sizeof(attrs)); } @@ -1023,6 +1084,53 @@ mbox_run(struct mbox *b) scan_and_redraw(); } +static void +enter_incsearch(void) +{ + print_status("Incremental search..."); + is_active = 1; + is_pos = 0; + redraw_line(cursor_at); +} + +static int +handle_incsearch(int ch) +{ + if ((ch == KEY_BACKSPACE || ch == KEY_DC) && is_pos) + --is_pos; + else if (ch >= ' ' && ch <= '~') + { + if (is_pos < sizeof(is_buf) - 1) + is_buf[is_pos++] = ch; + } + else + { + print_status(""); + is_active = 0; + is_pos = 0; + redraw_line(cursor_at); + return 0; + } + + is_buf[is_pos] = 0; + for (int i=0; iname, is_buf, is_pos)) + { + if (i != cursor_at) + { + move_cursor(i); + return 1; + } + break; + } + } + + redraw_line(cursor_at); + return 1; +} + #define STR2(c) #c #define STR(c) STR2(c) @@ -1186,6 +1294,13 @@ restart: remains *= 10; halfdelay((remains > 255) ? 255 : remains); int ch = getch(); + if (ch < 0) + continue; + if (is_active && handle_incsearch(ch)) + { + refresh(); + continue; + } for (int i=0; io.hotkey) { @@ -1252,6 +1367,9 @@ restart: allow_osd = 0; print_status("On-screen display is now disabled. Watch your step."); break; + case '/': + enter_incsearch(); + break; default: if (ch >= '0' && ch <= '9') { -- 2.39.2