tex: cm command to change keymap - neatvi - [fork] simple vi-type editor with U… | |
git clone git://src.adamsgaard.dk/neatvi | |
Log | |
Files | |
Refs | |
README | |
--- | |
commit 3a4ce478980b560dd436c5fd93e867b1adb35c6a | |
parent 327a8df78c89d94f7074d6a5881f222287d8fddc | |
Author: Ali Gholami Rudi <[email protected]> | |
Date: Thu, 29 Oct 2015 19:40:33 +0330 | |
ex: cm command to change keymap | |
README explains how to add or switch keymaps. | |
Diffstat: | |
M README | 40 ++++++++++++++++++++++-------… | |
M conf.c | 25 ++++++++++++++++++++----- | |
M conf.h | 3 --- | |
M ex.c | 29 +++++++++++++++++++++++++++++ | |
M kmap.h | 2 ++ | |
M led.c | 27 ++++++--------------------- | |
M vi.c | 9 ++++----- | |
M vi.h | 5 ++++- | |
8 files changed, 93 insertions(+), 47 deletions(-) | |
--- | |
diff --git a/README b/README | |
t@@ -3,16 +3,31 @@ NEATVI | |
Neatvi is a vi/ex editor. It can edit bidirectional UTF-8 text. | |
-Edit conf.h to adjust syntax highlighting rules, direction adjustment | |
-patterns, and the alternate keymap. To define a new keymap, create a | |
-new array in kmap.h, like kmap_fa, and add it to kmaps array in led.c. | |
-When in input mode, ^f switches to the alternate keymap and ^e | |
-switches back to the default keymap. | |
+Edit conf.h to adjust syntax highlighting rules and text direction | |
+patterns. To define a new keymap, create a new array in kmap.h, like | |
+kmap_fa, and add it to kmaps array in the same header (the first entry | |
+of the new array specifies its name). The current keymap may be | |
+changed using :cm ex command. When in input mode, ^e changes to the | |
+English kaymap and ^f changes to the alternate keymap (the last keymap | |
+specified with :km). | |
-The following options are supported: | |
+Commands not available in ex(1): | |
+ | |
+:cm[ap][!] [kmap] | |
+ Without kmap, print the current keymap name. | |
+ When kmap is specified, set the alternate keymap to | |
+ kmap and, unless ! is given, switch to this keymap. | |
+ | |
+:ft [filetype] | |
+ Without filetype, print the current file type. | |
+ When filetype is specified, set the file type of the | |
+ current ex buffer. | |
+ | |
+Options supported by neatvi: | |
td, textdirection | |
- Current direction context. The following values are meaningful: | |
+ Current direction context. The following values are | |
+ meaningful: | |
* +2: always left-to-right. | |
* +1: follow conf.h's dircontexts[]; left-to-right for others. | |
t@@ -23,7 +38,12 @@ shape | |
If set (default), performs Arabic/Farsi letter shaping. | |
order | |
- If set, reorder characters based on the rules defined in conf.h. | |
+ If set, reorder characters based on the rules defined | |
+ in conf.h. | |
+ | |
+hl, highlight | |
+ If set (default), text will receive syntax highlighting | |
+ based on the rules in conf.h. | |
ai, autoindent | |
As in vi(1). | |
t@@ -33,7 +53,3 @@ aw, autowrite | |
ic, ignorecase | |
As in vi(1). | |
- | |
-hl, highlight | |
- If set (default), text will receive syntax highlighting based on the | |
- rules in conf.h. | |
diff --git a/conf.c b/conf.c | |
t@@ -1,11 +1,8 @@ | |
#include <stdio.h> | |
+#include <string.h> | |
#include "vi.h" | |
#include "conf.h" | |
- | |
-char *conf_kmapalt(void) | |
-{ | |
- return KMAPALT; | |
-} | |
+#include "kmap.h" | |
int conf_dirmark(int idx, char **pat, int *ctx, int *dir, int *grp) | |
{ | |
t@@ -77,3 +74,21 @@ int conf_highlight_revdir(int *att) | |
*att = SYN_REVDIR; | |
return 0; | |
} | |
+ | |
+char **conf_kmap(char *name) | |
+{ | |
+ int i; | |
+ for (i = 0; i < LEN(kmaps); i++) | |
+ if (name && kmaps[i][0] && !strcmp(name, kmaps[i][0])) | |
+ return kmaps[i]; | |
+ return kmap_en; | |
+} | |
+ | |
+char *conf_digraph(int c1, int c2) | |
+{ | |
+ int i; | |
+ for (i = 0; i < LEN(digraphs); i++) | |
+ if (digraphs[i][0][0] == c1 && digraphs[i][0][1] == c2) | |
+ return digraphs[i][1]; | |
+ return NULL; | |
+} | |
diff --git a/conf.h b/conf.h | |
t@@ -61,9 +61,6 @@ static struct highlight { | |
{"sh", {4}, "\'[^\']*\'"}, | |
}; | |
-/* the alternate keymap (^F and ^E in insert mode to switch) */ | |
-#define KMAPALT "fa" | |
- | |
/* how to hightlight text in the reverse direction */ | |
#define SYN_REVDIR (SYN_BGMK(255)) | |
diff --git a/ex.c b/ex.c | |
t@@ -21,6 +21,8 @@ int xshape = 1; /* perform letter sha… | |
int xorder = 1; /* change the order of characters */ | |
char xfindkwd[EXLEN]; /* the last searched keyword */ | |
int xfinddir = +1; /* the last search direction */ | |
+static char *xkmap = "en"; /* the current keymap */ | |
+static char xkmap2[8] = "fa"; /* the alternate keymap */ | |
static struct buf { | |
char ft[32]; | |
t@@ -96,6 +98,16 @@ char *ex_filetype(void) | |
return xhl ? bufs[0].ft : ""; | |
} | |
+char **ex_kmap(void) | |
+{ | |
+ return &xkmap; | |
+} | |
+ | |
+char *ex_kmapalt(void) | |
+{ | |
+ return xkmap2; | |
+} | |
+ | |
/* read ex command location */ | |
static char *ex_loc(char *s, char *loc) | |
{ | |
t@@ -690,6 +702,21 @@ static int ec_ft(char *ec) | |
return 0; | |
} | |
+static int ec_cmap(char *ec) | |
+{ | |
+ char cmd[EXLEN]; | |
+ char arg[EXLEN]; | |
+ ex_cmd(ec, cmd); | |
+ ex_arg(ec, arg); | |
+ if (arg[0]) | |
+ snprintf(xkmap2, sizeof(xkmap2), arg); | |
+ else | |
+ ex_print(xkmap); | |
+ if (arg[0] && !strchr(cmd, '!')) | |
+ xkmap = xkmap2; | |
+ return 0; | |
+} | |
+ | |
static struct option { | |
char *abbr; | |
char *name; | |
t@@ -784,6 +811,8 @@ static struct excmd { | |
{"!", "!", ec_exec}, | |
{"make", "make", ec_make}, | |
{"ft", "filetype", ec_ft}, | |
+ {"cm", "cmap", ec_cmap}, | |
+ {"cm!", "cmap!", ec_cmap}, | |
{"", "", ec_null}, | |
}; | |
diff --git a/kmap.h b/kmap.h | |
t@@ -100,6 +100,8 @@ static char *kmap_fa[256] = { | |
['|'] = "|", | |
}; | |
+static char **kmaps[] = {kmap_en, kmap_fa}; | |
+ | |
static char *digraphs[][2] = { | |
{"cq", "’"}, | |
{"pl", "+"}, | |
diff --git a/led.c b/led.c | |
t@@ -4,23 +4,11 @@ | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include "vi.h" | |
-#include "kmap.h" | |
- | |
-static char **kmaps[] = {kmap_en, kmap_fa}; | |
- | |
-static char **kmap_find(char *name) | |
-{ | |
- int i; | |
- for (i = 0; i < LEN(kmaps); i++) | |
- if (name && kmaps[i][0] && !strcmp(name, kmaps[i][0])) | |
- return kmaps[i]; | |
- return kmap_en; | |
-} | |
static char *kmap_map(char *kmap, int c) | |
{ | |
static char cs[4]; | |
- char **keymap = kmap_find(kmap); | |
+ char **keymap = conf_kmap(kmap); | |
cs[0] = c; | |
return keymap[c] ? keymap[c] : cs; | |
} | |
t@@ -198,10 +186,7 @@ static char *led_readchar(int c, char *kmap) | |
c2 = term_read(); | |
if (TK_INT(c2)) | |
return NULL; | |
- for (i = 0; i < LEN(digraphs); i++) | |
- if (digraphs[i][0][0] == c1 && digraphs[i][0][1] == c2) | |
- return digraphs[i][1]; | |
- return NULL; | |
+ return conf_digraph(c1, c2); | |
} | |
if ((c & 0xc0) == 0xc0) { /* utf-8 character */ | |
buf[0] = c; | |
t@@ -220,10 +205,10 @@ char *led_read(char **kmap) | |
while (!TK_INT(c)) { | |
switch (c) { | |
case TK_CTL('f'): | |
- *kmap = conf_kmapalt(); | |
+ *kmap = ex_kmapalt(); | |
break; | |
case TK_CTL('e'): | |
- *kmap = kmap_en[0]; | |
+ *kmap = "en"; | |
break; | |
default: | |
return led_readchar(c, *kmap); | |
t@@ -249,10 +234,10 @@ static char *led_line(char *pref, char *post, char *ai, … | |
c = term_read(); | |
switch (c) { | |
case TK_CTL('f'): | |
- *kmap = conf_kmapalt(); | |
+ *kmap = ex_kmapalt(); | |
continue; | |
case TK_CTL('e'): | |
- *kmap = kmap_en[0]; | |
+ *kmap = "en"; | |
continue; | |
case TK_CTL('h'): | |
case 127: | |
diff --git a/vi.c b/vi.c | |
t@@ -17,7 +17,6 @@ static char vi_charlast[8]; /* the last character sea… | |
static int vi_charcmd; /* the character finding command */ | |
static int vi_arg1, vi_arg2; /* the first and second arguments */ | |
static int vi_ybuf; /* current yank buffer */ | |
-static char *vi_kmap; /* current insertion keymap */ | |
static int vi_pcol; /* the column requested by | command */ | |
static int vi_printed; /* ex_print() calls since the last comma… | |
static int vi_scroll; /* scroll amount for ^f and ^d*/ | |
t@@ -79,7 +78,7 @@ static void vi_back(int c) | |
static char *vi_char(void) | |
{ | |
- return led_read(&vi_kmap); | |
+ return led_read(ex_kmap()); | |
} | |
static char *vi_prompt(char *msg, char **kmap) | |
t@@ -101,7 +100,7 @@ char *ex_read(char *msg) | |
struct sbuf *sb; | |
char c; | |
if (xled) { | |
- char *s = led_prompt(msg, "", &vi_kmap); | |
+ char *s = led_prompt(msg, "", ex_kmap()); | |
if (s) | |
term_chr('\n'); | |
return s; | |
t@@ -217,7 +216,7 @@ static int vi_search(int cmd, int cnt, int *row, int *off) | |
char *soff = ""; | |
if (cmd == '/' || cmd == '?') { | |
char sign[4] = {cmd}; | |
- char *kw = vi_prompt(sign, &vi_kmap); | |
+ char *kw = vi_prompt(sign, ex_kmap()); | |
if (!kw) | |
return 1; | |
xfinddir = cmd == '/' ? +1 : -1; | |
t@@ -618,7 +617,7 @@ static int charcount(char *text, char *post) | |
static char *vi_input(char *pref, char *post, int *row, int *off) | |
{ | |
- char *rep = led_input(pref, post, &vi_kmap); | |
+ char *rep = led_input(pref, post, ex_kmap()); | |
if (!rep) | |
return NULL; | |
*row = linecount(rep) - 1; | |
diff --git a/vi.h b/vi.h | |
t@@ -141,6 +141,8 @@ int ex_init(char **files); | |
void ex_done(void); | |
char *ex_path(void); | |
char *ex_filetype(void); | |
+char **ex_kmap(void); | |
+char *ex_kmapalt(void); | |
struct lbuf *ex_lbuf(void); | |
#define xb ex_lbuf() | |
t@@ -169,13 +171,14 @@ void syn_init(void); | |
void syn_done(void); | |
/* configuration variables */ | |
-char *conf_kmapalt(void); | |
int conf_dirmark(int idx, char **pat, int *ctx, int *dir, int *grp); | |
int conf_dircontext(int idx, char **pat, int *ctx); | |
int conf_placeholder(int idx, char **s, char **d, int *wid); | |
int conf_highlight(int idx, char **ft, int **att, char **pat, int *end); | |
int conf_filetype(int idx, char **ft, char **pat); | |
int conf_highlight_revdir(int *att); | |
+char **conf_kmap(char *name); | |
+char *conf_digraph(int c1, int c2); | |
/* global variables */ | |
extern int xrow; |