edit.c revision 1f69aa52ea2e0a73ac502565df8c666ee49cab6a
18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Command line editing and history
31f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * Copyright (c) 2010-2011, Jouni Malinen <j@w1.fi>
48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
58d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This program is free software; you can redistribute it and/or modify
68d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * it under the terms of the GNU General Public License version 2 as
78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * published by the Free Software Foundation.
88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Alternatively, this software may be distributed under the terms of BSD
108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * license.
118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * See README and COPYING for more details.
138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h"
168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <termios.h>
178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h"
198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eloop.h"
208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "list.h"
218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "edit.h"
228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define CMD_BUF_LEN 256
248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic char cmdbuf[CMD_BUF_LEN];
258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int cmdbuf_pos = 0;
268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int cmdbuf_len = 0;
271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic char currbuf[CMD_BUF_LEN];
281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic int currbuf_valid = 0;
298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define HISTORY_MAX 100
318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct edit_history {
338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct dl_list list;
348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char str[1];
358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct dl_list history_list;
388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct edit_history *history_curr;
398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void *edit_cb_ctx;
418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void (*edit_cmd_cb)(void *ctx, char *cmd);
428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void (*edit_eof_cb)(void *ctx);
438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic char ** (*edit_completion_cb)(void *ctx, const char *cmd, int pos) =
448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	NULL;
458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct termios prevt, newt;
478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define CLEAR_END_LINE "\e[K"
508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid edit_clear_line(void)
538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int i;
558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	putchar('\r');
568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < cmdbuf_len + 2; i++)
578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		putchar(' ');
588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void move_start(void)
628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	cmdbuf_pos = 0;
648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	edit_redraw();
658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void move_end(void)
698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	cmdbuf_pos = cmdbuf_len;
718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	edit_redraw();
728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void move_left(void)
768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (cmdbuf_pos > 0) {
788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		cmdbuf_pos--;
798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		edit_redraw();
808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void move_right(void)
858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (cmdbuf_pos < cmdbuf_len) {
878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		cmdbuf_pos++;
888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		edit_redraw();
898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void move_word_left(void)
948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (cmdbuf_pos > 0 && cmdbuf[cmdbuf_pos - 1] == ' ')
968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		cmdbuf_pos--;
978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (cmdbuf_pos > 0 && cmdbuf[cmdbuf_pos - 1] != ' ')
988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		cmdbuf_pos--;
998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	edit_redraw();
1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void move_word_right(void)
1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (cmdbuf_pos < cmdbuf_len && cmdbuf[cmdbuf_pos] == ' ')
1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		cmdbuf_pos++;
1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (cmdbuf_pos < cmdbuf_len && cmdbuf[cmdbuf_pos] != ' ')
1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		cmdbuf_pos++;
1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	edit_redraw();
1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void delete_left(void)
1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (cmdbuf_pos == 0)
1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	edit_clear_line();
1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memmove(cmdbuf + cmdbuf_pos - 1, cmdbuf + cmdbuf_pos,
1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   cmdbuf_len - cmdbuf_pos);
1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	cmdbuf_pos--;
1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	cmdbuf_len--;
1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	edit_redraw();
1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void delete_current(void)
1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (cmdbuf_pos == cmdbuf_len)
1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	edit_clear_line();
1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memmove(cmdbuf + cmdbuf_pos, cmdbuf + cmdbuf_pos + 1,
1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   cmdbuf_len - cmdbuf_pos);
1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	cmdbuf_len--;
1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	edit_redraw();
1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void delete_word(void)
1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int pos;
1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	edit_clear_line();
1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = cmdbuf_pos;
1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (pos > 0 && cmdbuf[pos - 1] == ' ')
1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos--;
1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (pos > 0 && cmdbuf[pos - 1] != ' ')
1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos--;
1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memmove(cmdbuf + pos, cmdbuf + cmdbuf_pos, cmdbuf_len - cmdbuf_pos);
1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	cmdbuf_len -= cmdbuf_pos - pos;
1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	cmdbuf_pos = pos;
1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	edit_redraw();
1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void clear_left(void)
1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (cmdbuf_pos == 0)
1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	edit_clear_line();
1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memmove(cmdbuf, cmdbuf + cmdbuf_pos, cmdbuf_len - cmdbuf_pos);
1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	cmdbuf_len -= cmdbuf_pos;
1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	cmdbuf_pos = 0;
1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	edit_redraw();
1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void clear_right(void)
1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (cmdbuf_pos == cmdbuf_len)
1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	edit_clear_line();
1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	cmdbuf_len = cmdbuf_pos;
1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	edit_redraw();
1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void history_add(const char *str)
1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct edit_history *h, *match = NULL, *last = NULL;
1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t len, count = 0;
1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (str[0] == '\0')
1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dl_list_for_each(h, &history_list, struct edit_history, list) {
1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (os_strcmp(str, h->str) == 0) {
1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			match = h;
1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		last = h;
1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		count++;
1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (match) {
1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		dl_list_del(&h->list);
2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		dl_list_add(&history_list, &h->list);
2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		history_curr = h;
2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (count >= HISTORY_MAX && last) {
2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		dl_list_del(&last->list);
2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(last);
2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	len = os_strlen(str);
2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	h = os_zalloc(sizeof(*h) + len);
2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (h == NULL)
2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dl_list_add(&history_list, &h->list);
2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_strlcpy(h->str, str, len + 1);
2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	history_curr = h;
2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void history_use(void)
2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	edit_clear_line();
2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	cmdbuf_len = cmdbuf_pos = os_strlen(history_curr->str);
2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(cmdbuf, history_curr->str, cmdbuf_len);
2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	edit_redraw();
2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void history_prev(void)
2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (history_curr == NULL)
2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (history_curr ==
2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    dl_list_first(&history_list, struct edit_history, list)) {
2361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (!currbuf_valid) {
2371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			cmdbuf[cmdbuf_len] = '\0';
2381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			os_memcpy(currbuf, cmdbuf, cmdbuf_len + 1);
2391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			currbuf_valid = 1;
2401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			history_use();
2411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			return;
2421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		}
2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (history_curr ==
2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    dl_list_last(&history_list, struct edit_history, list))
2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	history_curr = dl_list_entry(history_curr->list.next,
2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     struct edit_history, list);
2511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	history_use();
2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void history_next(void)
2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (history_curr == NULL ||
2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    history_curr ==
2591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	    dl_list_first(&history_list, struct edit_history, list)) {
2601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (currbuf_valid) {
2611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			currbuf_valid = 0;
2621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			edit_clear_line();
2631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			cmdbuf_len = cmdbuf_pos = os_strlen(currbuf);
2641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			os_memcpy(cmdbuf, currbuf, cmdbuf_len);
2651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			edit_redraw();
2661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		}
2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
2681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	history_curr = dl_list_entry(history_curr->list.prev,
2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     struct edit_history, list);
2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	history_use();
2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void history_read(const char *fname)
2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	FILE *f;
2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char buf[CMD_BUF_LEN], *pos;
2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	f = fopen(fname, "r");
2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (f == NULL)
2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (fgets(buf, CMD_BUF_LEN, f)) {
2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		for (pos = buf; *pos; pos++) {
2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (*pos == '\r' || *pos == '\n') {
2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				*pos = '\0';
2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				break;
2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		history_add(buf);
2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	fclose(f);
2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void history_write(const char *fname,
3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  int (*filter_cb)(void *ctx, const char *cmd))
3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	FILE *f;
3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct edit_history *h;
3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	f = fopen(fname, "w");
3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (f == NULL)
3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dl_list_for_each_reverse(h, &history_list, struct edit_history, list) {
3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (filter_cb && filter_cb(edit_cb_ctx, h->str))
3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		fprintf(f, "%s\n", h->str);
3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	fclose(f);
3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void history_debug_dump(void)
3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct edit_history *h;
3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	edit_clear_line();
3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	printf("\r");
3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dl_list_for_each_reverse(h, &history_list, struct edit_history, list)
3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		printf("%s%s\n", h == history_curr ? "[C]" : "", h->str);
3261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (currbuf_valid)
3271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		printf("{%s}\n", currbuf);
3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	edit_redraw();
3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void insert_char(int c)
3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (cmdbuf_len >= (int) sizeof(cmdbuf) - 1)
3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (cmdbuf_len == cmdbuf_pos) {
3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		cmdbuf[cmdbuf_pos++] = c;
3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		cmdbuf_len++;
3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		putchar(c);
3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		fflush(stdout);
3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memmove(cmdbuf + cmdbuf_pos + 1, cmdbuf + cmdbuf_pos,
3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   cmdbuf_len - cmdbuf_pos);
3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		cmdbuf[cmdbuf_pos++] = c;
3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		cmdbuf_len++;
3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		edit_redraw();
3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void process_cmd(void)
3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (cmdbuf_len == 0) {
3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		printf("\n> ");
3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		fflush(stdout);
3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	printf("\n");
3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	cmdbuf[cmdbuf_len] = '\0';
3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	history_add(cmdbuf);
3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	cmdbuf_pos = 0;
3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	cmdbuf_len = 0;
3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	edit_cmd_cb(edit_cb_ctx, cmdbuf);
3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	printf("> ");
3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	fflush(stdout);
3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void free_completions(char **c)
3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int i;
3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (c == NULL)
3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; c[i]; i++)
3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(c[i]);
3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(c);
3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int filter_strings(char **c, char *str, size_t len)
3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int i, j;
3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0, j = 0; c[j]; j++) {
3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (os_strncasecmp(c[j], str, len) == 0) {
3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (i != j) {
3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				c[i] = c[j];
3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				c[j] = NULL;
3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			i++;
3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else {
3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(c[j]);
3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			c[j] = NULL;
3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	c[i] = NULL;
3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return i;
3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int common_len(const char *a, const char *b)
4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int len = 0;
4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (a[len] && a[len] == b[len])
4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		len++;
4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return len;
4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int max_common_length(char **c)
4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int len, i;
4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	len = os_strlen(c[0]);
4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 1; c[i]; i++) {
4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		int same = common_len(c[0], c[i]);
4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (same < len)
4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			len = same;
4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return len;
4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int cmp_str(const void *a, const void *b)
4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return os_strcmp(* (const char **) a, * (const char **) b);
4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void complete(int list)
4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char **c;
4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int i, len, count;
4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int start, end;
4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int room, plen, add_space;
4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (edit_completion_cb == NULL)
4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	cmdbuf[cmdbuf_len] = '\0';
4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	c = edit_completion_cb(edit_cb_ctx, cmdbuf, cmdbuf_pos);
4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (c == NULL)
4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	end = cmdbuf_pos;
4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	start = end;
4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (start > 0 && cmdbuf[start - 1] != ' ')
4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		start--;
4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	plen = end - start;
4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	count = filter_strings(c, &cmdbuf[start], plen);
4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (count == 0) {
4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		free_completions(c);
4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	len = max_common_length(c);
4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (len <= plen && count > 1) {
4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (list) {
4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			qsort(c, count, sizeof(char *), cmp_str);
4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			edit_clear_line();
4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			printf("\r");
4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			for (i = 0; c[i]; i++)
4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				printf("%s%s", i > 0 ? " " : "", c[i]);
4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			printf("\n");
4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			edit_redraw();
4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		free_completions(c);
4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	len -= plen;
4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	room = sizeof(cmdbuf) - 1 - cmdbuf_len;
4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (room < len)
4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		len = room;
4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	add_space = count == 1 && len < room;
4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memmove(cmdbuf + cmdbuf_pos + len + add_space, cmdbuf + cmdbuf_pos,
4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   cmdbuf_len - cmdbuf_pos);
4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(&cmdbuf[cmdbuf_pos - plen], c[0], plen + len);
4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (add_space)
4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		cmdbuf[cmdbuf_pos + len] = ' ';
4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	cmdbuf_pos += len + add_space;
4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	cmdbuf_len += len + add_space;
4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	edit_redraw();
4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	free_completions(c);
4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtenum edit_key_code {
4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_NONE = 256,
4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_TAB,
4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_UP,
4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_DOWN,
4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_RIGHT,
5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_LEFT,
5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_ENTER,
5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_BACKSPACE,
5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_INSERT,
5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_DELETE,
5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_HOME,
5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_END,
5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_PAGE_UP,
5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_PAGE_DOWN,
5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_F1,
5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_F2,
5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_F3,
5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_F4,
5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_F5,
5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_F6,
5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_F7,
5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_F8,
5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_F9,
5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_F10,
5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_F11,
5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_F12,
5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_CTRL_UP,
5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_CTRL_DOWN,
5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_CTRL_RIGHT,
5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_CTRL_LEFT,
5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_CTRL_A,
5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_CTRL_B,
5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_CTRL_D,
5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_CTRL_E,
5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_CTRL_F,
5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_CTRL_G,
5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_CTRL_H,
5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_CTRL_J,
5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_CTRL_K,
5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_CTRL_L,
5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_CTRL_N,
5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_CTRL_O,
5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_CTRL_P,
5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_CTRL_R,
5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_CTRL_T,
5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_CTRL_U,
5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_CTRL_V,
5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_CTRL_W,
5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_ALT_UP,
5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_ALT_DOWN,
5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_ALT_RIGHT,
5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_ALT_LEFT,
5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_SHIFT_UP,
5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_SHIFT_DOWN,
5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_SHIFT_RIGHT,
5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_SHIFT_LEFT,
5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_ALT_SHIFT_UP,
5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_ALT_SHIFT_DOWN,
5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_ALT_SHIFT_RIGHT,
5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_ALT_SHIFT_LEFT,
5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	EDIT_KEY_EOF
5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void show_esc_buf(const char *esc_buf, char c, int i)
5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	edit_clear_line();
5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	printf("\rESC buffer '%s' c='%c' [%d]\n", esc_buf, c, i);
5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	edit_redraw();
5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic enum edit_key_code esc_seq_to_key1_no(char last)
5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	switch (last) {
5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 'A':
5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_UP;
5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 'B':
5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_DOWN;
5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 'C':
5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_RIGHT;
5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 'D':
5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_LEFT;
5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	default:
5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_NONE;
5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic enum edit_key_code esc_seq_to_key1_shift(char last)
5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	switch (last) {
5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 'A':
5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_SHIFT_UP;
5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 'B':
5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_SHIFT_DOWN;
5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 'C':
5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_SHIFT_RIGHT;
5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 'D':
5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_SHIFT_LEFT;
5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	default:
5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_NONE;
5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic enum edit_key_code esc_seq_to_key1_alt(char last)
6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	switch (last) {
6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 'A':
6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_ALT_UP;
6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 'B':
6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_ALT_DOWN;
6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 'C':
6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_ALT_RIGHT;
6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 'D':
6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_ALT_LEFT;
6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	default:
6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_NONE;
6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic enum edit_key_code esc_seq_to_key1_alt_shift(char last)
6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	switch (last) {
6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 'A':
6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_ALT_SHIFT_UP;
6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 'B':
6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_ALT_SHIFT_DOWN;
6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 'C':
6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_ALT_SHIFT_RIGHT;
6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 'D':
6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_ALT_SHIFT_LEFT;
6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	default:
6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_NONE;
6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic enum edit_key_code esc_seq_to_key1_ctrl(char last)
6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	switch (last) {
6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 'A':
6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_CTRL_UP;
6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 'B':
6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_CTRL_DOWN;
6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 'C':
6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_CTRL_RIGHT;
6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 'D':
6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_CTRL_LEFT;
6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	default:
6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_NONE;
6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic enum edit_key_code esc_seq_to_key1(int param1, int param2, char last)
6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* ESC-[<param1>;<param2><last> */
6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (param1 < 0 && param2 < 0)
6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return esc_seq_to_key1_no(last);
6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (param1 == 1 && param2 == 2)
6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return esc_seq_to_key1_shift(last);
6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (param1 == 1 && param2 == 3)
6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return esc_seq_to_key1_alt(last);
6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (param1 == 1 && param2 == 4)
6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return esc_seq_to_key1_alt_shift(last);
6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (param1 == 1 && param2 == 5)
6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return esc_seq_to_key1_ctrl(last);
6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (param2 < 0) {
6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (last != '~')
6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return EDIT_KEY_NONE;
6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		switch (param1) {
6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 2:
6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return EDIT_KEY_INSERT;
6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 3:
6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return EDIT_KEY_DELETE;
6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 5:
6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return EDIT_KEY_PAGE_UP;
6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 6:
6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return EDIT_KEY_PAGE_DOWN;
6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 15:
6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return EDIT_KEY_F5;
6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 17:
6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return EDIT_KEY_F6;
6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 18:
6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return EDIT_KEY_F7;
6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 19:
6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return EDIT_KEY_F8;
6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 20:
6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return EDIT_KEY_F9;
6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 21:
6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return EDIT_KEY_F10;
6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 23:
6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return EDIT_KEY_F11;
6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 24:
6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return EDIT_KEY_F12;
6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return EDIT_KEY_NONE;
7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic enum edit_key_code esc_seq_to_key2(int param1, int param2, char last)
7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* ESC-O<param1>;<param2><last> */
7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (param1 >= 0 || param2 >= 0)
7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_NONE;
7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	switch (last) {
7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 'F':
7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_END;
7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 'H':
7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_HOME;
7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 'P':
7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_F1;
7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 'Q':
7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_F2;
7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 'R':
7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_F3;
7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 'S':
7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_F4;
7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	default:
7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_NONE;
7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic enum edit_key_code esc_seq_to_key(char *seq)
7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char last, *pos;
7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int param1 = -1, param2 = -1;
7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	enum edit_key_code ret = EDIT_KEY_NONE;
7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	last = '\0';
7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (pos = seq; *pos; pos++)
7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		last = *pos;
7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (seq[1] >= '0' && seq[1] <= '9') {
7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		param1 = atoi(&seq[1]);
7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos = os_strchr(seq, ';');
7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (pos)
7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			param2 = atoi(pos + 1);
7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (seq[0] == '[')
7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = esc_seq_to_key1(param1, param2, last);
7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else if (seq[0] == 'O')
7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = esc_seq_to_key2(param1, param2, last);
7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret != EDIT_KEY_NONE)
7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return ret;
7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	edit_clear_line();
7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	printf("\rUnknown escape sequence '%s'\n", seq);
7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	edit_redraw();
7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return EDIT_KEY_NONE;
7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic enum edit_key_code edit_read_key(int sock)
7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int c;
7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	unsigned char buf[1];
7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int res;
7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	static int esc = -1;
7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	static char esc_buf[7];
7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	res = read(sock, buf, 1);
7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (res < 0)
7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		perror("read");
7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (res <= 0)
7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_EOF;
7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	c = buf[0];
7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (esc >= 0) {
7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (c == 27 /* ESC */) {
7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			esc = 0;
7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return EDIT_KEY_NONE;
7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (esc == 6) {
7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			show_esc_buf(esc_buf, c, 0);
7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			esc = -1;
7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else {
7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			esc_buf[esc++] = c;
7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			esc_buf[esc] = '\0';
7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (esc == 1) {
7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (esc_buf[0] != '[' && esc_buf[0] != 'O') {
7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			show_esc_buf(esc_buf, c, 1);
7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			esc = -1;
7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return EDIT_KEY_NONE;
7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else
8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return EDIT_KEY_NONE; /* Escape sequence continues */
8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (esc > 1) {
8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if ((c >= '0' && c <= '9') || c == ';')
8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return EDIT_KEY_NONE; /* Escape sequence continues */
8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (c == '~' || (c >= 'A' && c <= 'Z')) {
8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			esc = -1;
8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return esc_seq_to_key(esc_buf);
8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		show_esc_buf(esc_buf, c, 2);
8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		esc = -1;
8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_NONE;
8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	switch (c) {
8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 1:
8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_CTRL_A;
8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 2:
8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_CTRL_B;
8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 4:
8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_CTRL_D;
8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 5:
8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_CTRL_E;
8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 6:
8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_CTRL_F;
8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 7:
8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_CTRL_G;
8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 8:
8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_CTRL_H;
8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 9:
8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_TAB;
8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 10:
8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_CTRL_J;
8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 13: /* CR */
8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_ENTER;
8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 11:
8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_CTRL_K;
8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 12:
8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_CTRL_L;
8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 14:
8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_CTRL_N;
8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 15:
8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_CTRL_O;
8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 16:
8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_CTRL_P;
8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 18:
8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_CTRL_R;
8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 20:
8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_CTRL_T;
8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 21:
8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_CTRL_U;
8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 22:
8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_CTRL_V;
8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 23:
8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_CTRL_W;
8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 27: /* ESC */
8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		esc = 0;
8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_NONE;
8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 127:
8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_BACKSPACE;
8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	default:
8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return c;
8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic char search_buf[21];
8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int search_skip;
8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic char * search_find(void)
8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct edit_history *h;
8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t len = os_strlen(search_buf);
8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int skip = search_skip;
8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (len == 0)
8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dl_list_for_each(h, &history_list, struct edit_history, list) {
8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (os_strstr(h->str, search_buf)) {
8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (skip == 0)
8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				return h->str;
8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			skip--;
8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	search_skip = 0;
8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return NULL;
8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void search_redraw(void)
8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *match = search_find();
8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	printf("\rsearch '%s': %s" CLEAR_END_LINE,
8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	       search_buf, match ? match : "");
8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	printf("\rsearch '%s", search_buf);
9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	fflush(stdout);
9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void search_start(void)
9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	edit_clear_line();
9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	search_buf[0] = '\0';
9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	search_skip = 0;
9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	search_redraw();
9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void search_clear(void)
9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	search_redraw();
9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	printf("\r" CLEAR_END_LINE);
9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void search_stop(void)
9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *match = search_find();
9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	search_buf[0] = '\0';
9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	search_clear();
9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (match) {
9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_strlcpy(cmdbuf, match, CMD_BUF_LEN);
9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		cmdbuf_len = os_strlen(cmdbuf);
9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		cmdbuf_pos = cmdbuf_len;
9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	edit_redraw();
9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void search_cancel(void)
9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	search_buf[0] = '\0';
9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	search_clear();
9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	edit_redraw();
9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void search_backspace(void)
9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t len;
9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	len = os_strlen(search_buf);
9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (len == 0)
9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	search_buf[len - 1] = '\0';
9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	search_skip = 0;
9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	search_redraw();
9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void search_next(void)
9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	search_skip++;
9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	search_find();
9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	search_redraw();
9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void search_char(char c)
9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t len;
9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	len = os_strlen(search_buf);
9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (len == sizeof(search_buf) - 1)
9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	search_buf[len] = c;
9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	search_buf[len + 1] = '\0';
9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	search_skip = 0;
9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	search_redraw();
9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic enum edit_key_code search_key(enum edit_key_code c)
9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	switch (c) {
9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_ENTER:
9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_CTRL_J:
9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_LEFT:
9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_RIGHT:
9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_HOME:
9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_END:
9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_CTRL_A:
9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_CTRL_E:
9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		search_stop();
9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return c;
9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_DOWN:
9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_UP:
9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		search_cancel();
9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EDIT_KEY_EOF;
9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_CTRL_H:
9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_BACKSPACE:
9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		search_backspace();
9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_CTRL_R:
9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		search_next();
9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	default:
10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (c >= 32 && c <= 255)
10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			search_char(c);
10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return EDIT_KEY_NONE;
10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void edit_read_char(int sock, void *eloop_ctx, void *sock_ctx)
10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	static int last_tab = 0;
10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	static int search = 0;
10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	enum edit_key_code c;
10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	c = edit_read_key(sock);
10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (search) {
10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		c = search_key(c);
10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (c == EDIT_KEY_NONE)
10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return;
10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		search = 0;
10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (c == EDIT_KEY_EOF)
10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return;
10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (c != EDIT_KEY_TAB && c != EDIT_KEY_NONE)
10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		last_tab = 0;
10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	switch (c) {
10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_NONE:
10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_EOF:
10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		edit_eof_cb(edit_cb_ctx);
10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_TAB:
10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		complete(last_tab);
10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		last_tab = 1;
10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_UP:
10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_CTRL_P:
10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		history_prev();
10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_DOWN:
10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_CTRL_N:
10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		history_next();
10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_RIGHT:
10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_CTRL_F:
10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		move_right();
10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_LEFT:
10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_CTRL_B:
10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		move_left();
10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_CTRL_RIGHT:
10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		move_word_right();
10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_CTRL_LEFT:
10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		move_word_left();
10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_DELETE:
10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		delete_current();
10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_END:
10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		move_end();
10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_HOME:
10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_CTRL_A:
10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		move_start();
10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_F2:
10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		history_debug_dump();
10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_CTRL_D:
10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (cmdbuf_len > 0) {
10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			delete_current();
10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return;
10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		printf("\n");
10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		edit_eof_cb(edit_cb_ctx);
10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_CTRL_E:
10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		move_end();
10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_CTRL_H:
10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_BACKSPACE:
10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		delete_left();
10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_ENTER:
10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_CTRL_J:
10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		process_cmd();
10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_CTRL_K:
10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		clear_right();
10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_CTRL_L:
10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		edit_clear_line();
10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		edit_redraw();
10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_CTRL_R:
11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		search = 1;
11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		search_start();
11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_CTRL_U:
11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		clear_left();
11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case EDIT_KEY_CTRL_W:
11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		delete_word();
11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	default:
11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (c >= 32 && c <= 255)
11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			insert_char(c);
11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint edit_init(void (*cmd_cb)(void *ctx, char *cmd),
11198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	      void (*eof_cb)(void *ctx),
11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	      char ** (*completion_cb)(void *ctx, const char *cmd, int pos),
11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	      void *ctx, const char *history_file)
11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
11231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	currbuf[0] = '\0';
11248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dl_list_init(&history_list);
11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	history_curr = NULL;
11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (history_file)
11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		history_read(history_file);
11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	edit_cb_ctx = ctx;
11308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	edit_cmd_cb = cmd_cb;
11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	edit_eof_cb = eof_cb;
11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	edit_completion_cb = completion_cb;
11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	tcgetattr(STDIN_FILENO, &prevt);
11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	newt = prevt;
11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	newt.c_lflag &= ~(ICANON | ECHO);
11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	tcsetattr(STDIN_FILENO, TCSANOW, &newt);
11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_register_read_sock(STDIN_FILENO, edit_read_char, NULL, NULL);
11408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	printf("> ");
11428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	fflush(stdout);
11438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
11458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
11468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid edit_deinit(const char *history_file,
11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 int (*filter_cb)(void *ctx, const char *cmd))
11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct edit_history *h;
11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (history_file)
11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		history_write(history_file, filter_cb);
11548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while ((h = dl_list_first(&history_list, struct edit_history, list))) {
11558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		dl_list_del(&h->list);
11568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(h);
11578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
11588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	edit_clear_line();
11598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	putchar('\r');
11608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	fflush(stdout);
11618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_unregister_read_sock(STDIN_FILENO);
11628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	tcsetattr(STDIN_FILENO, TCSANOW, &prevt);
11638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
11648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid edit_redraw(void)
11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char tmp;
11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	cmdbuf[cmdbuf_len] = '\0';
11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	printf("\r> %s", cmdbuf);
11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (cmdbuf_pos != cmdbuf_len) {
11728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		tmp = cmdbuf[cmdbuf_pos];
11738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		cmdbuf[cmdbuf_pos] = '\0';
11748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		printf("\r> %s", cmdbuf);
11758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		cmdbuf[cmdbuf_pos] = tmp;
11768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
11778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	fflush(stdout);
11788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1179