commit 36a12616e748e39265af475dbaee5e8356cc984a
parent 5d691e9f97b979d571d38c101554d72e91cb7db5
Author: lumidify <nobody@lumidify.org>
Date: Sun, 19 Sep 2021 19:27:06 +0200
Add basic support for commands
Diffstat:
6 files changed, 142 insertions(+), 35 deletions(-)
diff --git a/BUG b/BUG
@@ -0,0 +1,9 @@
+Random bugs noted down so I remember them; you are not expected to understand this
+deleting two lines in middle: leaves stray empty line without cursor; undo not right order;
+#0 0x00000d017890ccef in memcpy (dst0=0xd01adb5cf00, src0=0xd01c90a610b, length=18446744073709551566) at /usr/src/lib/libc/string/memcpy.c:97
+#1 0x00000cff1763be78 in ledit_insert_text_base (buffer=0xd01adb67300, line_index=6, index=0, text=0xd01c90a610b "\001\r", len=-50) at buffer.c:322
+#2 0x00000cff1763c516 in ledit_insert_text_with_newlines_base (buffer=0xd01adb67300, line_index=4, index=0,
+ text=0xd01c90a6080 "اسجد\233ا\204کسجدا\233س\204کجاس\233\204دکاج\233د\204کسادجا\233سداکج\204د\233ا\n", len=89, end_line_ret=0x0,
+ end_char_ret=0x0) at buffer.c:391
+#3 0x00000cff17640058 in ledit_undo (buffer=0xd01adb67300) at undo.c:172
+#4 0x00000cff17639d8a in undo () at ledit.c:1774
diff --git a/Makefile b/Makefile
@@ -9,8 +9,8 @@ MANPREFIX = ${PREFIX}/man
BIN = ${NAME}
MAN1 = ${BIN:=.1}
-OBJ = ${BIN:=.o} cache.o buffer.o memory.o util.o search.o lbuf.o undo.o
-HDR = cache.h buffer.h memory.h common.h util.h search.h lbuf.h undo.h
+OBJ = ${BIN:=.o} cache.o buffer.o memory.o util.o search.o lbuf.o undo.o commands.o
+HDR = cache.h buffer.h memory.h common.h util.h search.h lbuf.h undo.h commands.h
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
diff --git a/buffer.c b/buffer.c
@@ -1035,7 +1035,7 @@ ledit_delete_range_base(
rgl1 = l1;
rgb1 = 0;
rgl2 = l2 + 1;
- rgb2 = nextline->len;
+ rgb2 = 0;
}
if (text_ret) {
ledit_copy_text_to_lbuf(
diff --git a/commands.c b/commands.c
@@ -1,12 +1,52 @@
/* FIXME: Parse commands properly and allow combinations of commands */
+#include <ctype.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <pango/pangoxft.h>
+#include <X11/extensions/Xdbe.h>
+
+#include "memory.h"
+#include "common.h"
+#include "lbuf.h"
+#include "buffer.h"
+
+static int
+handle_write(ledit_buffer *buffer, char *cmd, int l1, int l2) {
+ (void)buffer;
+ (void)cmd;
+ (void)l1;
+ (void)l2;
+ printf("write\n");
+ return 0;
+}
+
+static int
+handle_quit(ledit_buffer *buffer, char *cmd, int l1, int l2) {
+ (void)buffer;
+ (void)cmd;
+ (void)l1;
+ (void)l2;
+ printf("quit\n");
+ return 0;
+}
static int
handle_write_quit(ledit_buffer *buffer, char *cmd, int l1, int l2) {
+ (void)buffer;
+ (void)cmd;
+ (void)l1;
+ (void)l2;
+ printf("write quit\n");
return 0;
}
static int
handle_substitute(ledit_buffer *buffer, char *cmd, int l1, int l2) {
+ (void)buffer;
+ (void)cmd;
+ (void)l1;
+ (void)l2;
+ printf("substitute\n");
return 0;
}
@@ -20,48 +60,103 @@ static const struct {
enum cmd_type type;
int (*handler)(ledit_buffer *buffer, char *cmd, int l1, int l2);
} cmds[] = {
- {"w", CMD_NORMAL, &handle_write_quit},
- {"q", CMD_NORMAL, &handle_write_quit},
+ {"wq", CMD_OPTIONAL_RANGE, &handle_write_quit},
+ {"w", CMD_OPTIONAL_RANGE, &handle_write},
+ {"q", CMD_NORMAL, &handle_quit},
{"s", CMD_OPTIONAL_RANGE, &handle_substitute}
};
#define LENGTH(X) (sizeof(X) / sizeof(X[0]))
+/*
+. current line - FIXME: implement
+$ last line
+% all lines
+*/
+
+/* FIXME: ACTUALLY USE LEN!!! */
+static int
+parse_range(ledit_buffer *buffer, char *cmd, int len, char **cmd_ret, int *line1_ret, int *line2_ret) {
+ (void)len;
+ enum {
+ START_LINENO = 1,
+ START_RANGE = 2,
+ IN_RANGE = 4,
+ IN_LINENO = 8
+ } s = START_LINENO | START_RANGE;
+ int l1 = -1, l2 = -1;
+ char *c = cmd;
+ for (; *c != '\0'; c++) {
+ if (isdigit(*c)) {
+ /* FIXME: integer overflow */
+ if (s & IN_LINENO) {
+ if (l2 != -1)
+ l2 = l2 * 10 + (*c - '0');
+ else
+ l1 = l1 * 10 + (*c - '0');
+ } else if ((s & START_LINENO) && (s & START_RANGE)) {
+ l1 = *c - '0';
+ s &= ~START_RANGE;
+ s &= ~START_LINENO;
+ s |= IN_RANGE | IN_LINENO;
+ } else if ((s & START_LINENO)) {
+ l2 = *c - '0';
+ s &= ~START_LINENO;
+ s |= IN_LINENO;
+ }
+ } else if (*c == ',' && !(s & START_RANGE)) {
+ if (l1 != -1 && l2 != -1) {
+ return 1;
+ } else {
+ s |= START_LINENO;
+ s &= ~IN_LINENO;
+ }
+ } else if (*c == '%') {
+ if (s & START_RANGE) {
+ l1 = 1;
+ l2 = buffer->lines_num;
+ break;
+ } else {
+ return 1;
+ }
+ } else if (*c == '$') {
+ if (s & START_LINENO) {
+ if (l1 == -1)
+ l1 = buffer->lines_num;
+ else
+ l2 = buffer->lines_num;
+ s &= ~START_LINENO;
+ s &= ~IN_LINENO;
+ } else {
+ return 1;
+ }
+ } else {
+ break;
+ }
+ }
+ if ((l1 == -1 || l2 == -1) && !(s & START_RANGE))
+ return 1;
+ *cmd_ret = c;
+ *line1_ret = l1;
+ *line2_ret = l2;
+ return 0;
+}
+
int
ledit_handle_cmd(ledit_buffer *buffer, char *cmd, int len) {
if (len < 0)
len = strlen(cmd);
if (len < 1)
- return;
- char *cur_pos = cmd;
- int l1 = buffer->cur_line;
- int l2 = buffer->cur_line;
- int range_given = 0;
- switch (cur_pos[0]) {
- case '%':
- l1 = 0;
- l2 = buffer->lines_num - 1;
- range_given = 1;
- cur_pos++;
- break;
- case '&'
- l1 = buffer->sel.line1;
- l2 = buffer->sel.line2;
- if (l1 < 0 || l2 < 0)
- return 1;
- if (l1 < l2) {
- int tmp = l1;
- l1 = l2;
- l2 = tmp;
- }
- range_given = 1;
- cur_pos++;
- break
- }
- for (int i = 0; i < LENGTH(cmds); i++) {
- if (!strncmp(cmds[i].cmd, cur_pos, strlen(cmds[i].cmd)) &&
- (!range_given || cmds[i].type == CMD_NORMAL)) {
- return cmds[i].handler(buffer, cur_pos, l1, l2);
+ return 1;
+ char *c;
+ int l1, l2;
+ if (parse_range(buffer, cmd, len, &c, &l1, &l2))
+ return 1;
+ int range_given = l1 != -1 && l2 != -1;
+ for (size_t i = 0; i < LENGTH(cmds); i++) {
+ if (!strncmp(cmds[i].cmd, c, strlen(cmds[i].cmd)) &&
+ (!range_given || cmds[i].type == CMD_OPTIONAL_RANGE)) {
+ return cmds[i].handler(buffer, c, l1, l2);
}
}
return 1;
diff --git a/commands.h b/commands.h
@@ -0,0 +1 @@
+int ledit_handle_cmd(ledit_buffer *buffer, char *cmd, int len);
diff --git a/ledit.c b/ledit.c
@@ -1755,6 +1755,8 @@ end_lineedit(void) {
else
ledit_set_search_backward(bottom_bar.line_text + 1);
search_next();
+ } else if (old_mode == COMMANDEDIT) {
+ ledit_handle_cmd(buffer, bottom_bar.line_text + 1, -1);
}
}