tex: cm command to change keymap - neatvi - [fork] simple vi-type editor with UTF-8 support
(HTM) git clone git://src.adamsgaard.dk/neatvi
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
---
(DIR) commit 3a4ce478980b560dd436c5fd93e867b1adb35c6a
(DIR) parent 327a8df78c89d94f7074d6a5881f222287d8fddc
(HTM) Author: Ali Gholami Rudi <ali@rudi.ir>
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(-)
---
(DIR) 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.
(DIR) 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;
+}
(DIR) 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))
(DIR) diff --git a/ex.c b/ex.c
t@@ -21,6 +21,8 @@ int xshape = 1; /* perform letter shaping */
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},
};
(DIR) 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", "+"},
(DIR) 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, int ai_max, int *key, ch
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:
(DIR) diff --git a/vi.c b/vi.c
t@@ -17,7 +17,6 @@ static char vi_charlast[8]; /* the last character searched via f, t, F, or T */
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 command */
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;
(DIR) 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;