[27278] in Source-Commits

home help back first fref pref prev next nref lref last post

discuss-ng commit: Implement Vim-style keybindings in ndsc

daemon@ATHENA.MIT.EDU (Victor Vasiliev)
Sat Sep 14 23:23:16 2013

Date: Sat, 14 Sep 2013 23:23:09 -0400
From: Victor Vasiliev <vasilvv@MIT.EDU>
Message-Id: <201309150323.r8F3N9TB009784@drugstore.mit.edu>
To: source-commits@MIT.EDU

https://github.com/mit-athena/discuss-ng/commit/06a02a3f08a0e19d4b893e7ec87b56bd95a91010
commit 06a02a3f08a0e19d4b893e7ec87b56bd95a91010
Author: Victor Vasiliev <vasilvv@mit.edu>
Date:   Sat Sep 14 23:13:48 2013 -0400

    Implement Vim-style keybindings in ndsc
    
    This allows navigating more easily and delete and undo multiple things
    at once.

 ndsc |   92 +++++++++++++++++++++++++++++++++++++++++++----------------------
 1 files changed, 61 insertions(+), 31 deletions(-)

diff --git a/ndsc b/ndsc
index 59b8ac6..cec8768 100755
--- a/ndsc
+++ b/ndsc
@@ -171,6 +171,8 @@ def redraw():
             screen.addstr(2 + i, 3, text)
 
     footer = " %i/%i " % (pos_cur + 1, len(transactions))
+    if status_bar:
+        footer += "─── %s " % status_bar
     screen.addstr(max_y-2, 6, footer)
 
     if viewed_transaction:
@@ -201,64 +203,84 @@ def handle_transaction_view():
     textpos_y = textpos_x = 0
 
 def handle_transaction_delete():
+    target = transactions[pos_cur:pos_cur + multiplier]
+
     # Do not allow the meeting to become empty
-    if len(transactions) < 2:
+    if len(transactions) - len(target) < 1:
         return
 
-    trn = transactions[pos_cur]
-
-    trn.delete()
-    del transactions[pos_cur]
+    for trn in target:
+        trn.delete()
+    del transactions[pos_cur:pos_cur + multiplier]
+    del transaction_numbers[pos_cur:pos_cur + multiplier]
 
-    delete_stack.append(trn)
+    delete_stack.append(target)
 
 def handle_transaction_undelete():
-    if not delete_stack:
-        return
-
-    trn = delete_stack.pop()
-
-    try:
-        trn.meeting.undelete_transaction(trn.number)
-    except discuss.DiscussError as err:
-        # If transaction was expunged, there is nothing we can do, but this should
-        # not crash the client
-        if err.code == discuss.constants.EXPUNGED_TRN:
-            return
-        else:
-            raise err
-
-    transactions.insert(bisect.bisect_left(transactions, trn), trn)
+    trns = []
+    for i in range(multiplier):
+        try:
+            trns += delete_stack.pop()
+        except IndexError:
+            break
+
+    for trn in trns:
+        try:
+            trn.meeting.undelete_transaction(trn.number)
+        except discuss.DiscussError as err:
+            # If transaction was expunged, there is nothing we can do, but this should
+            # not crash the client
+            if err.code == discuss.constants.EXPUNGED_TRN:
+                status_bar = 'Cannot undelete [%i] because it is expunged' % trn.number
+            else:
+                raise err
+
+        new_pos = bisect.bisect_left(transactions, trn)
+        transactions.insert(new_pos, trn)
+        transaction_numbers.insert(new_pos, trn.number)
+
+def reset_multiplier():
+    global status_bar, multiplier_acc
+
+    status_bar = ''
+    multiplier_acc = ''
 
 def main_loop():
     global pos_cur, pos_top, viewed_transaction
     global textpos_y, textpos_x
     global max_number, max_sender_len
+    global status_bar, multiplier_acc, multiplier
+    global transaction_numbers
 
     screen.nodelay(False)
     screen.keypad(True)
 
-    max_number = max(trn.number for trn in transactions)
+    transaction_numbers = [trn.number for trn in transactions]
+
+    max_number = max(transaction_numbers)
     max_sender_len = max(len(trn.signature) for trn in transactions)
 
+    reset_multiplier()
     redraw()
 
     while True:
         ch = screen.getch()
 
         if viewed_transaction == None:
+            multiplier = int(multiplier_acc) if multiplier_acc else 1
+
             if ch == ord('q'):
                 return
-            if ch == curses.KEY_DOWN:
-                pos_cur += 1
-            if ch == curses.KEY_UP:
-                pos_cur -= 1
+            if ch == curses.KEY_DOWN or ch == ord('j'):
+                pos_cur += multiplier
+            if ch == curses.KEY_UP or ch == ord('k'):
+                pos_cur -= multiplier
             if ch == curses.KEY_PPAGE:
-                pos_top -= rows
-                pos_cur -= rows
+                pos_top -= rows * multiplier
+                pos_cur -= rows * multiplier
             if ch == curses.KEY_NPAGE:
-                pos_top += rows
-                pos_cur += rows
+                pos_top += rows * multiplier
+                pos_cur += rows * multiplier
             if ch == curses.KEY_HOME:
                 pos_cur = 0
                 pos_top = 0
@@ -271,6 +293,14 @@ def main_loop():
                 handle_transaction_delete()
             if ch == ord('u'):
                 handle_transaction_undelete()
+            if ch == ord('g'):
+                pos_cur = bisect.bisect_left(transaction_numbers, multiplier)
+
+            if ch >= ord('0') and ch <= ord('9'):
+                multiplier_acc = multiplier_acc + chr(ch)
+                status_bar = multiplier_acc
+            else:
+                reset_multiplier()
         else:
             if ch == ord('q'):
                 viewed_transaction = None

home help back first fref pref prev next nref lref last post