thisisparker / cursewords

:pencil: Terminal-based crossword puzzle solving interface
GNU Affero General Public License v3.0
249 stars 30 forks source link

[Feature] NYT-style fills (Experimental) #41

Open mizlan opened 2 years ago

mizlan commented 2 years ago

The following patch accounts for the differences in the use of the Backspace key and the behavior when an alphanumeric key is pressed. I've labeled this as experimental but in my testing, I did not find anything wrong with it. I'm very pleasantly surprised at how easy this was, using the numerous helper functions you've defined :)

diff --git a/cursewords/cursewords.py b/cursewords/cursewords.py
index 7c48fd8..e2c287d 100755
--- a/cursewords/cursewords.py
+++ b/cursewords/cursewords.py
@@ -1054,26 +1054,42 @@ def main():

             # Letter entry
             elif not puzzle_complete and keypress.isalnum():
-                if not current_cell.is_blankish:
-                    overwrite_mode = True
-                current_cell.entry = keypress.upper()

                 if current_cell.marked_wrong:
                     current_cell.marked_wrong = False
                     current_cell.corrected = True
                 modified_since_save = True
-                cursor.advance_within_word(overwrite_mode, wrap_mode=True)
+
+                if current_cell.is_blankish:
+                    cursor.advance_within_word(overwrite_mode=False, wrap_mode=True)
+                else:
+                    is_last_letter = cursor.current_word()[-1] == cursor.position
+
+                    if is_last_letter:
+                        # jump to first blank in current word or next word
+                        cursor.advance_within_word(wrap_mode=True)
+                    else:
+                        # "overwrite" the word
+                        cursor.advance_within_word(overwrite_mode=True, wrap_mode=False)
+
+                # (the old cell)
+                current_cell.entry = keypress.upper()

             # Deletion keys
             elif (not puzzle_complete and
                   keypress.name in ['KEY_BACKSPACE', 'KEY_DELETE']):
-                current_cell.clear()
-                overwrite_mode = True
                 modified_since_save = True
-                if keypress.name == 'KEY_BACKSPACE':
-                    cursor.retreat_within_word(end_placement=True)
-                elif keypress.name == 'KEY_DELETE':
-                    cursor.advance_within_word(overwrite_mode=True)
+
+                # just delete current cell, do not move
+                if not current_cell.is_blankish:
+                    current_cell.clear()
+                else:
+                    # delete *after* you move
+                    if keypress.name == 'KEY_BACKSPACE':
+                        cursor.retreat_within_word(end_placement=True)
+                    elif keypress.name == 'KEY_DELETE':
+                        cursor.advance_within_word(overwrite_mode=True)
+                    grid.cells.get(cursor.position).clear()

             # Navigation
             elif (keypress.name in ['KEY_TAB'] or
mizlan commented 2 years ago

You'd probably want to figure out a configuration system before I make a PR. If you're okay with it, I can also go ahead and make a PR with an --nyt-fill flag that would enable these controls.

mizlan commented 2 years ago

Oops some flags in function arguments are default values and are hence redundant. Will fix later.