* Copyright (C) 2012 xaizek.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "bracket_notation.h"
#include <curses.h>
#include <assert.h>
#include <ctype.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <wctype.h>
#include "compat/curses.h"
#include "compat/reallocarray.h"
#include "engine/text_buffer.h"
#include "modes/wk.h"
#include "utils/macros.h"
#include "utils/str.h"
#include "utils/utils.h"
typedef struct
{
const wchar_t *notation;
const wchar_t key[8];
size_t len;
}
key_pair_t;
static int notation_sorter(const void *first, const void *second);
static const key_pair_t * find_notation(const wchar_t str[]);
static const char * wchar_to_spec(const wchar_t c[], size_t *len, int bs);
static key_pair_t key_pairs[] = {
{ L"<esc>", L"\x1b" },
{ L"<c-@>", { WC_C_SPACE } },
{ L"<c-a>", L"\x01" },
{ L"<c-b>", L"\x02" },
{ L"<c-c>", L"\x03" },
{ L"<c-d>", L"\x04" },
{ L"<c-e>", L"\x05" },
{ L"<c-f>", L"\x06" },
{ L"<c-g>", L"\x07" },
{ L"<c-h>", L"\x08" },
{ L"<c-i>", L"\x09" },
{ L"<c-j>", L"\x0a" },
{ L"<c-k>", L"\x0b" },
{ L"<c-l>", L"\x0c" },
{ L"<c-m>", L"\x0d" },
{ L"<c-n>", L"\x0e" },
{ L"<c-o>", L"\x0f" },
{ L"<c-p>", L"\x10" },
{ L"<c-q>", L"\x11" },
{ L"<c-r>", L"\x12" },
{ L"<c-s>", L"\x13" },
{ L"<c-t>", L"\x14" },
{ L"<c-u>", L"\x15" },
{ L"<c-v>", L"\x16" },
{ L"<c-w>", L"\x17" },
{ L"<c-x>", L"\x18" },
{ L"<c-y>", L"\x19" },
{ L"<c-z>", L"\x1a" },
{ L"<c-[>", L"\x1b" },
{ L"<c-\\>", L"\x1c" },
{ L"<c-]>", L"\x1d" },
{ L"<c-^>", L"\x1e" },
{ L"<c-_>", L"\x1f" },
{ L"<s-c-a>", L"\x01" },
{ L"<s-c-b>", L"\x02" },
{ L"<s-c-c>", L"\x03" },
{ L"<s-c-d>", L"\x04" },
{ L"<s-c-e>", L"\x05" },
{ L"<s-c-f>", L"\x06" },
{ L"<s-c-g>", L"\x07" },
{ L"<s-c-h>", L"\x08" },
{ L"<s-c-i>", L"\x09" },
{ L"<s-c-j>", L"\x0a" },
{ L"<s-c-k>", L"\x0b" },
{ L"<s-c-l>", L"\x0c" },
{ L"<s-c-m>", L"\x0d" },
{ L"<s-c-n>", L"\x0e" },
{ L"<s-c-o>", L"\x0f" },
{ L"<s-c-p>", L"\x10" },
{ L"<s-c-q>", L"\x11" },
{ L"<s-c-r>", L"\x12" },
{ L"<s-c-s>", L"\x13" },
{ L"<s-c-t>", L"\x14" },
{ L"<s-c-u>", L"\x15" },
{ L"<s-c-v>", L"\x16" },
{ L"<s-c-w>", L"\x17" },
{ L"<s-c-x>", L"\x18" },
{ L"<s-c-y>", L"\x19" },
{ L"<s-c-z>", L"\x1a" },
{ L"<s-c-[>", L"\x1b" },
{ L"<s-c-\\>", L"\x1c" },
{ L"<s-c-]>", L"\x1d" },
{ L"<s-c-^>", L"\x1e" },
{ L"<s-c-_>", L"\x1f" },
{ L"<c-s-a>", L"\x01" },
{ L"<c-s-b>", L"\x02" },
{ L"<c-s-c>", L"\x03" },
{ L"<c-s-d>", L"\x04" },
{ L"<c-s-e>", L"\x05" },
{ L"<c-s-f>", L"\x06" },
{ L"<c-s-g>", L"\x07" },
{ L"<c-s-h>", L"\x08" },
{ L"<c-s-i>", L"\x09" },
{ L"<c-s-j>", L"\x0a" },
{ L"<c-s-k>", L"\x0b" },
{ L"<c-s-l>", L"\x0c" },
{ L"<c-s-m>", L"\x0d" },
{ L"<c-s-n>", L"\x0e" },
{ L"<c-s-o>", L"\x0f" },
{ L"<c-s-p>", L"\x10" },
{ L"<c-s-q>", L"\x11" },
{ L"<c-s-r>", L"\x12" },
{ L"<c-s-s>", L"\x13" },
{ L"<c-s-t>", L"\x14" },
{ L"<c-s-u>", L"\x15" },
{ L"<c-s-v>", L"\x16" },
{ L"<c-s-w>", L"\x17" },
{ L"<c-s-x>", L"\x18" },
{ L"<c-s-y>", L"\x19" },
{ L"<c-s-z>", L"\x1a" },
{ L"<c-s-[>", L"\x1b" },
{ L"<c-s-\\>", L"\x1c" },
{ L"<c-s-]>", L"\x1d" },
{ L"<c-s-^>", L"\x1e" },
{ L"<c-s-_>", L"\x1f" },
{ L"<cr>", L"\r" },
{ L"<space>", L" " },
{ L"<nop>", L"" },
{ L"<tab>", L"\t" },
{ L"<lt>", L"<" },
#ifdef ENABLE_EXTENDED_KEYS
{ L"<s-tab>", { K(KEY_BTAB) } },
#else
{ L"<s-tab>", L"\033"L"[Z" },
#endif
#ifndef __PDCURSES__
{ L"<a-0>", L"\033"L"0" },
{ L"<a-1>", L"\033"L"1" },
{ L"<a-2>", L"\033"L"2" },
{ L"<a-3>", L"\033"L"3" },
{ L"<a-4>", L"\033"L"4" },
{ L"<a-5>", L"\033"L"5" },
{ L"<a-6>", L"\033"L"6" },
{ L"<a-7>", L"\033"L"7" },
{ L"<a-8>", L"\033"L"8" },
{ L"<a-9>", L"\033"L"9" },
{ L"<a-a>", L"\033"L"a" },
{ L"<a-b>", L"\033"L"b" },
{ L"<a-c>", L"\033"L"c" },
{ L"<a-d>", L"\033"L"d" },
{ L"<a-e>", L"\033"L"e" },
{ L"<a-f>", L"\033"L"f" },
{ L"<a-g>", L"\033"L"g" },
{ L"<a-h>", L"\033"L"h" },
{ L"<a-i>", L"\033"L"i" },
{ L"<a-j>", L"\033"L"j" },
{ L"<a-k>", L"\033"L"k" },
{ L"<a-l>", L"\033"L"l" },
{ L"<a-m>", L"\033"L"m" },
{ L"<a-n>", L"\033"L"n" },
{ L"<a-o>", L"\033"L"o" },
{ L"<a-p>", L"\033"L"p" },
{ L"<a-q>", L"\033"L"q" },
{ L"<a-r>", L"\033"L"r" },
{ L"<a-s>", L"\033"L"s" },
{ L"<a-t>", L"\033"L"t" },
{ L"<a-u>", L"\033"L"u" },
{ L"<a-v>", L"\033"L"v" },
{ L"<a-w>", L"\033"L"w" },
{ L"<a-x>", L"\033"L"x" },
{ L"<a-y>", L"\033"L"y" },
{ L"<a-z>", L"\033"L"z" },
{ L"<m-0>", L"\033"L"0" },
{ L"<m-1>", L"\033"L"1" },
{ L"<m-2>", L"\033"L"2" },
{ L"<m-3>", L"\033"L"3" },
{ L"<m-4>", L"\033"L"4" },
{ L"<m-5>", L"\033"L"5" },
{ L"<m-6>", L"\033"L"6" },
{ L"<m-7>", L"\033"L"7" },
{ L"<m-8>", L"\033"L"8" },
{ L"<m-9>", L"\033"L"9" },
{ L"<m-a>", L"\033"L"a" },
{ L"<m-b>", L"\033"L"b" },
{ L"<m-c>", L"\033"L"c" },
{ L"<m-d>", L"\033"L"d" },
{ L"<m-e>", L"\033"L"e" },
{ L"<m-f>", L"\033"L"f" },
{ L"<m-g>", L"\033"L"g" },
{ L"<m-h>", L"\033"L"h" },
{ L"<m-i>", L"\033"L"i" },
{ L"<m-j>", L"\033"L"j" },
{ L"<m-k>", L"\033"L"k" },
{ L"<m-l>", L"\033"L"l" },
{ L"<m-m>", L"\033"L"m" },
{ L"<m-n>", L"\033"L"n" },
{ L"<m-o>", L"\033"L"o" },
{ L"<m-p>", L"\033"L"p" },
{ L"<m-q>", L"\033"L"q" },
{ L"<m-r>", L"\033"L"r" },
{ L"<m-s>", L"\033"L"s" },
{ L"<m-t>", L"\033"L"t" },
{ L"<m-u>", L"\033"L"u" },
{ L"<m-v>", L"\033"L"v" },
{ L"<m-w>", L"\033"L"w" },
{ L"<m-x>", L"\033"L"x" },
{ L"<m-y>", L"\033"L"y" },
{ L"<m-z>", L"\033"L"z" },
{ L"<a-c-a>", L"\033"L"\x01" },
{ L"<a-c-b>", L"\033"L"\x02" },
{ L"<a-c-c>", L"\033"L"\x03" },
{ L"<a-c-d>", L"\033"L"\x04" },
{ L"<a-c-e>", L"\033"L"\x05" },
{ L"<a-c-f>", L"\033"L"\x06" },
{ L"<a-c-g>", L"\033"L"\x07" },
{ L"<a-c-h>", L"\033"L"\x08" },
{ L"<a-c-i>", L"\033"L"\x09" },
{ L"<a-c-j>", L"\033"L"\x0a" },
{ L"<a-c-k>", L"\033"L"\x0b" },
{ L"<a-c-l>", L"\033"L"\x0c" },
{ L"<a-c-m>", L"\033"L"\x0d" },
{ L"<a-c-n>", L"\033"L"\x0e" },
{ L"<a-c-o>", L"\033"L"\x0f" },
{ L"<a-c-p>", L"\033"L"\x10" },
{ L"<a-c-q>", L"\033"L"\x11" },
{ L"<a-c-r>", L"\033"L"\x12" },
{ L"<a-c-s>", L"\033"L"\x13" },
{ L"<a-c-t>", L"\033"L"\x14" },
{ L"<a-c-u>", L"\033"L"\x15" },
{ L"<a-c-v>", L"\033"L"\x16" },
{ L"<a-c-w>", L"\033"L"\x17" },
{ L"<a-c-x>", L"\033"L"\x18" },
{ L"<a-c-y>", L"\033"L"\x19" },
{ L"<a-c-z>", L"\033"L"\x1a" },
{ L"<m-c-a>", L"\033"L"\x01" },
{ L"<m-c-b>", L"\033"L"\x02" },
{ L"<m-c-c>", L"\033"L"\x03" },
{ L"<m-c-d>", L"\033"L"\x04" },
{ L"<m-c-e>", L"\033"L"\x05" },
{ L"<m-c-f>", L"\033"L"\x06" },
{ L"<m-c-g>", L"\033"L"\x07" },
{ L"<m-c-h>", L"\033"L"\x08" },
{ L"<m-c-i>", L"\033"L"\x09" },
{ L"<m-c-j>", L"\033"L"\x0a" },
{ L"<m-c-k>", L"\033"L"\x0b" },
{ L"<m-c-l>", L"\033"L"\x0c" },
{ L"<m-c-m>", L"\033"L"\x0d" },
{ L"<m-c-n>", L"\033"L"\x0e" },
{ L"<m-c-o>", L"\033"L"\x0f" },
{ L"<m-c-p>", L"\033"L"\x10" },
{ L"<m-c-q>", L"\033"L"\x11" },
{ L"<m-c-r>", L"\033"L"\x12" },
{ L"<m-c-s>", L"\033"L"\x13" },
{ L"<m-c-t>", L"\033"L"\x14" },
{ L"<m-c-u>", L"\033"L"\x15" },
{ L"<m-c-v>", L"\033"L"\x16" },
{ L"<m-c-w>", L"\033"L"\x17" },
{ L"<m-c-x>", L"\033"L"\x18" },
{ L"<m-c-y>", L"\033"L"\x19" },
{ L"<m-c-z>", L"\033"L"\x1a" },
{ L"<c-a-a>", L"\033"L"\x01" },
{ L"<c-a-b>", L"\033"L"\x02" },
{ L"<c-a-c>", L"\033"L"\x03" },
{ L"<c-a-d>", L"\033"L"\x04" },
{ L"<c-a-e>", L"\033"L"\x05" },
{ L"<c-a-f>", L"\033"L"\x06" },
{ L"<c-a-g>", L"\033"L"\x07" },
{ L"<c-a-h>", L"\033"L"\x08" },
{ L"<c-a-i>", L"\033"L"\x09" },
{ L"<c-a-j>", L"\033"L"\x0a" },
{ L"<c-a-k>", L"\033"L"\x0b" },
{ L"<c-a-l>", L"\033"L"\x0c" },
{ L"<c-a-m>", L"\033"L"\x0d" },
{ L"<c-a-n>", L"\033"L"\x0e" },
{ L"<c-a-o>", L"\033"L"\x0f" },
{ L"<c-a-p>", L"\033"L"\x10" },
{ L"<c-a-q>", L"\033"L"\x11" },
{ L"<c-a-r>", L"\033"L"\x12" },
{ L"<c-a-s>", L"\033"L"\x13" },
{ L"<c-a-t>", L"\033"L"\x14" },
{ L"<c-a-u>", L"\033"L"\x15" },
{ L"<c-a-v>", L"\033"L"\x16" },
{ L"<c-a-w>", L"\033"L"\x17" },
{ L"<c-a-x>", L"\033"L"\x18" },
{ L"<c-a-y>", L"\033"L"\x19" },
{ L"<c-a-z>", L"\033"L"\x1a" },
{ L"<c-m-a>", L"\033"L"\x01" },
{ L"<c-m-b>", L"\033"L"\x02" },
{ L"<c-m-c>", L"\033"L"\x03" },
{ L"<c-m-d>", L"\033"L"\x04" },
{ L"<c-m-e>", L"\033"L"\x05" },
{ L"<c-m-f>", L"\033"L"\x06" },
{ L"<c-m-g>", L"\033"L"\x07" },
{ L"<c-m-h>", L"\033"L"\x08" },
{ L"<c-m-i>", L"\033"L"\x09" },
{ L"<c-m-j>", L"\033"L"\x0a" },
{ L"<c-m-k>", L"\033"L"\x0b" },
{ L"<c-m-l>", L"\033"L"\x0c" },
{ L"<c-m-m>", L"\033"L"\x0d" },
{ L"<c-m-n>", L"\033"L"\x0e" },
{ L"<c-m-o>", L"\033"L"\x0f" },
{ L"<c-m-p>", L"\033"L"\x10" },
{ L"<c-m-q>", L"\033"L"\x11" },
{ L"<c-m-r>", L"\033"L"\x12" },
{ L"<c-m-s>", L"\033"L"\x13" },
{ L"<c-m-t>", L"\033"L"\x14" },
{ L"<c-m-u>", L"\033"L"\x15" },
{ L"<c-m-v>", L"\033"L"\x16" },
{ L"<c-m-w>", L"\033"L"\x17" },
{ L"<c-m-x>", L"\033"L"\x18" },
{ L"<c-m-y>", L"\033"L"\x19" },
{ L"<c-m-z>", L"\033"L"\x1a" },
{ L"<a-s-a>", L"\033"L"A" },
{ L"<a-s-b>", L"\033"L"B" },
{ L"<a-s-c>", L"\033"L"C" },
{ L"<a-s-d>", L"\033"L"D" },
{ L"<a-s-e>", L"\033"L"E" },
{ L"<a-s-f>", L"\033"L"F" },
{ L"<a-s-g>", L"\033"L"G" },
{ L"<a-s-h>", L"\033"L"H" },
{ L"<a-s-i>", L"\033"L"I" },
{ L"<a-s-j>", L"\033"L"J" },
{ L"<a-s-k>", L"\033"L"K" },
{ L"<a-s-l>", L"\033"L"L" },
{ L"<a-s-m>", L"\033"L"M" },
{ L"<a-s-n>", L"\033"L"N" },
{ L"<a-s-o>", L"\033"L"O" },
{ L"<a-s-p>", L"\033"L"P" },
{ L"<a-s-q>", L"\033"L"Q" },
{ L"<a-s-r>", L"\033"L"R" },
{ L"<a-s-s>", L"\033"L"S" },
{ L"<a-s-t>", L"\033"L"T" },
{ L"<a-s-u>", L"\033"L"U" },
{ L"<a-s-v>", L"\033"L"V" },
{ L"<a-s-w>", L"\033"L"W" },
{ L"<a-s-x>", L"\033"L"X" },
{ L"<a-s-y>", L"\033"L"Y" },
{ L"<a-s-z>", L"\033"L"Z" },
{ L"<s-a-a>", L"\033"L"A" },
{ L"<s-a-b>", L"\033"L"B" },
{ L"<s-a-c>", L"\033"L"C" },
{ L"<s-a-d>", L"\033"L"D" },
{ L"<s-a-e>", L"\033"L"E" },
{ L"<s-a-f>", L"\033"L"F" },
{ L"<s-a-g>", L"\033"L"G" },
{ L"<s-a-h>", L"\033"L"H" },
{ L"<s-a-i>", L"\033"L"I" },
{ L"<s-a-j>", L"\033"L"J" },
{ L"<s-a-k>", L"\033"L"K" },
{ L"<s-a-l>", L"\033"L"L" },
{ L"<s-a-m>", L"\033"L"M" },
{ L"<s-a-n>", L"\033"L"N" },
{ L"<s-a-o>", L"\033"L"O" },
{ L"<s-a-p>", L"\033"L"P" },
{ L"<s-a-q>", L"\033"L"Q" },
{ L"<s-a-r>", L"\033"L"R" },
{ L"<s-a-s>", L"\033"L"S" },
{ L"<s-a-t>", L"\033"L"T" },
{ L"<s-a-u>", L"\033"L"U" },
{ L"<s-a-v>", L"\033"L"V" },
{ L"<s-a-w>", L"\033"L"W" },
{ L"<s-a-x>", L"\033"L"X" },
{ L"<s-a-y>", L"\033"L"Y" },
{ L"<s-a-z>", L"\033"L"Z" },
{ L"<m-s-a>", L"\033"L"A" },
{ L"<m-s-b>", L"\033"L"B" },
{ L"<m-s-c>", L"\033"L"C" },
{ L"<m-s-d>", L"\033"L"D" },
{ L"<m-s-e>", L"\033"L"E" },
{ L"<m-s-f>", L"\033"L"F" },
{ L"<m-s-g>", L"\033"L"G" },
{ L"<m-s-h>", L"\033"L"H" },
{ L"<m-s-i>", L"\033"L"I" },
{ L"<m-s-j>", L"\033"L"J" },
{ L"<m-s-k>", L"\033"L"K" },
{ L"<m-s-l>", L"\033"L"L" },
{ L"<m-s-m>", L"\033"L"M" },
{ L"<m-s-n>", L"\033"L"N" },
{ L"<m-s-o>", L"\033"L"O" },
{ L"<m-s-p>", L"\033"L"P" },
{ L"<m-s-q>", L"\033"L"Q" },
{ L"<m-s-r>", L"\033"L"R" },
{ L"<m-s-s>", L"\033"L"S" },
{ L"<m-s-t>", L"\033"L"T" },
{ L"<m-s-u>", L"\033"L"U" },
{ L"<m-s-v>", L"\033"L"V" },
{ L"<m-s-w>", L"\033"L"W" },
{ L"<m-s-x>", L"\033"L"X" },
{ L"<m-s-y>", L"\033"L"Y" },
{ L"<m-s-z>", L"\033"L"Z" },
{ L"<s-m-a>", L"\033"L"A" },
{ L"<s-m-b>", L"\033"L"B" },
{ L"<s-m-c>", L"\033"L"C" },
{ L"<s-m-d>", L"\033"L"D" },
{ L"<s-m-e>", L"\033"L"E" },
{ L"<s-m-f>", L"\033"L"F" },
{ L"<s-m-g>", L"\033"L"G" },
{ L"<s-m-h>", L"\033"L"H" },
{ L"<s-m-i>", L"\033"L"I" },
{ L"<s-m-j>", L"\033"L"J" },
{ L"<s-m-k>", L"\033"L"K" },
{ L"<s-m-l>", L"\033"L"L" },
{ L"<s-m-m>", L"\033"L"M" },
{ L"<s-m-n>", L"\033"L"N" },
{ L"<s-m-o>", L"\033"L"O" },
{ L"<s-m-p>", L"\033"L"P" },
{ L"<s-m-q>", L"\033"L"Q" },
{ L"<s-m-r>", L"\033"L"R" },
{ L"<s-m-s>", L"\033"L"S" },
{ L"<s-m-t>", L"\033"L"T" },
{ L"<s-m-u>", L"\033"L"U" },
{ L"<s-m-v>", L"\033"L"V" },
{ L"<s-m-w>", L"\033"L"W" },
{ L"<s-m-x>", L"\033"L"X" },
{ L"<s-m-y>", L"\033"L"Y" },
{ L"<s-m-z>", L"\033"L"Z" },
#else
{ L"<a-a>", { K(ALT_A) } },
{ L"<a-b>", { K(ALT_B) } },
{ L"<a-c>", { K(ALT_C) } },
{ L"<a-d>", { K(ALT_D) } },
{ L"<a-e>", { K(ALT_E) } },
{ L"<a-f>", { K(ALT_F) } },
{ L"<a-g>", { K(ALT_G) } },
{ L"<a-h>", { K(ALT_H) } },
{ L"<a-i>", { K(ALT_I) } },
{ L"<a-j>", { K(ALT_J) } },
{ L"<a-k>", { K(ALT_K) } },
{ L"<a-l>", { K(ALT_L) } },
{ L"<a-m>", { K(ALT_M) } },
{ L"<a-n>", { K(ALT_N) } },
{ L"<a-o>", { K(ALT_O) } },
{ L"<a-p>", { K(ALT_P) } },
{ L"<a-q>", { K(ALT_Q) } },
{ L"<a-r>", { K(ALT_R) } },
{ L"<a-s>", { K(ALT_S) } },
{ L"<a-t>", { K(ALT_T) } },
{ L"<a-u>", { K(ALT_U) } },
{ L"<a-v>", { K(ALT_V) } },
{ L"<a-w>", { K(ALT_W) } },
{ L"<a-x>", { K(ALT_X) } },
{ L"<a-y>", { K(ALT_Y) } },
{ L"<a-z>", { K(ALT_Z) } },
{ L"<m-a>", { K(ALT_A) } },
{ L"<m-b>", { K(ALT_B) } },
{ L"<m-c>", { K(ALT_C) } },
{ L"<m-d>", { K(ALT_D) } },
{ L"<m-e>", { K(ALT_E) } },
{ L"<m-f>", { K(ALT_F) } },
{ L"<m-g>", { K(ALT_G) } },
{ L"<m-h>", { K(ALT_H) } },
{ L"<m-i>", { K(ALT_I) } },
{ L"<m-j>", { K(ALT_J) } },
{ L"<m-k>", { K(ALT_K) } },
{ L"<m-l>", { K(ALT_L) } },
{ L"<m-m>", { K(ALT_M) } },
{ L"<m-n>", { K(ALT_N) } },
{ L"<m-o>", { K(ALT_O) } },
{ L"<m-p>", { K(ALT_P) } },
{ L"<m-q>", { K(ALT_Q) } },
{ L"<m-r>", { K(ALT_R) } },
{ L"<m-s>", { K(ALT_S) } },
{ L"<m-t>", { K(ALT_T) } },
{ L"<m-u>", { K(ALT_U) } },
{ L"<m-v>", { K(ALT_V) } },
{ L"<m-w>", { K(ALT_W) } },
{ L"<m-x>", { K(ALT_X) } },
{ L"<m-y>", { K(ALT_Y) } },
{ L"<m-z>", { K(ALT_Z) } },
#endif
{ L"<del>", L"\177" },
#ifdef ENABLE_EXTENDED_KEYS
{ L"<home>", { K(KEY_HOME) } },
{ L"<end>", { K(KEY_END) } },
{ L"<left>", { K(KEY_LEFT) } },
{ L"<right>", { K(KEY_RIGHT) } },
{ L"<up>", { K(KEY_UP) } },
{ L"<down>", { K(KEY_DOWN) } },
{ L"<bs>", { K(KEY_BACKSPACE) } },
{ L"<delete>", { K(KEY_DC) } },
{ L"<insert>", { K(KEY_IC) } },
{ L"<pageup>", { K(KEY_PPAGE) } },
{ L"<pagedown>", { K(KEY_NPAGE) } },
{ L"<s-home>", { K(KEY_SHOME) } },
{ L"<s-end>", { K(KEY_SEND) } },
{ L"<s-left>", { K(KEY_SLEFT) } },
{ L"<s-right>", { K(KEY_SRIGHT) } },
{ L"<s-up>", { K(KEY_SR) } },
{ L"<s-down>", { K(KEY_SF) } },
{ L"<s-delete>", { K(KEY_SDC) } },
{ L"<s-insert>", { K(KEY_SIC) } },
{ L"<s-pageup>", { K(KEY_SPREVIOUS) } },
{ L"<s-pagedown>", { K(KEY_SNEXT) } },
{ L"<f0>", { K(KEY_F(0)) } },
{ L"<f1>", { K(KEY_F(1)) } },
{ L"<f2>", { K(KEY_F(2)) } },
{ L"<f3>", { K(KEY_F(3)) } },
{ L"<f4>", { K(KEY_F(4)) } },
{ L"<f5>", { K(KEY_F(5)) } },
{ L"<f6>", { K(KEY_F(6)) } },
{ L"<f7>", { K(KEY_F(7)) } },
{ L"<f8>", { K(KEY_F(8)) } },
{ L"<f9>", { K(KEY_F(9)) } },
{ L"<f10>", { K(KEY_F(10)) } },
{ L"<f11>", { K(KEY_F(11)) } },
{ L"<f12>", { K(KEY_F(12)) } },
{ L"<f13>", { K(KEY_F(13)) } },
{ L"<f14>", { K(KEY_F(14)) } },
{ L"<f15>", { K(KEY_F(15)) } },
{ L"<f16>", { K(KEY_F(16)) } },
{ L"<f17>", { K(KEY_F(17)) } },
{ L"<f18>", { K(KEY_F(18)) } },
{ L"<f19>", { K(KEY_F(19)) } },
{ L"<f20>", { K(KEY_F(20)) } },
{ L"<f21>", { K(KEY_F(21)) } },
{ L"<f22>", { K(KEY_F(22)) } },
{ L"<f23>", { K(KEY_F(23)) } },
{ L"<f24>", { K(KEY_F(24)) } },
{ L"<f25>", { K(KEY_F(25)) } },
{ L"<f26>", { K(KEY_F(26)) } },
{ L"<f27>", { K(KEY_F(27)) } },
{ L"<f28>", { K(KEY_F(28)) } },
{ L"<f29>", { K(KEY_F(29)) } },
{ L"<f30>", { K(KEY_F(30)) } },
{ L"<f31>", { K(KEY_F(31)) } },
{ L"<f32>", { K(KEY_F(32)) } },
{ L"<f33>", { K(KEY_F(33)) } },
{ L"<f34>", { K(KEY_F(34)) } },
{ L"<f35>", { K(KEY_F(35)) } },
{ L"<f36>", { K(KEY_F(36)) } },
{ L"<f37>", { K(KEY_F(37)) } },
{ L"<f38>", { K(KEY_F(38)) } },
{ L"<f39>", { K(KEY_F(39)) } },
{ L"<f40>", { K(KEY_F(40)) } },
{ L"<f41>", { K(KEY_F(41)) } },
{ L"<f42>", { K(KEY_F(42)) } },
{ L"<f43>", { K(KEY_F(43)) } },
{ L"<f44>", { K(KEY_F(44)) } },
{ L"<f45>", { K(KEY_F(45)) } },
{ L"<f46>", { K(KEY_F(46)) } },
{ L"<f47>", { K(KEY_F(47)) } },
{ L"<f48>", { K(KEY_F(48)) } },
{ L"<f49>", { K(KEY_F(49)) } },
{ L"<f50>", { K(KEY_F(50)) } },
{ L"<f51>", { K(KEY_F(51)) } },
{ L"<f52>", { K(KEY_F(52)) } },
{ L"<f53>", { K(KEY_F(53)) } },
{ L"<f54>", { K(KEY_F(54)) } },
{ L"<f55>", { K(KEY_F(55)) } },
{ L"<f56>", { K(KEY_F(56)) } },
{ L"<f57>", { K(KEY_F(57)) } },
{ L"<f58>", { K(KEY_F(58)) } },
{ L"<f59>", { K(KEY_F(59)) } },
{ L"<f60>", { K(KEY_F(60)) } },
{ L"<f61>", { K(KEY_F(61)) } },
{ L"<f62>", { K(KEY_F(62)) } },
{ L"<f63>", { K(KEY_F(63)) } },
{ L"<s-f1>", { K(KEY_F(13)) } },
{ L"<s-f2>", { K(KEY_F(14)) } },
{ L"<s-f3>", { K(KEY_F(15)) } },
{ L"<s-f4>", { K(KEY_F(16)) } },
{ L"<s-f5>", { K(KEY_F(17)) } },
{ L"<s-f6>", { K(KEY_F(18)) } },
{ L"<s-f7>", { K(KEY_F(19)) } },
{ L"<s-f8>", { K(KEY_F(20)) } },
{ L"<s-f9>", { K(KEY_F(21)) } },
{ L"<s-f10>", { K(KEY_F(22)) } },
{ L"<s-f11>", { K(KEY_F(23)) } },
{ L"<s-f12>", { K(KEY_F(24)) } },
{ L"<c-f1>", { K(KEY_F(25)) } },
{ L"<c-f2>", { K(KEY_F(26)) } },
{ L"<c-f3>", { K(KEY_F(27)) } },
{ L"<c-f4>", { K(KEY_F(28)) } },
{ L"<c-f5>", { K(KEY_F(29)) } },
{ L"<c-f6>", { K(KEY_F(30)) } },
{ L"<c-f7>", { K(KEY_F(31)) } },
{ L"<c-f8>", { K(KEY_F(32)) } },
{ L"<c-f9>", { K(KEY_F(33)) } },
{ L"<c-f10>", { K(KEY_F(34)) } },
{ L"<c-f11>", { K(KEY_F(35)) } },
{ L"<c-f12>", { K(KEY_F(36)) } },
{ L"<a-f1>", { K(KEY_F(37)) } },
{ L"<a-f2>", { K(KEY_F(38)) } },
{ L"<a-f3>", { K(KEY_F(39)) } },
{ L"<a-f4>", { K(KEY_F(40)) } },
{ L"<a-f5>", { K(KEY_F(41)) } },
{ L"<a-f6>", { K(KEY_F(42)) } },
{ L"<a-f7>", { K(KEY_F(43)) } },
{ L"<a-f8>", { K(KEY_F(44)) } },
{ L"<a-f9>", { K(KEY_F(45)) } },
{ L"<a-f10>", { K(KEY_F(46)) } },
{ L"<a-f11>", { K(KEY_F(47)) } },
{ L"<a-f12>", { K(KEY_F(48)) } },
{ L"<m-f1>", { K(KEY_F(37)) } },
{ L"<m-f2>", { K(KEY_F(38)) } },
{ L"<m-f3>", { K(KEY_F(39)) } },
{ L"<m-f4>", { K(KEY_F(40)) } },
{ L"<m-f5>", { K(KEY_F(41)) } },
{ L"<m-f6>", { K(KEY_F(42)) } },
{ L"<m-f7>", { K(KEY_F(43)) } },
{ L"<m-f8>", { K(KEY_F(44)) } },
{ L"<m-f9>", { K(KEY_F(45)) } },
{ L"<m-f10>", { K(KEY_F(46)) } },
{ L"<m-f11>", { K(KEY_F(47)) } },
{ L"<m-f12>", { K(KEY_F(48)) } },
#endif
};
void
init_bracket_notation(void)
{
size_t i;
for(i = 0; i < ARRAY_LEN(key_pairs); i++)
{
key_pairs[i].len = wcslen(key_pairs[i].notation);
}
safe_qsort(key_pairs, ARRAY_LEN(key_pairs), sizeof(key_pairs[0]),
notation_sorter);
}
static int
notation_sorter(const void *first, const void *second)
{
const key_pair_t *paira = (const key_pair_t *)first;
const key_pair_t *pairb = (const key_pair_t *)second;
const wchar_t *stra = paira->notation;
const wchar_t *strb = pairb->notation;
return wcscmp(stra, strb);
}
wchar_t *
substitute_specs(const char cmd[])
{
wchar_t *result;
wchar_t *const cmdw = to_wide(cmd);
if(cmdw == NULL)
{
return NULL;
}
result = substitute_specsw(cmdw);
free(cmdw);
return result;
}
wchar_t *
substitute_specsw(const wchar_t cmd[])
{
wchar_t *buf, *p;
const size_t len = wcslen(cmd) + 1;
const wchar_t *s = cmd;
buf = reallocarray(NULL, len, sizeof(wchar_t));
if(buf == NULL)
{
return NULL;
}
p = buf;
while(*s != L'\0')
{
const key_pair_t *const pair = find_notation(s);
if(pair == NULL)
{
*p++ = *s++;
}
else
{
wcscpy(p, pair->key);
p += wcslen(p);
s += pair->len;
}
}
*p = L'\0';
assert((size_t)(p + 1 - buf) <= len && "Destination buffer was too small.");
return buf;
}
const wchar_t *
spec_to_wstr(const char str[])
{
wchar_t wide[strlen(str) + 1];
int i;
for(i = 0; str[i] != '\0'; ++i)
{
wide[i] = (unsigned char)str[i];
}
wide[i] = L'\0';
const key_pair_t *pair = find_notation(wide);
if(pair == NULL)
{
return NULL;
}
return pair->key;
}
* str wasn't found in the list. */
static const key_pair_t *
find_notation(const wchar_t str[])
{
wchar_t str_lowered[wcslen(str) + 1];
int l = 0, u = ARRAY_LEN(key_pairs) - 1;
wcscpy(str_lowered, str);
wcstolower(str_lowered);
while(l <= u)
{
const int i = l + (u - l)/2;
const key_pair_t *const key_pair = &key_pairs[i];
const int comp = wcsncmp(str_lowered, key_pair->notation, key_pair->len);
if(comp == 0)
{
return key_pair;
}
else if(comp < 0)
{
u = i - 1;
}
else
{
l = i + 1;
}
}
return NULL;
}
char *
wstr_to_spec(const wchar_t str[])
{
vle_textbuf *const descr = vle_tb_create();
const size_t str_len = wcslen(str);
size_t seq_len;
size_t i;
for(i = 0U; i < str_len; i += seq_len)
{
if(str[i] == L' ' && i != 0U && i != str_len - 1)
{
vle_tb_append(descr, " ");
seq_len = 1U;
}
else
{
vle_tb_append(descr, wchar_to_spec(&str[i], &seq_len, (i == 0U)));
}
}
return vle_tb_release(descr);
}
* corresponding key. Upon exit *len is set to number of used characters from
* the string. Returns pointer to internal buffer. */
static const char *
wchar_to_spec(const wchar_t c[], size_t *len, int bs)
{
static char buf[256];
*len = 1;
switch(*c)
{
case L' ': strcpy(buf, "<space>"); break;
case L'\r': strcpy(buf, "<cr>"); break;
case L'\n': strcpy(buf, "<c-j>"); break;
case L'\177': strcpy(buf, "<del>"); break;
case L'<': strcpy(buf, "<lt>"); break;
case K(KEY_HOME): strcpy(buf, "<home>"); break;
case K(KEY_END): strcpy(buf, "<end>"); break;
case K(KEY_UP): strcpy(buf, "<up>"); break;
case K(KEY_DOWN): strcpy(buf, "<down>"); break;
case K(KEY_LEFT): strcpy(buf, "<left>"); break;
case K(KEY_RIGHT): strcpy(buf, "<right>"); break;
case K(KEY_DC): strcpy(buf, "<delete>"); break;
case K(KEY_BTAB): strcpy(buf, "<s-tab>"); break;
case K(KEY_PPAGE): strcpy(buf, "<pageup>"); break;
case K(KEY_NPAGE): strcpy(buf, "<pagedown>"); break;
case K(KEY_SHOME): strcpy(buf, "<s-home>"); break;
case K(KEY_SEND): strcpy(buf, "<s-end>"); break;
case K(KEY_SR): strcpy(buf, "<s-up>"); break;
case K(KEY_SF): strcpy(buf, "<s-down>"); break;
case K(KEY_SLEFT): strcpy(buf, "<s-left>"); break;
case K(KEY_SRIGHT): strcpy(buf, "<s-right>"); break;
case K(KEY_SDC): strcpy(buf, "<s-delete>"); break;
case K(KEY_SIC): strcpy(buf, "<s-insert>"); break;
case K(KEY_SPREVIOUS): strcpy(buf, "<s-pageup>"); break;
case K(KEY_SNEXT): strcpy(buf, "<s-pagedown>"); break;
case WC_C_SPACE: strcpy(buf, "<c-@>"); break;
case L'\b':
if(!bs)
{
goto def;
}
case K(KEY_BACKSPACE):
strcpy(buf, "<bs>");
break;
case L'\033':
if(c[1] == L'[' && c[2] == 'Z')
{
strcpy(buf, "<s-tab>");
*len += 2;
break;
}
if(c[1] != L'\0' && c[1] != L'\033')
{
if(isupper(c[1]))
{
strcpy(buf, "<a-s-a>");
buf[5] += c[1] - L'A';
}
else
{
strcpy(buf, "<a-a>");
buf[3] += c[1] - L'a';
}
++*len;
break;
}
strcpy(buf, "<esc>");
break;
default:
def:
if(*c == '\n' || (*c > L' ' && *c < 256))
{
buf[0] = *c;
buf[1] = '\0';
}
else if(*c >= K(KEY_F0) && *c < K(KEY_F0) + 10)
{
strcpy(buf, "<f0>");
buf[2] += *c - K(KEY_F0);
}
else if(*c >= K(KEY_F0) + 13 && *c <= K(KEY_F0) + 21)
{
strcpy(buf, "<s-f1>");
buf[4] += *c - (K(KEY_F0) + 13);
}
else if(*c >= K(KEY_F0) + 22 && *c <= K(KEY_F0) + 24)
{
strcpy(buf, "<s-f10>");
buf[5] += *c - (K(KEY_F0) + 22);
}
else if(*c >= K(KEY_F0) + 25 && *c <= K(KEY_F0) + 33)
{
strcpy(buf, "<c-f1>");
buf[4] += *c - (K(KEY_F0) + 25);
}
else if(*c >= K(KEY_F0) + 34 && *c <= K(KEY_F0) + 36)
{
strcpy(buf, "<c-f10>");
buf[5] += *c - (K(KEY_F0) + 34);
}
else if(*c >= K(KEY_F0) + 37 && *c <= K(KEY_F0) + 45)
{
strcpy(buf, "<a-f1>");
buf[4] += *c - (K(KEY_F0) + 37);
}
else if(*c >= K(KEY_F0) + 46 && *c <= K(KEY_F0) + 48)
{
strcpy(buf, "<a-f10>");
buf[5] += *c - (K(KEY_F0) + 46);
}
else if(*c >= K(KEY_F0) + 10 && *c < K(KEY_F0) + 63)
{
strcpy(buf, "<f00>");
buf[2] += (*c - K(KEY_F0))/10;
buf[3] += (*c - K(KEY_F0))%10;
}
else if(iswcntrl(*c))
{
strcpy(buf, "<c-A>");
buf[3] = tolower(buf[3] + *c - 1);
}
else
{
const wchar_t wchar[] = { *c, L'\0' };
char *const mb = to_multibyte(wchar);
copy_str(buf, sizeof(buf), mb);
free(mb);
}
break;
}
return buf;
}