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/b7455f285061
branches:  trunk
changeset: 952970:b7455f285061
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 2965b5a8a6b9 -r b7455f285061 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