commit 0ac206aa676b56346dd45906fe0379a1e845fb80
parent 25deb9532df29d093281a2b542be2463809d7379
Author: lumidify <nobody@lumidify.org>
Date: Thu, 20 May 2021 21:37:00 +0200
Add support for Ctrl-c and Ctrl-v
Diffstat:
M | Makefile | | | 2 | +- |
M | buffer.c | | | 54 | ++++++++++++++++++++++++++++++++++++++++++++++-------- |
M | buffer.h | | | 6 | ++++++ |
M | ledit.c | | | 203 | +++++++++++++++++++++++++++++++++++++++++++++---------------------------------- |
4 files changed, 170 insertions(+), 95 deletions(-)
diff --git a/Makefile b/Makefile
@@ -12,7 +12,7 @@ MAN1 = ${BIN:=.1}
OBJ = ${BIN:=.o} cache.o buffer.o memory.o
HDR = cache.h buffer.h memory.h common.h
-CFLAGS_LEDIT = ${CFLAGS} -g -Wall -Wextra -D_POSIX_C_SOURCE=200809L `pkg-config --cflags x11 xkbfile pangoxft xext`
+CFLAGS_LEDIT = -g -Wall -Wextra -D_POSIX_C_SOURCE=200809L `pkg-config --cflags x11 xkbfile pangoxft xext`
LDFLAGS_LEDIT = ${LDFLAGS} `pkg-config --libs x11 xkbfile pangoxft xext` -lm
all: ${BIN}
diff --git a/buffer.c b/buffer.c
@@ -1,3 +1,7 @@
+/* FIXME: shrink buffers when text length less than a fourth of the size */
+
+#include <string.h>
+
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <pango/pangoxft.h>
@@ -101,20 +105,49 @@ ledit_insert_text(ledit_buffer *buffer, int line_index, int index, char *text, i
ledit_line *line = &buffer->lines[line_index];
if (len == -1)
len = strlen(text);
- if (line->len + len > line->cap) {
- line->cap *= 2;
- if (line->cap == 0)
- line->cap = 2;
+ if (line->len + len > line->cap || line->text == NULL) {
+ /* FIXME: read up on what the best values are here */
+ line->cap = line->cap * 2 > line->len + len ? line->cap * 2 : line->len + len;
line->text = ledit_realloc(line->text, line->cap);
}
memmove(line->text + index + len, line->text + index, line->len - index);
memcpy(line->text + index, text, len);
line->len += len;
pango_layout_set_text(line->layout, line->text, line->len);
- recalc_single_line_size(buffer, line_index);
+ /*recalc_single_line_size(buffer, line_index);*/
line->dirty = 1;
}
+static void append_line_impl(ledit_buffer *buffer, int line_index, int text_index);
+
+void
+ledit_insert_text_with_newlines(
+ ledit_buffer *buffer,
+ int line_index, int index,
+ char *text, int len,
+ int *end_line_ret, int *end_char_ret) {
+ if (len == -1)
+ len = strlen(text);
+ char *cur, *last = text;
+ int cur_line = line_index;
+ int cur_index = index;
+ while ((cur = strchr(last, '\n'))) {
+ ledit_insert_text(buffer, cur_line, cur_index, last, cur - last);
+ /* FIXME: inefficient because there's no gap buffer yet */
+ append_line_impl(buffer, cur_line, -1);
+ cur_index = 0;
+ cur_line++;
+ last = cur + 1;
+ }
+ /* FIXME: check how legal this casting between pointers and ints is */
+ ledit_insert_text(buffer, cur_line, cur_index, last, text + len - last);
+ if (end_line_ret)
+ *end_line_ret = cur_line;
+ if (end_char_ret)
+ *end_char_ret = cur_index + text + len - last;
+ recalc_line_size_absolute(buffer); /* FIXME: make this more efficient */
+}
+
void
ledit_render_line(ledit_buffer *buffer, int line_index) {
/* FIXME: check for <= 0 on size */
@@ -171,8 +204,8 @@ init_line(ledit_buffer *buffer, ledit_line *line) {
}
/* FIXME: error checking (index out of bounds, etc.) */
-void
-ledit_append_line(ledit_buffer *buffer, int line_index, int text_index) {
+static void
+append_line_impl(ledit_buffer *buffer, int line_index, int text_index) {
if (buffer->lines_num >= buffer->lines_cap) {
buffer->lines_cap *= 2;
if (buffer->lines_cap == 0)
@@ -201,6 +234,11 @@ ledit_append_line(ledit_buffer *buffer, int line_index, int text_index) {
pango_layout_set_text(l->layout, l->text, l->len);
/* FIXME: set height here */
}
+}
+
+void
+ledit_append_line(ledit_buffer *buffer, int line_index, int text_index) {
+ append_line_impl(buffer, line_index, text_index);
recalc_line_size_absolute(buffer);
}
@@ -281,7 +319,7 @@ ledit_delete_unicode_char(ledit_buffer *buffer, int line_index, int byte_index,
ledit_line *l = ledit_get_line(buffer, line_index);
int new_index = byte_index;
if (dir < 0) {
- int i = buffer->cur_index - 1;
+ int i = byte_index - 1;
/* find valid utf8 char - this probably needs to be improved */
while (i > 0 && ((l->text[i] & 0xC0) == 0x80))
i--;
diff --git a/buffer.h b/buffer.h
@@ -44,6 +44,12 @@ void ledit_set_line_selection(ledit_buffer *buffer, int line, int start_byte, in
void ledit_set_line_cursor_attrs(ledit_buffer *buffer, int line, int index);
void ledit_wipe_line_cursor_attrs(ledit_buffer *buffer, int line);
void ledit_insert_text(ledit_buffer *buffer, int line_index, int index, char *text, int len);
+void ledit_insert_text_with_newlines(
+ ledit_buffer *buffer,
+ int line_index, int index,
+ char *text, int len,
+ int *end_line_ret, int *end_char_ret
+);
void ledit_render_line(ledit_buffer *buffer, int line_index);
void ledit_append_line(ledit_buffer *buffer, int line_index, int text_index);
void ledit_delete_line_entries(ledit_buffer *buffer, int index1, int index2);
diff --git a/ledit.c b/ledit.c
@@ -1,3 +1,4 @@
+/* FIXME: Fix lag when selecting with mouse */
/* FIXME: Use PANGO_PIXELS() */
/* FIXME: Fix cursor movement, especially buffer->trailing and writing at end of line */
/* FIXME: horizontal scrolling (also need cache to avoid too large pixmaps) */
@@ -43,6 +44,7 @@ enum key_type {
struct key {
char *text; /* for keys that correspond with text */
+ unsigned int mods; /* modifier mask */
KeySym keysym; /* for other keys, e.g. arrow keys */
enum ledit_mode modes; /* modes in which this keybinding is functional */
enum key_type prev_keys; /* allowed previous keys */
@@ -240,23 +242,12 @@ selnotify(XEvent *e)
continue;
}
- /* FIXME: Is this needed for ledit? I don't think so, right? */
- /*
- * As seen in getsel:
- * Line endings are inconsistent in the terminal and GUI world
- * copy and pasting. When receiving some selection data,
- * replace all '\n' with '\r'.
- * FIXME: Fix the computer world.
- */
- /*
- repl = data;
- last = data + nitems * format / 8;
- while ((repl = memchr(repl, '\n', last - repl))) {
- *repl++ = '\r';
- }
- */
-
- printf("%.*s\n", (int)(nitems * format / 8), (char*)data);
+ ledit_insert_text_with_newlines(
+ buffer,
+ buffer->cur_line, buffer->cur_index,
+ (char*)data, (int)(nitems * format / 8),
+ &buffer->cur_line, &buffer->cur_index
+ );
XFree(data);
/* number of 32-bit chunks returned */
ofs += nitems * format / 32;
@@ -670,9 +661,11 @@ mainloop(void) {
running = 0;
break;
case SelectionNotify:
+ need_redraw = 1;
selnotify(&event);
break;
case PropertyNotify:
+ need_redraw = 1;
propnotify(&event);
break;
case SelectionRequest:
@@ -1011,6 +1004,7 @@ sort_selection(int *line1, int *byte1, int *line2, int *byte2) {
}
}
+/* FIXME: don't reset selection when selection is clicked away */
/* FIXME: when selecting with mouse, only call this when button is released */
/* lines and bytes need to be sorted already! */
static void
@@ -1240,9 +1234,10 @@ backspace(void) {
ledit_line *l1 = ledit_get_line(buffer, buffer->cur_line - 1);
ledit_line *l2 = ledit_get_line(buffer, buffer->cur_line);
int old_len = l1->len;
- ledit_insert_text(
+ ledit_insert_text_with_newlines(
buffer, buffer->cur_line - 1,
- l1->len, l2->text, l2->len
+ l1->len, l2->text, l2->len,
+ NULL, NULL
);
ledit_delete_line_entry(buffer, buffer->cur_line);
buffer->cur_line--;
@@ -1267,9 +1262,10 @@ delete_key(void) {
buffer, buffer->cur_line + 1
);
int old_len = cur_line->len;
- ledit_insert_text(
+ ledit_insert_text_with_newlines(
buffer, buffer->cur_line, cur_line->len,
- next_line->text, next_line->len
+ next_line->text, next_line->len,
+ NULL, NULL
);
ledit_delete_line_entry(buffer, buffer->cur_line + 1);
buffer->cur_index = old_len;
@@ -1338,7 +1334,7 @@ move_cursor_left_right(int dir) {
new_index = cur_line->len;
}
}
- if (e != NULL & e->motion_cb != NULL) {
+ if (e != NULL && e->motion_cb != NULL) {
e->motion_cb(buffer->cur_line, new_index, KEY_MOTION_CHAR);
} else {
buffer->cur_index = new_index;
@@ -1473,7 +1469,7 @@ static void
cursor_to_beginning(void) {
struct key_stack_elem *e = pop_key_stack();
/* FIXME: error when no callback? */
- if (e != NULL & e->motion_cb != NULL) {
+ if (e != NULL && e->motion_cb != NULL) {
e->motion_cb(buffer->cur_line, 0, KEY_MOTION_CHAR);
} else {
buffer->cur_index = 0;
@@ -1508,71 +1504,75 @@ switch_selection_end(void) {
buffer->cur_index = buffer->sel.byte2;
}
+#define XK_ANY_MOD UINT_MAX
+#define XK_NO_MOD 0
+
static struct key keys_en[] = {
- {NULL, XK_BackSpace, INSERT, KEY_ANY, KEY_ANY, &backspace},
- {NULL, XK_Left, VISUAL|INSERT|NORMAL, KEY_ANY, KEY_ANY, &cursor_left},
- {NULL, XK_Right, VISUAL|INSERT|NORMAL, KEY_ANY, KEY_ANY, &cursor_right},
- {NULL, XK_Up, VISUAL|INSERT|NORMAL, KEY_ANY, KEY_ANY, &cursor_up},
- {NULL, XK_Down, VISUAL|INSERT|NORMAL, KEY_ANY, KEY_ANY, &cursor_down},
- {NULL, XK_Return, INSERT, KEY_ANY, KEY_ANY, &return_key},
- {NULL, XK_Delete, INSERT, KEY_ANY, KEY_ANY, &delete_key},
- {NULL, XK_Escape, VISUAL|INSERT, KEY_ANY, KEY_ANY, &escape_key},
- {"i", 0, NORMAL|VISUAL, KEY_ANY, KEY_ANY, &enter_insert},
- {"h", 0, NORMAL|VISUAL, KEY_ANY, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_left},
- {"l", 0, NORMAL|VISUAL, KEY_ANY, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_right},
- {"j", 0, NORMAL|VISUAL, KEY_ANY, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_down},
- {"k", 0, NORMAL|VISUAL, KEY_ANY, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_up},
- {"0", 0, NORMAL|VISUAL, ~KEY_NUMBER, KEY_ANY, &cursor_to_beginning},
- {"0", 0, NORMAL|VISUAL, KEY_NUMBER, KEY_NUMBER, &push_0},
- {"1", 0, NORMAL|VISUAL, KEY_ANY, KEY_NUMBER, &push_1},
- {"2", 0, NORMAL|VISUAL, KEY_ANY, KEY_NUMBER, &push_2},
- {"3", 0, NORMAL|VISUAL, KEY_ANY, KEY_NUMBER, &push_3},
- {"4", 0, NORMAL|VISUAL, KEY_ANY, KEY_NUMBER, &push_4},
- {"5", 0, NORMAL|VISUAL, KEY_ANY, KEY_NUMBER, &push_5},
- {"6", 0, NORMAL|VISUAL, KEY_ANY, KEY_NUMBER, &push_6},
- {"7", 0, NORMAL|VISUAL, KEY_ANY, KEY_NUMBER, &push_7},
- {"8", 0, NORMAL|VISUAL, KEY_ANY, KEY_NUMBER, &push_8},
- {"9", 0, NORMAL|VISUAL, KEY_ANY, KEY_NUMBER, &push_9},
- {"x", 0, NORMAL, KEY_ANY, KEY_NUMBERALLOWED, &key_x},
- {"d", 0, NORMAL|VISUAL, KEY_ANY, KEY_MOTION|KEY_NUMBERALLOWED, &key_d},
- {"v", 0, NORMAL, KEY_ANY, KEY_ANY, &enter_visual},
- {"o", 0, VISUAL, KEY_ANY, KEY_ANY, &switch_selection_end},
- {"y", 0, NORMAL|VISUAL, KEY_ANY, KEY_ANY, &clipcopy},
- {"p", 0, NORMAL|VISUAL, KEY_ANY, KEY_ANY, &clippaste}
+ {NULL, 0, XK_BackSpace, INSERT, KEY_ANY, KEY_ANY, &backspace},
+ {NULL, 0, XK_Left, VISUAL|INSERT|NORMAL, KEY_ANY, KEY_ANY, &cursor_left},
+ {NULL, 0, XK_Right, VISUAL|INSERT|NORMAL, KEY_ANY, KEY_ANY, &cursor_right},
+ {NULL, 0, XK_Up, VISUAL|INSERT|NORMAL, KEY_ANY, KEY_ANY, &cursor_up},
+ {NULL, 0, XK_Down, VISUAL|INSERT|NORMAL, KEY_ANY, KEY_ANY, &cursor_down},
+ {NULL, 0, XK_Return, INSERT, KEY_ANY, KEY_ANY, &return_key},
+ {NULL, 0, XK_Delete, INSERT, KEY_ANY, KEY_ANY, &delete_key},
+ {NULL, 0, XK_Escape, VISUAL|INSERT, KEY_ANY, KEY_ANY, &escape_key},
+ {"i", 0, 0, NORMAL|VISUAL, KEY_ANY, KEY_ANY, &enter_insert},
+ {"h", 0, 0, NORMAL|VISUAL, KEY_ANY, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_left},
+ {"l", 0, 0, NORMAL|VISUAL, KEY_ANY, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_right},
+ {"j", 0, 0, NORMAL|VISUAL, KEY_ANY, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_down},
+ {"k", 0, 0, NORMAL|VISUAL, KEY_ANY, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_up},
+ {"0", 0, 0, NORMAL|VISUAL, ~KEY_NUMBER, KEY_ANY, &cursor_to_beginning},
+ {"0", 0, 0, NORMAL|VISUAL, KEY_NUMBER, KEY_NUMBER, &push_0},
+ {"1", 0, 0, NORMAL|VISUAL, KEY_ANY, KEY_NUMBER, &push_1},
+ {"2", 0, 0, NORMAL|VISUAL, KEY_ANY, KEY_NUMBER, &push_2},
+ {"3", 0, 0, NORMAL|VISUAL, KEY_ANY, KEY_NUMBER, &push_3},
+ {"4", 0, 0, NORMAL|VISUAL, KEY_ANY, KEY_NUMBER, &push_4},
+ {"5", 0, 0, NORMAL|VISUAL, KEY_ANY, KEY_NUMBER, &push_5},
+ {"6", 0, 0, NORMAL|VISUAL, KEY_ANY, KEY_NUMBER, &push_6},
+ {"7", 0, 0, NORMAL|VISUAL, KEY_ANY, KEY_NUMBER, &push_7},
+ {"8", 0, 0, NORMAL|VISUAL, KEY_ANY, KEY_NUMBER, &push_8},
+ {"9", 0, 0, NORMAL|VISUAL, KEY_ANY, KEY_NUMBER, &push_9},
+ {"x", 0, 0, NORMAL, KEY_ANY, KEY_NUMBERALLOWED, &key_x},
+ {"d", 0, 0, NORMAL|VISUAL, KEY_ANY, KEY_MOTION|KEY_NUMBERALLOWED, &key_d},
+ {"v", 0, 0, NORMAL, KEY_ANY, KEY_ANY, &enter_visual},
+ {"o", 0, 0, VISUAL, KEY_ANY, KEY_ANY, &switch_selection_end},
+ {"c", ControlMask, 0, INSERT|VISUAL, KEY_ANY, KEY_ANY, &clipcopy},
+ {"v", ControlMask, 0, INSERT, KEY_ANY, KEY_ANY, &clippaste}
};
static struct key keys_ur[] = {
- {NULL, XK_BackSpace, INSERT, KEY_ANY, KEY_ANY, &backspace},
- {NULL, XK_Left, INSERT|NORMAL, KEY_ANY, KEY_ANY, &cursor_left},
- {NULL, XK_Right, INSERT|NORMAL, KEY_ANY, KEY_ANY, &cursor_right},
- {NULL, XK_Up, INSERT|NORMAL, KEY_ANY, KEY_ANY, &cursor_up},
- {NULL, XK_Down, INSERT|NORMAL, KEY_ANY, KEY_ANY, &cursor_down},
- {NULL, XK_Return, INSERT, KEY_ANY, KEY_ANY, &return_key},
- {NULL, XK_Delete, INSERT, KEY_ANY, KEY_ANY, &delete_key},
- {NULL, XK_Escape, INSERT, KEY_ANY, KEY_ANY, &escape_key},
- {"ی", 0, NORMAL, KEY_ANY, KEY_ANY, &enter_insert},
- {"ح", 0, NORMAL, KEY_ANY, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_left},
- {"ل", 0, NORMAL, KEY_ANY, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_right},
- {"ج", 0, NORMAL, KEY_ANY, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_down},
- {"ک", 0, NORMAL, KEY_ANY, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_up},
- {"0", 0, NORMAL, KEY_ANY, KEY_ANY, &cursor_to_beginning}
+ {NULL, 0, XK_BackSpace, INSERT, KEY_ANY, KEY_ANY, &backspace},
+ {NULL, 0, XK_Left, INSERT|NORMAL, KEY_ANY, KEY_ANY, &cursor_left},
+ {NULL, 0, XK_Right, INSERT|NORMAL, KEY_ANY, KEY_ANY, &cursor_right},
+ {NULL, 0, XK_Up, INSERT|NORMAL, KEY_ANY, KEY_ANY, &cursor_up},
+ {NULL, 0, XK_Down, INSERT|NORMAL, KEY_ANY, KEY_ANY, &cursor_down},
+ {NULL, 0, XK_Return, INSERT, KEY_ANY, KEY_ANY, &return_key},
+ {NULL, 0, XK_Delete, INSERT, KEY_ANY, KEY_ANY, &delete_key},
+ {NULL, 0, XK_Escape, INSERT, KEY_ANY, KEY_ANY, &escape_key},
+ {"ی", 0, 0, NORMAL, KEY_ANY, KEY_ANY, &enter_insert},
+ {"ح", 0, 0, NORMAL, KEY_ANY, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_left},
+ {"ل", 0, 0, NORMAL, KEY_ANY, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_right},
+ {"ج", 0, 0, NORMAL, KEY_ANY, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_down},
+ {"ک", 0, 0, NORMAL, KEY_ANY, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_up},
+ {"0", 0, 0, NORMAL, KEY_ANY, KEY_ANY, &cursor_to_beginning},
+ {"چ", ControlMask, 0, INSERT|VISUAL, KEY_ANY, KEY_ANY, &clipcopy}
};
static struct key keys_hi[] = {
- {NULL, XK_BackSpace, INSERT, KEY_ANY, KEY_ANY, &backspace},
- {NULL, XK_Left, INSERT|NORMAL, KEY_ANY, KEY_ANY, &cursor_left},
- {NULL, XK_Right, INSERT|NORMAL, KEY_ANY, KEY_ANY, &cursor_right},
- {NULL, XK_Up, INSERT|NORMAL, KEY_ANY, KEY_ANY, &cursor_up},
- {NULL, XK_Down, INSERT|NORMAL, KEY_ANY, KEY_ANY, &cursor_down},
- {NULL, XK_Return, INSERT, KEY_ANY, KEY_ANY, &return_key},
- {NULL, XK_Delete, INSERT, KEY_ANY, KEY_ANY, &delete_key},
- {NULL, XK_Escape, INSERT, KEY_ANY, KEY_ANY, &escape_key},
- {"ि", 0, NORMAL, KEY_ANY, KEY_ANY, &enter_insert},
- {"ह", 0, NORMAL, KEY_ANY, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_left},
- {"ल", 0, NORMAL, KEY_ANY, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_right},
- {"ज", 0, NORMAL, KEY_ANY, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_down},
- {"क", 0, NORMAL, KEY_ANY, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_up},
- {"0", 0, NORMAL, KEY_ANY, KEY_ANY, &cursor_to_beginning}
+ {NULL, 0, XK_BackSpace, INSERT, KEY_ANY, KEY_ANY, &backspace},
+ {NULL, 0, XK_Left, INSERT|NORMAL, KEY_ANY, KEY_ANY, &cursor_left},
+ {NULL, 0, XK_Right, INSERT|NORMAL, KEY_ANY, KEY_ANY, &cursor_right},
+ {NULL, 0, XK_Up, INSERT|NORMAL, KEY_ANY, KEY_ANY, &cursor_up},
+ {NULL, 0, XK_Down, INSERT|NORMAL, KEY_ANY, KEY_ANY, &cursor_down},
+ {NULL, 0, XK_Return, INSERT, KEY_ANY, KEY_ANY, &return_key},
+ {NULL, 0, XK_Delete, INSERT, KEY_ANY, KEY_ANY, &delete_key},
+ {NULL, 0, XK_Escape, INSERT, KEY_ANY, KEY_ANY, &escape_key},
+ {"ि", 0, 0, NORMAL, KEY_ANY, KEY_ANY, &enter_insert},
+ {"ह", 0, 0, NORMAL, KEY_ANY, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_left},
+ {"ल", 0, 0, NORMAL, KEY_ANY, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_right},
+ {"ज", 0, 0, NORMAL, KEY_ANY, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_down},
+ {"क", 0, 0, NORMAL, KEY_ANY, KEY_MOTION | KEY_NUMBERALLOWED, &cursor_up},
+ {"0", 0, 0, NORMAL, KEY_ANY, KEY_ANY, &cursor_to_beginning}
};
#define LENGTH(X) (sizeof(X) / sizeof(X[0]))
@@ -1602,10 +1602,37 @@ static void change_keyboard(char *lang) {
}
}
+/* FIXME: Does this break anything? */
+static unsigned int importantmod = ShiftMask | ControlMask | Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask;
+
+static int
+match(unsigned int mask, unsigned int state)
+{
+ return mask == XK_ANY_MOD || mask == (state & importantmod);
+}
+
static void
key_press(XEvent event) {
char buf[32];
KeySym sym;
+ /*
+ * FIXME: I don't understand how key handling works with different keymaps.
+ * If, for instance, you run "setxkbmap pk" and then type "Ctrl+c", the
+ * keysym will be "0x1000686, Arabic_tcheh" and the appropriate string will
+ * be returned by XmbLookupString (tested also using xev).
+ * If, however, you run "setxkbmap -layout "us,pk" -option grp:shifts_toggle"
+ * and type "Ctrl+c" after switching to the pk layout, the keysym will just
+ * be "0x63, c" and XmbLookupString will return the control code sent by
+ * Ctrl+c (ascii 03). This means the handling is different depending on how
+ * the keymap is switched to, and I have no clue what the proper way to
+ * handle this would be, since the shortcuts are explicitly supposed to work
+ * properly in all language maps. My current solution is to just ignore the
+ * control key in the state so the text found by Xutf8LookupString is correct
+ * and the modifier mask can be checked separately. Please tell me if you
+ * know the proper way to do this.
+ */
+ unsigned int key_state = event.xkey.state;
+ event.xkey.state &= ~ControlMask;
/* FIXME: X_HAVE_UTF8_STRING See XmbLookupString(3) */
int n = Xutf8LookupString(
state.xic, &event.xkey, buf, sizeof(buf), &sym, NULL
@@ -1617,12 +1644,14 @@ key_press(XEvent event) {
if (n > 0 &&
(cur_keys->keys[i].modes & state.mode) &&
(!e || (e->key & cur_keys->keys[i].prev_keys)) &&
- !strncmp(cur_keys->keys[i].text, buf, n)) {
+ !strncmp(cur_keys->keys[i].text, buf, n) &&
+ match(cur_keys->keys[i].mods, key_state)) {
cur_keys->keys[i].func();
found = 1;
}
} else if ((cur_keys->keys[i].modes & state.mode) &&
- cur_keys->keys[i].keysym == sym) {
+ cur_keys->keys[i].keysym == sym &&
+ match(cur_keys->keys[i].mods, key_state)) {
cur_keys->keys[i].func();
found = 1;
}
@@ -1631,10 +1660,12 @@ key_press(XEvent event) {
}
if (state.mode == INSERT && !found && n > 0) {
delete_selection();
- ledit_insert_text(
- buffer, buffer->cur_line, buffer->cur_index, buf, n
+ ledit_insert_text_with_newlines(
+ buffer,
+ buffer->cur_line, buffer->cur_index,
+ buf, n,
+ &buffer->cur_line, &buffer->cur_index
);
- buffer->cur_index += n;
}
ensure_cursor_shown();
}