Browse Source

Move the line editor into its own file

Trying to make it reusable in other projects.
Přemysl Janouch 1 month ago
parent
commit
f241a7016a
Signed by: Přemysl Janouch <p@janouch.name> GPG Key ID: A0420B94F92B9493
2 changed files with 347 additions and 263 deletions
  1. 288
    0
      line-editor.c
  2. 59
    263
      nncmpp.c

+ 288
- 0
line-editor.c View File

@@ -0,0 +1,288 @@
1
+/*
2
+ * line-editor.c: a line editor component for the TUI part of liberty
3
+ *
4
+ * Copyright (c) 2017 - 2018, Přemysl Janouch <p@janouch.name>
5
+ *
6
+ * Permission to use, copy, modify, and/or distribute this software for any
7
+ * purpose with or without fee is hereby granted.
8
+ *
9
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
12
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
14
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
15
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
+ *
17
+ */
18
+
19
+// This is here just for IDE code model reasons
20
+#ifndef HAVE_LIBERTY
21
+#include "liberty/liberty.c"
22
+#include "liberty/liberty-tui.c"
23
+#endif
24
+
25
+static void
26
+row_buffer_append_c (struct row_buffer *self, ucs4_t c, chtype attrs)
27
+{
28
+	struct row_char current = { .attrs = attrs, .c = c };
29
+	struct row_char invalid = { .attrs = attrs, .c = '?', .width = 1 };
30
+
31
+	current.width = uc_width (current.c, locale_charset ());
32
+	if (current.width < 0 || !app_is_character_in_locale (current.c))
33
+		current = invalid;
34
+
35
+	ARRAY_RESERVE (self->chars, 1);
36
+	self->chars[self->chars_len++] = current;
37
+	self->total_width += current.width;
38
+}
39
+
40
+// --- Line editor -------------------------------------------------------------
41
+
42
+enum line_editor_action
43
+{
44
+	LINE_EDITOR_B_CHAR,                 ///< Go back a character
45
+	LINE_EDITOR_F_CHAR,                 ///< Go forward a character
46
+	LINE_EDITOR_B_WORD,                 ///< Go back a word
47
+	LINE_EDITOR_F_WORD,                 ///< Go forward a word
48
+	LINE_EDITOR_HOME,                   ///< Go to start of line
49
+	LINE_EDITOR_END,                    ///< Go to end of line
50
+
51
+	LINE_EDITOR_B_DELETE,               ///< Delete last character
52
+	LINE_EDITOR_F_DELETE,               ///< Delete next character
53
+	LINE_EDITOR_B_KILL_WORD,            ///< Delete last word
54
+	LINE_EDITOR_B_KILL_LINE,            ///< Delete everything up to BOL
55
+	LINE_EDITOR_F_KILL_LINE,            ///< Delete everything up to EOL
56
+};
57
+
58
+struct line_editor
59
+{
60
+	int point;                          ///< Caret index into line data
61
+	ucs4_t *line;                       ///< Line data, 0-terminated
62
+	int *w;                             ///< Codepoint widths, 0-terminated
63
+	size_t len;                         ///< Editor length
64
+	size_t alloc;                       ///< Editor allocated
65
+	char prompt;                        ///< Prompt character
66
+
67
+	void (*on_changed) (void);          ///< Callback on text change
68
+	void (*on_end) (bool);              ///< Callback on abort
69
+};
70
+
71
+static void
72
+line_editor_free (struct line_editor *self)
73
+{
74
+	free (self->line);
75
+	free (self->w);
76
+}
77
+
78
+/// Notify whomever invoked the editor that it's been either confirmed or
79
+/// cancelled and clean up editor state
80
+static void
81
+line_editor_abort (struct line_editor *self, bool status)
82
+{
83
+	self->on_end (status);
84
+	self->on_changed = NULL;
85
+
86
+	free (self->line);
87
+	self->line = NULL;
88
+	free (self->w);
89
+	self->w = NULL;
90
+	self->alloc = 0;
91
+	self->len = 0;
92
+	self->point = 0;
93
+	self->prompt = 0;
94
+}
95
+
96
+/// Start the line editor; remember to fill in "change" and "end" callbacks
97
+static void
98
+line_editor_start (struct line_editor *self, char prompt)
99
+{
100
+	self->alloc = 16;
101
+	self->line = xcalloc (sizeof *self->line, self->alloc);
102
+	self->w = xcalloc (sizeof *self->w, self->alloc);
103
+	self->len = 0;
104
+	self->point = 0;
105
+	self->prompt = prompt;
106
+}
107
+
108
+static void
109
+line_editor_changed (struct line_editor *self)
110
+{
111
+	self->line[self->len] = 0;
112
+	self->w[self->len] = 0;
113
+
114
+	if (self->on_changed)
115
+		self->on_changed ();
116
+}
117
+
118
+static void
119
+line_editor_move (struct line_editor *self, int to, int from, int len)
120
+{
121
+	memmove (self->line + to, self->line + from,
122
+		sizeof *self->line * len);
123
+	memmove (self->w + to, self->w + from,
124
+		sizeof *self->w * len);
125
+}
126
+
127
+static void
128
+line_editor_insert (struct line_editor *self, ucs4_t codepoint)
129
+{
130
+	while (self->alloc - self->len < 2 /* inserted + sentinel */)
131
+	{
132
+		self->alloc <<= 1;
133
+		self->line = xreallocarray
134
+			(self->line, sizeof *self->line, self->alloc);
135
+		self->w = xreallocarray
136
+			(self->w, sizeof *self->w, self->alloc);
137
+	}
138
+
139
+	line_editor_move (self, self->point + 1, self->point,
140
+		self->len - self->point);
141
+	self->line[self->point] = codepoint;
142
+	self->w[self->point] = app_is_character_in_locale (codepoint)
143
+		? uc_width (codepoint, locale_charset ())
144
+		: 1 /* the replacement question mark */;
145
+
146
+	self->point++;
147
+	self->len++;
148
+	line_editor_changed (self);
149
+}
150
+
151
+static bool
152
+line_editor_action (struct line_editor *self, enum line_editor_action action)
153
+{
154
+	switch (action)
155
+	{
156
+	default:
157
+		return soft_assert (!"unknown line editor action");
158
+
159
+	case LINE_EDITOR_B_CHAR:
160
+		if (self->point < 1)
161
+			return false;
162
+		do self->point--;
163
+		while (self->point > 0
164
+			&& !self->w[self->point]);
165
+		return true;
166
+	case LINE_EDITOR_F_CHAR:
167
+		if (self->point + 1 > (int) self->len)
168
+			return false;
169
+		do self->point++;
170
+		while (self->point < (int) self->len
171
+			&& !self->w[self->point]);
172
+		return true;
173
+	case LINE_EDITOR_B_WORD:
174
+	{
175
+		if (self->point < 1)
176
+			return false;
177
+		int i = self->point;
178
+		while (i && self->line[--i] == ' ');
179
+		while (i-- && self->line[i] != ' ');
180
+		self->point = ++i;
181
+		return true;
182
+	}
183
+	case LINE_EDITOR_F_WORD:
184
+	{
185
+		if (self->point + 1 > (int) self->len)
186
+			return false;
187
+		int i = self->point;
188
+		while (i < (int) self->len && self->line[i] != ' ') i++;
189
+		while (i < (int) self->len && self->line[i] == ' ') i++;
190
+		self->point = i;
191
+		return true;
192
+	}
193
+	case LINE_EDITOR_HOME:
194
+		self->point = 0;
195
+		return true;
196
+	case LINE_EDITOR_END:
197
+		self->point = self->len;
198
+		return true;
199
+
200
+	case LINE_EDITOR_B_DELETE:
201
+	{
202
+		if (self->point < 1)
203
+			return false;
204
+		int len = 1;
205
+		while (self->point - len > 0
206
+			&& !self->w[self->point - len])
207
+			len++;
208
+		line_editor_move (self, self->point - len, self->point,
209
+			self->len - self->point);
210
+		self->len -= len;
211
+		self->point -= len;
212
+		line_editor_changed (self);
213
+		return true;
214
+	}
215
+	case LINE_EDITOR_F_DELETE:
216
+	{
217
+		if (self->point + 1 > (int) self->len)
218
+			return false;
219
+		int len = 1;
220
+		while (self->point + len < (int) self->len
221
+			&& !self->w[self->point + len])
222
+			len++;
223
+		self->len -= len;
224
+		line_editor_move (self, self->point, self->point + len,
225
+			self->len - self->point);
226
+		line_editor_changed (self);
227
+		return true;
228
+	}
229
+	case LINE_EDITOR_B_KILL_WORD:
230
+	{
231
+		if (self->point < 1)
232
+			return false;
233
+
234
+		int i = self->point;
235
+		while (i && self->line[--i] == ' ');
236
+		while (i-- && self->line[i] != ' ');
237
+		i++;
238
+
239
+		line_editor_move (self, i, self->point, (self->len - self->point));
240
+		self->len -= self->point - i;
241
+		self->point = i;
242
+		line_editor_changed (self);
243
+		return true;
244
+	}
245
+	case LINE_EDITOR_B_KILL_LINE:
246
+		self->len -= self->point;
247
+		line_editor_move (self, 0, self->point, self->len);
248
+		self->point = 0;
249
+		line_editor_changed (self);
250
+		return true;
251
+	case LINE_EDITOR_F_KILL_LINE:
252
+		self->len = self->point;
253
+		line_editor_changed (self);
254
+		return true;
255
+	}
256
+}
257
+
258
+static int
259
+line_editor_write (const struct line_editor *self, struct row_buffer *row,
260
+	int width, chtype attrs)
261
+{
262
+	if (self->prompt)
263
+	{
264
+		hard_assert (self->prompt < 127);
265
+		row_buffer_append_c (row, self->prompt, attrs);
266
+		width--;
267
+	}
268
+
269
+	int following = 0;
270
+	for (size_t i = self->point; i < self->len; i++)
271
+		following += self->w[i];
272
+
273
+	int preceding = 0;
274
+	size_t start = self->point;
275
+	while (start && preceding < width / 2)
276
+		preceding += self->w[--start];
277
+
278
+	// There can be one extra space at the end of the line but this way we
279
+	// don't need to care about non-spacing marks following full-width chars
280
+	while (start && width - preceding - following > 2 /* widest char */)
281
+		preceding += self->w[--start];
282
+
283
+	// XXX: we should also show < > indicators for overflow but it'd probably
284
+	//   considerably complicate this algorithm
285
+	for (; start < self->len; start++)
286
+		row_buffer_append_c (row, self->line[start], attrs);
287
+	return !!self->prompt + preceding;
288
+}

+ 59
- 263
nncmpp.c View File

@@ -66,6 +66,9 @@ enum
66 66
 #include "liberty/liberty.c"
67 67
 #include "liberty/liberty-tui.c"
68 68
 
69
+#define HAVE_LIBERTY
70
+#include "line-editor.c"
71
+
69 72
 #include <math.h>
70 73
 #include <locale.h>
71 74
 #include <termios.h>
@@ -630,19 +633,9 @@ static struct app_context
630 633
 	int gauge_offset;                   ///< Offset to the gauge or -1
631 634
 	int gauge_width;                    ///< Width of the gauge, if present
632 635
 
636
+	struct line_editor editor;          ///< Line editor
633 637
 	struct poller_idle refresh_event;   ///< Refresh the screen
634 638
 
635
-	// Line editor:
636
-
637
-	int editor_point;                   ///< Caret index into line data
638
-	ucs4_t *editor_line;                ///< Line data, 0-terminated
639
-	int *editor_w;                      ///< Codepoint widths, 0-terminated
640
-	size_t editor_len;                  ///< Editor length
641
-	size_t editor_alloc;                ///< Editor allocated
642
-	char editor_prompt;                 ///< Prompt character
643
-	void (*on_editor_changed) (void);   ///< Callback on text change
644
-	void (*on_editor_end) (bool);       ///< Callback on abort
645
-
646 639
 	// Terminal:
647 640
 
648 641
 	termo_t *tk;                        ///< termo handle
@@ -886,8 +879,7 @@ app_free_context (void)
886 879
 	strv_free (&g.streams);
887 880
 	item_list_free (&g.playlist);
888 881
 
889
-	free (g.editor_line);
890
-	free (g.editor_w);
882
+	line_editor_free (&g.editor);
891 883
 
892 884
 	config_free (&g.config);
893 885
 	poller_free (&g.poller);
@@ -1361,53 +1353,6 @@ app_write_mpd_status (struct row_buffer *buf)
1361 1353
 	row_buffer_free (&right);
1362 1354
 }
1363 1355
 
1364
-static void
1365
-row_buffer_append_c (struct row_buffer *self, ucs4_t c, chtype attrs)
1366
-{
1367
-	struct row_char current = { .attrs = attrs, .c = c };
1368
-	struct row_char invalid = { .attrs = attrs, .c = '?', .width = 1 };
1369
-
1370
-	current.width = uc_width (current.c, locale_charset ());
1371
-	if (current.width < 0 || !app_is_character_in_locale (current.c))
1372
-		current = invalid;
1373
-
1374
-	ARRAY_RESERVE (self->chars, 1);
1375
-	self->chars[self->chars_len++] = current;
1376
-	self->total_width += current.width;
1377
-}
1378
-
1379
-static int
1380
-app_write_editor (struct row_buffer *row)
1381
-{
1382
-	int limit = COLS;
1383
-	if (g.editor_prompt)
1384
-	{
1385
-		hard_assert (g.editor_prompt < 127);
1386
-		row_buffer_append_c (row, g.editor_prompt, APP_ATTR (HIGHLIGHT));
1387
-		limit--;
1388
-	}
1389
-
1390
-	int following = 0;
1391
-	for (size_t i = g.editor_point; i < g.editor_len; i++)
1392
-		following += g.editor_w[i];
1393
-
1394
-	int preceding = 0;
1395
-	size_t start = g.editor_point;
1396
-	while (start && preceding < limit / 2)
1397
-		preceding += g.editor_w[--start];
1398
-
1399
-	// There can be one extra space at the end of the line but this way we
1400
-	// don't need to care about non-spacing marks following full-width chars
1401
-	while (start && limit - preceding - following > 2 /* widest char */)
1402
-		preceding += g.editor_w[--start];
1403
-
1404
-	// XXX: we should also show < > indicators for overflow but it'd probably
1405
-	//   considerably complicate this algorithm
1406
-	for (; start < g.editor_len; start++)
1407
-		row_buffer_append_c (row, g.editor_line[start], APP_ATTR (HIGHLIGHT));
1408
-	return !!g.editor_prompt + preceding;
1409
-}
1410
-
1411 1356
 static void
1412 1357
 app_draw_statusbar (void)
1413 1358
 {
@@ -1416,8 +1361,8 @@ app_draw_statusbar (void)
1416 1361
 	struct row_buffer buf = row_buffer_make ();
1417 1362
 	if (g.message)
1418 1363
 		row_buffer_append (&buf, g.message, APP_ATTR (HIGHLIGHT));
1419
-	else if (g.editor_line)
1420
-		caret = app_write_editor (&buf);
1364
+	else if (g.editor.line)
1365
+		caret = line_editor_write (&g.editor, &buf, COLS, APP_ATTR (HIGHLIGHT));
1421 1366
 	else if (g.client.state == MPD_CONNECTED)
1422 1367
 		app_write_mpd_status (&buf);
1423 1368
 
@@ -1645,199 +1590,6 @@ action_resolve (const char *name)
1645 1590
 	return -1;
1646 1591
 }
1647 1592
 
1648
-// --- Line editor -------------------------------------------------------------
1649
-
1650
-// TODO: move the editor out as a component to liberty-tui.c
1651
-
1652
-/// Notify whomever invoked the editor that it's been either confirmed or
1653
-/// cancelled and clean up editor state
1654
-static void
1655
-app_editor_abort (bool status)
1656
-{
1657
-	g.on_editor_end (status);
1658
-	g.on_editor_changed = NULL;
1659
-	g.on_editor_end = NULL;
1660
-
1661
-	free (g.editor_line);
1662
-	g.editor_line = NULL;
1663
-	free (g.editor_w);
1664
-	g.editor_w = NULL;
1665
-	g.editor_alloc = 0;
1666
-	g.editor_len = 0;
1667
-	g.editor_point = 0;
1668
-	g.editor_prompt = 0;
1669
-}
1670
-
1671
-/// Start the line editor; remember to fill in "change" and "abort" callbacks
1672
-static void
1673
-app_editor_start (char prompt)
1674
-{
1675
-	g.editor_alloc = 16;
1676
-	g.editor_line = xcalloc (sizeof *g.editor_line, g.editor_alloc);
1677
-	g.editor_w = xcalloc (sizeof *g.editor_w, g.editor_alloc);
1678
-	g.editor_len = 0;
1679
-	g.editor_point = 0;
1680
-	g.editor_prompt = prompt;
1681
-	app_invalidate ();
1682
-}
1683
-
1684
-static void
1685
-app_editor_changed (void)
1686
-{
1687
-	g.editor_line[g.editor_len] = 0;
1688
-	g.editor_w[g.editor_len] = 0;
1689
-
1690
-	if (g.on_editor_changed)
1691
-		g.on_editor_changed ();
1692
-}
1693
-
1694
-static void
1695
-app_editor_move (int to, int from, int len)
1696
-{
1697
-	memmove (g.editor_line + to, g.editor_line + from,
1698
-		sizeof *g.editor_line * len);
1699
-	memmove (g.editor_w + to, g.editor_w + from,
1700
-		sizeof *g.editor_w * len);
1701
-}
1702
-
1703
-static bool
1704
-app_editor_process_action (enum action action)
1705
-{
1706
-	app_invalidate ();
1707
-	switch (action)
1708
-	{
1709
-	case ACTION_QUIT:
1710
-		app_editor_abort (false);
1711
-		return true;
1712
-	case ACTION_EDITOR_CONFIRM:
1713
-		app_editor_abort (true);
1714
-		return true;
1715
-	default:
1716
-		return false;
1717
-
1718
-	case ACTION_EDITOR_B_CHAR:
1719
-		if (g.editor_point < 1)
1720
-			return false;
1721
-		do g.editor_point--;
1722
-		while (g.editor_point > 0
1723
-			&& !g.editor_w[g.editor_point]);
1724
-		return true;
1725
-	case ACTION_EDITOR_F_CHAR:
1726
-		if (g.editor_point + 1 > (int) g.editor_len)
1727
-			return false;
1728
-		do g.editor_point++;
1729
-		while (g.editor_point < (int) g.editor_len
1730
-			&& !g.editor_w[g.editor_point]);
1731
-		return true;
1732
-	case ACTION_EDITOR_B_WORD:
1733
-	{
1734
-		if (g.editor_point < 1)
1735
-			return false;
1736
-		int i = g.editor_point;
1737
-		while (i && g.editor_line[--i] == ' ');
1738
-		while (i-- && g.editor_line[i] != ' ');
1739
-		g.editor_point = ++i;
1740
-		return true;
1741
-	}
1742
-	case ACTION_EDITOR_F_WORD:
1743
-	{
1744
-		if (g.editor_point + 1 > (int) g.editor_len)
1745
-			return false;
1746
-		int i = g.editor_point;
1747
-		while (i < (int) g.editor_len && g.editor_line[i] != ' ') i++;
1748
-		while (i < (int) g.editor_len && g.editor_line[i] == ' ') i++;
1749
-		g.editor_point = i;
1750
-		return true;
1751
-	}
1752
-	case ACTION_EDITOR_HOME:
1753
-		g.editor_point = 0;
1754
-		return true;
1755
-	case ACTION_EDITOR_END:
1756
-		g.editor_point = g.editor_len;
1757
-		return true;
1758
-
1759
-	case ACTION_EDITOR_B_DELETE:
1760
-	{
1761
-		if (g.editor_point < 1)
1762
-			return false;
1763
-		int len = 1;
1764
-		while (g.editor_point - len > 0
1765
-			&& !g.editor_w[g.editor_point - len])
1766
-			len++;
1767
-		app_editor_move (g.editor_point - len, g.editor_point,
1768
-			g.editor_len - g.editor_point);
1769
-		g.editor_len -= len;
1770
-		g.editor_point -= len;
1771
-		app_editor_changed ();
1772
-		return true;
1773
-	}
1774
-	case ACTION_EDITOR_F_DELETE:
1775
-	{
1776
-		if (g.editor_point + 1 > (int) g.editor_len)
1777
-			return false;
1778
-		int len = 1;
1779
-		while (g.editor_point + len < (int) g.editor_len
1780
-			&& !g.editor_w[g.editor_point + len])
1781
-			len++;
1782
-		g.editor_len -= len;
1783
-		app_editor_move (g.editor_point, g.editor_point + len,
1784
-			g.editor_len - g.editor_point);
1785
-		app_editor_changed ();
1786
-		return true;
1787
-	}
1788
-	case ACTION_EDITOR_B_KILL_WORD:
1789
-	{
1790
-		if (g.editor_point < 1)
1791
-			return false;
1792
-
1793
-		int i = g.editor_point;
1794
-		while (i && g.editor_line[--i] == ' ');
1795
-		while (i-- && g.editor_line[i] != ' ');
1796
-		i++;
1797
-
1798
-		app_editor_move (i, g.editor_point, (g.editor_len - g.editor_point));
1799
-		g.editor_len -= g.editor_point - i;
1800
-		g.editor_point = i;
1801
-		app_editor_changed ();
1802
-		return true;
1803
-	}
1804
-	case ACTION_EDITOR_B_KILL_LINE:
1805
-		g.editor_len -= g.editor_point;
1806
-		app_editor_move (0, g.editor_point, g.editor_len);
1807
-		g.editor_point = 0;
1808
-		app_editor_changed ();
1809
-		return true;
1810
-	case ACTION_EDITOR_F_KILL_LINE:
1811
-		g.editor_len = g.editor_point;
1812
-		app_editor_changed ();
1813
-		return true;
1814
-	}
1815
-}
1816
-
1817
-static void
1818
-app_editor_insert (ucs4_t codepoint)
1819
-{
1820
-	while (g.editor_alloc - g.editor_len < 2 /* inserted + sentinel */)
1821
-	{
1822
-		g.editor_alloc <<= 1;
1823
-		g.editor_line = xreallocarray
1824
-			(g.editor_line, sizeof *g.editor_line, g.editor_alloc);
1825
-		g.editor_w = xreallocarray
1826
-			(g.editor_w, sizeof *g.editor_w, g.editor_alloc);
1827
-	}
1828
-
1829
-	app_editor_move (g.editor_point + 1, g.editor_point,
1830
-		g.editor_len - g.editor_point);
1831
-	g.editor_line[g.editor_point] = codepoint;
1832
-	g.editor_w[g.editor_point] = app_is_character_in_locale (codepoint)
1833
-		? uc_width (codepoint, locale_charset ())
1834
-		: 1 /* the replacement question mark */;
1835
-
1836
-	g.editor_point++;
1837
-	g.editor_len++;
1838
-	app_editor_changed ();
1839
-}
1840
-
1841 1593
 // --- User input handling -----------------------------------------------------
1842 1594
 
1843 1595
 static void
@@ -1902,7 +1654,7 @@ app_on_editor_end (bool confirmed)
1902 1654
 		return;
1903 1655
 
1904 1656
 	size_t len;
1905
-	char *u8 = (char *) u32_to_u8 (g.editor_line, g.editor_len + 1, NULL, &len);
1657
+	char *u8 = (char *) u32_to_u8 (g.editor.line, g.editor.len + 1, NULL, &len);
1906 1658
 	mpd_client_send_command_raw (c, u8);
1907 1659
 	free (u8);
1908 1660
 
@@ -1932,8 +1684,9 @@ app_process_action (enum action action)
1932 1684
 		app_invalidate ();
1933 1685
 		return true;
1934 1686
 	case ACTION_MPD_COMMAND:
1935
-		app_editor_start (':');
1936
-		g.on_editor_end = app_on_editor_end;
1687
+		line_editor_start (&g.editor, ':');
1688
+		g.editor.on_end = app_on_editor_end;
1689
+		app_invalidate ();
1937 1690
 		return true;
1938 1691
 	default:
1939 1692
 		return false;
@@ -2006,6 +1759,49 @@ app_process_action (enum action action)
2006 1759
 	return false;
2007 1760
 }
2008 1761
 
1762
+static bool
1763
+app_editor_process_action (enum action action)
1764
+{
1765
+	app_invalidate ();
1766
+	switch (action)
1767
+	{
1768
+	case ACTION_QUIT:
1769
+		line_editor_abort (&g.editor, false);
1770
+		g.editor.on_end = NULL;
1771
+		return true;
1772
+	case ACTION_EDITOR_CONFIRM:
1773
+		line_editor_abort (&g.editor, true);
1774
+		g.editor.on_end = NULL;
1775
+		return true;
1776
+	default:
1777
+		return false;
1778
+
1779
+	case ACTION_EDITOR_B_CHAR:
1780
+		return line_editor_action (&g.editor, LINE_EDITOR_B_CHAR);
1781
+	case ACTION_EDITOR_F_CHAR:
1782
+		return line_editor_action (&g.editor, LINE_EDITOR_F_CHAR);
1783
+	case ACTION_EDITOR_B_WORD:
1784
+		return line_editor_action (&g.editor, LINE_EDITOR_B_WORD);
1785
+	case ACTION_EDITOR_F_WORD:
1786
+		return line_editor_action (&g.editor, LINE_EDITOR_F_WORD);
1787
+	case ACTION_EDITOR_HOME:
1788
+		return line_editor_action (&g.editor, LINE_EDITOR_HOME);
1789
+	case ACTION_EDITOR_END:
1790
+		return line_editor_action (&g.editor, LINE_EDITOR_END);
1791
+
1792
+	case ACTION_EDITOR_B_DELETE:
1793
+		return line_editor_action (&g.editor, LINE_EDITOR_B_DELETE);
1794
+	case ACTION_EDITOR_F_DELETE:
1795
+		return line_editor_action (&g.editor, LINE_EDITOR_F_DELETE);
1796
+	case ACTION_EDITOR_B_KILL_WORD:
1797
+		return line_editor_action (&g.editor, LINE_EDITOR_B_KILL_WORD);
1798
+	case ACTION_EDITOR_B_KILL_LINE:
1799
+		return line_editor_action (&g.editor, LINE_EDITOR_B_KILL_LINE);
1800
+	case ACTION_EDITOR_F_KILL_LINE:
1801
+		return line_editor_action (&g.editor, LINE_EDITOR_F_KILL_LINE);
1802
+	}
1803
+}
1804
+
2009 1805
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2010 1806
 
2011 1807
 static bool
@@ -2086,8 +1882,8 @@ app_process_mouse (termo_mouse_event_t type, int line, int column, int button,
2086 1882
 	if (type != TERMO_MOUSE_PRESS)
2087 1883
 		return true;
2088 1884
 
2089
-	if (g.editor_line)
2090
-		app_editor_abort (false);
1885
+	if (g.editor.line)
1886
+		line_editor_abort (&g.editor, false);
2091 1887
 
2092 1888
 	if (button == 1)
2093 1889
 		return app_process_left_mouse_click (line, column, double_click);
@@ -2270,7 +2066,7 @@ static bool
2270 2066
 app_process_termo_event (termo_key_t *event)
2271 2067
 {
2272 2068
 	struct binding dummy = { *event, 0, 0 }, *binding;
2273
-	if (g.editor_line)
2069
+	if (g.editor.line)
2274 2070
 	{
2275 2071
 		if ((binding = bsearch (&dummy, g_editor_keys, g_editor_keys_len,
2276 2072
 			sizeof *binding, app_binding_cmp)))
@@ -2278,7 +2074,7 @@ app_process_termo_event (termo_key_t *event)
2278 2074
 		if (event->type != TERMO_TYPE_KEY || event->modifiers != 0)
2279 2075
 			return false;
2280 2076
 
2281
-		app_editor_insert (event->code.codepoint);
2077
+		line_editor_insert (&g.editor, event->code.codepoint);
2282 2078
 		app_invalidate ();
2283 2079
 		return true;
2284 2080
 	}
@@ -3630,7 +3426,7 @@ app_on_key_timer (void *user_data)
3630 3426
 	termo_key_t event;
3631 3427
 	if (termo_getkey_force (g.tk, &event) == TERMO_RES_KEY)
3632 3428
 		if (!app_process_termo_event (&event))
3633
-			app_quit ();
3429
+			app_quit ();  // presumably an ESC, questionable
3634 3430
 }
3635 3431
 
3636 3432
 static void

Loading…
Cancel
Save