#include <string.h>
#include <ncurses.h>
#include <wchar.h>
#include <stdlib.h>
#include <ctype.h> // for isprint()
#include <wordexp.h>
#include "sc.h" // for rescol
#include "color.h" // for set_ucolor
#include "conf.h"
#include "cmds_command.h"
#include "cmds_edit.h"
#include "cmds.h"
#include "utils/string.h"
#include "utils/dictionary.h"
#include "tui.h"
#include "file.h"
#include "main.h"
#include "interp.h"
#include "hide_show.h"
#include "exec.h"
#include "help.h"
#include "marks.h"
#include "filter.h"
#include "maps.h"
#include "xls.h"
#include "xlsx.h"
#include "cmds_visual.h"
#ifdef UNDO
#include "undo.h"
#endif
extern char * rev;
extern struct dictionary * user_conf_d;
wchar_t inputline[BUFFERSIZE];
wchar_t interp_line[BUFFERSIZE];
int inputline_pos; // This is the position in window. Some chars has 2 chars width
// \-> https://en.wikipedia.org/wiki/Halfwidth_and_fullwidth_forms
int real_inputline_pos; // This is the real position in inputline
static wchar_t * valid_commands[] = {
L"!",
L"addfilter",
L"autojus",
L"cellcolor",
L"color",
L"e csv",
L"e tab",
L"e txt",
L"e xlsx",
L"e! csv",
L"e! tab",
L"e! txt",
L"e! xlsx",
L"datefmt",
L"delfilter",
L"delfilters",
L"file",
L"fill",
L"filteron",
L"filteroff",
L"format",
L"freeze",
L"h",
L"help",
L"hiddencols",
L"hiddenrows",
L"hidecol",
L"hiderow",
L"i csv",
L"i tab",
L"i xls",
L"i xlsx",
L"i! csv",
L"i! tab",
L"i! xls",
L"i! xlsx",
L"imap",
L"inoremap",
L"int",
L"iunmap",
L"load",
L"load!",
L"lock",
L"unfreeze",
L"unlock",
L"nmap",
L"nnoremap",
L"nunmap",
L"pad",
L"q",
L"q!",
L"quit!",
L"quit",
L"redefine_color",
L"refresh",
L"set",
L"showcol",
L"showfilters",
L"showmaps",
L"showrow",
L"showrows",
L"sort",
L"trigger",
L"untrigger",
L"unformat",
L"version",
L"w",
L"wq",
L"x",
L"valueize",
(wchar_t *) 0
};
void do_commandmode(struct block * sb) {
// If a visual selected range exists
int p = is_range_selected();
struct srange * sr = NULL;
if (p != -1) sr = get_range_by_pos(p);
//-------------------------------------
// Normal KEY handlers for this MODE
//-------------------------------------
if (sb->value == OKEY_BS || sb->value == OKEY_BS2) { // BS
if ( ! wcslen(inputline) || ! real_inputline_pos ) return;
int l = wcwidth(inputline[real_inputline_pos - 1]);
real_inputline_pos--;
del_wchar(inputline, real_inputline_pos);
inputline_pos -= l;
ui_show_header();
#ifdef HISTORY_FILE
if (commandline_history->pos == 0)
del_wchar(get_line_from_history(commandline_history, commandline_history->pos), real_inputline_pos); // Clean history
#endif
ui_show_header();
return;
} else if (sb->value == OKEY_LEFT) { // LEFT
if (inputline_pos) {
real_inputline_pos--;
int l = wcwidth(inputline[real_inputline_pos]);
inputline_pos -= l;
ui_show_header();
}
return;
} else if (sb->value == OKEY_RIGHT) { // RIGHT
int max = wcswidth(inputline, wcslen(inputline));
if (inputline_pos < max) {
int l = wcwidth(inputline[real_inputline_pos++]);
inputline_pos += l;
ui_show_header();
}
return;
} else if (sb->value == OKEY_DEL) { // DEL
if (inputline_pos > wcswidth(inputline, wcslen(inputline))) return;
del_wchar(inputline, real_inputline_pos);
#ifdef HISTORY_FILE
if (commandline_history->pos == 0)
del_wchar(get_line_from_history(commandline_history, commandline_history->pos), real_inputline_pos); // Clean history
#endif
ui_show_header();
return;
#ifdef HISTORY_FILE
} else if (sb->value == OKEY_UP || sb->value == ctl('p') || // UP
sb->value == OKEY_DOWN || sb->value == ctl('n')) { // DOWN
int delta = 0;
if (sb->value == OKEY_UP || sb->value == ctl('p')) { // up
if (commandline_history->len <= - commandline_history->pos + 1) return;
delta = -1;
}
if (sb->value == OKEY_DOWN || sb->value == ctl('n')) { // down
if ( - commandline_history->pos == 0) return;
delta = 1;
}
commandline_history->pos += delta;
wcscpy(inputline, get_line_from_history(commandline_history, commandline_history->pos));
inputline_pos =