Add window levels, status bar, UTF-8 input, charset conversion
- Isolated window levels with 500-line scrollback per window - Window 1: status + private messages - Windows 2-9: channels - Status bar showing window, channel, nick prefix, channel modes - Automatic charset conversion (UTF-8/UTF-16 -> ISO-8859-1 on wire) - UTF-8 aware input editing with Ctrl-A/E/U/K/Y - CTCP VERSION reply with real OS info from uname() - Real name from passwd GECOS field - SIGWINCH handling for terminal resize - Ctrl-C quit confirmation (y + Enter) - /whois, /wii, /mode, /quit with default reason - Green prompt, timestamps on all messages
This commit is contained in:
@@ -21,12 +21,12 @@
|
||||
#define BUF_SIZE 4096
|
||||
#define IRC_MAX 512
|
||||
|
||||
/* Window levels: 0=status, 1=msg, 2-8=channels */
|
||||
/* Window levels: 0=status+msg, 1-7=channels */
|
||||
#define WL_STATUS 0
|
||||
#define WL_MSG 1
|
||||
#define WL_CHAN 2
|
||||
#define WL_MSG 0
|
||||
#define WL_CHAN 1
|
||||
#define WL_MAX 9
|
||||
#define MAX_CHAN_WINS 7
|
||||
#define MAX_CHAN_WINS 8
|
||||
#define SCROLLBACK 500
|
||||
|
||||
static int current_level = WL_STATUS;
|
||||
@@ -70,7 +70,8 @@ static const char *current_channel(void)
|
||||
{
|
||||
if (current_level >= WL_CHAN && current_level < WL_MAX) {
|
||||
int idx = current_level - WL_CHAN;
|
||||
return win_chans[idx].name;
|
||||
if (idx < MAX_CHAN_WINS)
|
||||
return win_chans[idx].name;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
@@ -101,16 +102,13 @@ static void draw_statusbar(void)
|
||||
if (win_chans[idx].my_prefix)
|
||||
snprintf(prefix_str, sizeof(prefix_str), "%c",
|
||||
win_chans[idx].my_prefix);
|
||||
} else if (current_level == WL_MSG) {
|
||||
chan = "(messages)";
|
||||
} else {
|
||||
chan = "(status)";
|
||||
}
|
||||
|
||||
snprintf(bar, sizeof(bar), " [%d:%s] %s%s %s%s%s",
|
||||
current_level + 1,
|
||||
current_level == WL_STATUS ? "status" :
|
||||
current_level == WL_MSG ? "msg" : chan,
|
||||
current_level == WL_STATUS ? "status" : chan,
|
||||
prefix_str, nick,
|
||||
cmodes[0] ? "[" : "", cmodes, cmodes[0] ? "]" : "");
|
||||
|
||||
@@ -698,7 +696,7 @@ static void redraw_input(const char *input_line, size_t input_len,
|
||||
size_t input_pos)
|
||||
{
|
||||
size_t cpos_cols = display_cols(input_line, input_pos);
|
||||
printf("\033[%d;1H\033[K> ", term_rows);
|
||||
printf("\033[%d;1H\033[K\033[32m>\033[0m ", term_rows);
|
||||
fwrite(input_line, 1, input_len, stdout);
|
||||
printf("\033[%d;%dH", term_rows, (int)(cpos_cols + 3));
|
||||
fflush(stdout);
|
||||
@@ -797,9 +795,28 @@ int main(int argc, char *argv[])
|
||||
printf("\033[%d;1H\033[KWanna quit? [y/N] ",
|
||||
term_rows);
|
||||
fflush(stdout);
|
||||
unsigned char ans;
|
||||
ssize_t r = read(STDIN_FILENO, &ans, 1);
|
||||
if (r > 0 && (ans == 'y' || ans == 'Y')) {
|
||||
char qbuf[16];
|
||||
size_t qpos = 0;
|
||||
int quit = 0;
|
||||
for (;;) {
|
||||
unsigned char qch;
|
||||
ssize_t r = read(STDIN_FILENO, &qch, 1);
|
||||
if (r <= 0) break;
|
||||
if (qch == '\r' || qch == '\n') {
|
||||
quit = (qpos > 0 &&
|
||||
(qbuf[0] == 'y' || qbuf[0] == 'Y'));
|
||||
break;
|
||||
} else if ((qch == 127 || qch == 0x08) && qpos > 0) {
|
||||
qpos--;
|
||||
printf("\b \b");
|
||||
fflush(stdout);
|
||||
} else if (qch >= 32 && qpos < sizeof(qbuf) - 1) {
|
||||
qbuf[qpos++] = qch;
|
||||
ssize_t w = write(STDOUT_FILENO, &qch, 1);
|
||||
(void)w;
|
||||
}
|
||||
}
|
||||
if (quit) {
|
||||
irc_send_raw("QUIT :Leaving");
|
||||
break;
|
||||
}
|
||||
@@ -843,6 +860,7 @@ int main(int argc, char *argv[])
|
||||
if (lvl < WL_MAX) {
|
||||
current_level = lvl;
|
||||
redraw_window();
|
||||
redraw_input(input_line, input_len, input_pos);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -857,7 +875,7 @@ int main(int argc, char *argv[])
|
||||
handle_input(input_line);
|
||||
input_pos = 0;
|
||||
input_len = 0;
|
||||
printf("\033[%d;1H> ", term_rows);
|
||||
printf("\033[%d;1H\033[32m>\033[0m ", term_rows);
|
||||
fflush(stdout);
|
||||
} else if (ch == 0x01) {
|
||||
/* Ctrl-A: beginning of line */
|
||||
|
||||
Reference in New Issue
Block a user