Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/games/cgram cgram: add advanced cursor movement with tab, sh...
details: https://anonhg.NetBSD.org/src/rev/e4a611b6fbe2
branches: trunk
changeset: 959706:e4a611b6fbe2
user: rillig <rillig%NetBSD.org@localhost>
date: Mon Feb 22 17:36:42 2021 +0000
description:
cgram: add advanced cursor movement with tab, shift+tab, return
diffstat:
games/cgram/cgram.c | 166 ++++++++++++++++++++++++++++++++++++---------------
1 files changed, 117 insertions(+), 49 deletions(-)
diffs (266 lines):
diff -r d61cfeaa888a -r e4a611b6fbe2 games/cgram/cgram.c
--- a/games/cgram/cgram.c Mon Feb 22 16:28:20 2021 +0000
+++ b/games/cgram/cgram.c Mon Feb 22 17:36:42 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cgram.c,v 1.12 2021/02/22 16:28:20 rillig Exp $ */
+/* $NetBSD: cgram.c,v 1.13 2021/02/22 17:36:42 rillig Exp $ */
/*-
* Copyright (c) 2013, 2021 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(lint)
-__RCSID("$NetBSD: cgram.c,v 1.12 2021/02/22 16:28:20 rillig Exp $");
+__RCSID("$NetBSD: cgram.c,v 1.13 2021/02/22 17:36:42 rillig Exp $");
#endif
#include <assert.h>
@@ -73,6 +73,12 @@
}
static bool
+ch_isspace(char ch)
+{
+ return isspace((unsigned char)ch) != 0;
+}
+
+static bool
ch_isupper(char ch)
{
return isupper((unsigned char)ch) != 0;
@@ -193,6 +199,23 @@
return extent_y - 1;
}
+static char
+char_left_of_cursor(void)
+{
+ if (cursor_x > 0)
+ return lines.v[cursor_y].s[cursor_x - 1];
+ assert(cursor_y > 0);
+ return '\n'; /* eol of previous line */
+}
+
+static char
+char_at_cursor(void)
+{
+ if (cursor_x == cur_max_x())
+ return '\n';
+ return lines.v[cursor_y].s[cursor_x];
+}
+
static void
readquote(void)
{
@@ -266,7 +289,7 @@
return false;
}
- char och = lines.v[cursor_y].s[cursor_x];
+ char och = char_at_cursor();
if (!ch_isalpha(och)) {
beep();
return false;
@@ -292,8 +315,6 @@
return true;
}
-////////////////////////////////////////////////////////////
-
static bool
is_solved(void)
{
@@ -303,6 +324,8 @@
return true;
}
+////////////////////////////////////////////////////////////
+
static void
redraw(void)
{
@@ -342,21 +365,6 @@
refresh();
}
-static void
-opencurses(void)
-{
- initscr();
- cbreak();
- noecho();
- keypad(stdscr, true);
-}
-
-static void
-closecurses(void)
-{
- endwin();
-}
-
////////////////////////////////////////////////////////////
static void
@@ -383,6 +391,72 @@
offset_y = cursor_y - (LINES - 2);
}
+static bool
+can_go_left(void)
+{
+ return cursor_y > 0 ||
+ (cursor_y == 0 && cursor_x > 0);
+}
+
+static bool
+can_go_right(void)
+{
+ return cursor_y < cur_max_y() ||
+ (cursor_y == cur_max_y() && cursor_x < cur_max_x());
+}
+
+static void
+go_to_prev_line(void)
+{
+ cursor_y--;
+ cursor_x = cur_max_x();
+}
+
+static void
+go_to_next_line(void)
+{
+ cursor_x = 0;
+ cursor_y++;
+}
+
+static void
+go_left(void)
+{
+ if (cursor_x > 0)
+ cursor_x--;
+ else if (cursor_y > 0)
+ go_to_prev_line();
+}
+
+static void
+go_right(void)
+{
+ if (cursor_x < cur_max_x())
+ cursor_x++;
+ else if (cursor_y < cur_max_y())
+ go_to_next_line();
+}
+
+static void
+go_to_prev_word(void)
+{
+ while (can_go_left() && ch_isspace(char_left_of_cursor()))
+ go_left();
+
+ while (can_go_left() && !ch_isspace(char_left_of_cursor()))
+ go_left();
+}
+
+static void
+go_to_next_word(void)
+{
+ while (can_go_right() && !ch_isspace(char_at_cursor()))
+ go_right();
+
+ while (can_go_right() && ch_isspace(char_at_cursor()))
+ go_right();
+}
+
static void
handle_char_input(int ch)
{
@@ -390,23 +464,13 @@
if (substitute((char)ch)) {
if (cursor_x < cur_max_x())
cursor_x++;
- if (cursor_x == cur_max_x() &&
- cursor_y < cur_max_y()) {
- cursor_x = 0;
- cursor_y++;
- }
+ if (cursor_x == cur_max_x())
+ go_to_next_line();
}
- } else if (cursor_x < cur_max_x() &&
- ch == lines.v[cursor_y].s[cursor_x]) {
- cursor_x++;
- if (cursor_x == cur_max_x() &&
- cursor_y < cur_max_y()) {
- cursor_x = 0;
- cursor_y++;
- }
- } else {
+ } else if (ch == char_at_cursor())
+ go_right();
+ else
beep();
- }
}
static bool
@@ -421,12 +485,7 @@
break;
case 2: /* ^B */
case KEY_LEFT:
- if (cursor_x > 0) {
- cursor_x--;
- } else if (cursor_y > 0) {
- cursor_y--;
- cursor_x = cur_max_x();
- }
+ go_left();
break;
case 5: /* ^E */
case KEY_END:
@@ -434,12 +493,16 @@
break;
case 6: /* ^F */
case KEY_RIGHT:
- if (cursor_x < cur_max_x()) {
- cursor_x++;
- } else if (cursor_y < cur_max_y()) {
- cursor_y++;
- cursor_x = 0;
- }
+ go_right();
+ break;
+ case '\t':
+ go_to_next_word();
+ break;
+ case KEY_BTAB:
+ go_to_prev_word();
+ break;
+ case '\n':
+ go_to_next_line();
break;
case 12: /* ^L */
clear();
@@ -478,7 +541,11 @@
srandom((unsigned int)time(NULL));
readquote();
encode();
- opencurses();
+
+ initscr();
+ cbreak();
+ noecho();
+ keypad(stdscr, true);
}
static void
@@ -496,7 +563,8 @@
static void
clean_up(void)
{
- closecurses();
+ endwin();
+
stringarray_cleanup(&sollines);
stringarray_cleanup(&lines);
}
Home |
Main Index |
Thread Index |
Old Index