emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/crdt dfc98d3525 38/44: add crdt-goto-{next, prev}-user


From: ELPA Syncer
Subject: [elpa] externals/crdt dfc98d3525 38/44: add crdt-goto-{next, prev}-user
Date: Sat, 2 Jul 2022 22:57:35 -0400 (EDT)

branch: externals/crdt
commit dfc98d35257e812922da103a0a54e96fb155490d
Author: Qiantan Hong <qhong@alum.mit.edu>
Commit: Qiantan Hong <qhong@alum.mit.edu>

    add crdt-goto-{next,prev}-user
---
 README.org | 123 ++++++++++++++++++++++++++++++++++++-------------------------
 crdt.el    |  72 ++++++++++++++++++++++++++++++------
 2 files changed, 134 insertions(+), 61 deletions(-)

diff --git a/README.org b/README.org
index 1dcd4edca5..5d07211b38 100644
--- a/README.org
+++ b/README.org
@@ -1,9 +1,11 @@
 * Introduction
 
-~crdt.el~ is a real-time collaborative editing environment for Emacs using 
Conflict-free Replicated Data Types.
+~crdt.el~ is a real-time collaborative editing environment for Emacs
+using Conflict-free Replicated Data Types.
 
 Highlights:
-- [[https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type][CRDT]], 
darling child of collaborative editing researches...
+- [[https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type][CRDT]],
+  darling child of collaborative editing researches...
 - Share multiple buffer in one session
 - See other users' cursor and region
 - Synchronize Org mode folding status
@@ -16,26 +18,30 @@ Highlights:
 
 ~crdt.el~ is now on GNU ELPA! Just =M-x package-install crdt=.
 
-*Caution!!!* Please make sure that you and your peers are on the same 
~crdt.el~ version!
-It turns out to be one of the most common causes of ~crdt.el~ not working.
-Because currently the network protocol is not stablized, behavior when using 
mismatched versions is unexpectable.
+*Caution!!!* Please make sure that you and your peers are on the same
+~crdt.el~ version!  It turns out to be one of the most common causes
+of ~crdt.el~ not working.  Because currently the network protocol is
+not stablized, behavior when using mismatched versions is
+unexpectable.
 - Strictly speaking, it should works when =crdt-protocol-version= are defined 
and the same on all peers.
   But why not save some hassle and keep everyone on the latest version.
 - To upgrade, just =M-x package-reinstall crdt=, then preferably restart Emacs.
 
 ** Start a shared session
 
-A shared session is a place that can contains multiple buffers (or files),
-and multiple users can join to collaboratively edit those buffers (or files).
-Think about a meeting room with some people working together on some papers.
+A shared session is a place that can contains multiple buffers (or
+files), and multiple users can join to collaboratively edit those
+buffers (or files).  Think about a meeting room with some people
+working together on some papers.
 
 In some buffer, =M-x crdt-share-buffer=. Then enter session name.
 This add the current buffer to the existing session with that name.
-If no such exists, it creates a new session with the provided session name,
-and initially contains the current buffer as a shared buffer.
+If no such exists, it creates a new session with the provided session
+name, and initially contains the current buffer as a shared buffer.
 
-If a new session is to be created, you need to enter port (default to 6530),
-optional password and your display name (default to your current 
=(user-full-name)=).
+If a new session is to be created, you need to enter port (default to
+6530), optional password and your display name (default to your
+current =(user-full-name)=).
 
 ** Join a session
 
@@ -43,10 +49,16 @@ optional password and your display name (default to your 
current =(user-full-nam
   
 ** List active users
 
-In a CRDT shared buffer (either server or client), =M-x crdt-list-users=.
+In a CRDT shared buffer (either server or client), =M-x
+crdt-list-users=.
 
-In the displayed user list, press ~RET~ on an entry to goto that user's cursor 
position.
-Press ~f~ to follow that user, and press ~f~ again or =M-x crdt-stop-follow= 
to stop following.
+In the displayed user list, press ~RET~ on an entry to goto that
+user's cursor position.  Press ~f~ to follow that user, and press ~f~
+again or =M-x crdt-stop-follow= to stop following.
+
+You can also use =M-x crdt-goto-next-user= and =M-x
+crdt-goto-prev-user= to cycle through users' cursor positions from any
+CRDT shared buffer (don't need to be in the user list buffer).
 
 ** List all sessions, and buffer in current session
 
@@ -57,10 +69,12 @@ press ~RET~ in the session list to see buffers in the 
selected session.
 
 ** Stop sharing
 
-=M-x crdt-stop-session= stops a session you've started and disconnect all 
other users from it.
-This will ask for your confirmation, customize =crdt-confirm-stop-session= if 
you want to disable it.
+=M-x crdt-stop-session= stops a session you've started and disconnect
+all other users from it.  This will ask for your confirmation,
+customize =crdt-confirm-stop-session= if you want to disable it.
 
-You can also press ~k~ or ~d~ in the session list (show it by =M-x 
crdt-list-sessions=).
+You can also press ~k~ or ~d~ in the session list (show it by =M-x
+crdt-list-sessions=).
 
 =M-x crdt-stop-share-buffer= removes current buffer from its CRDT
 session (this operation is only allowed at server side). You can also
@@ -70,66 +84,75 @@ press ~k~ or ~d~ in the buffer list.
 
 =M-x crdt-disconnect=, then choose a session to disconnect from.
 
-You can also press ~k~ or ~d~ in the session list (show it by =M-x 
crdt-list-sessions=).
+You can also press ~k~ or ~d~ in the session list (show it by =M-x
+crdt-list-sessions=).
 
-The server Emacs has the privilege to disconnect a user from a session.
-To do so, press ~k~ or ~d~ on an entry in the user list (show it by =M-x 
crdt-list-users=).
+The server Emacs has the privilege to disconnect a user from a
+session.  To do so, press ~k~ or ~d~ on an entry in the user list
+(show it by =M-x crdt-list-users=).
 
 ** Visualizing author of parts of the document
-Turn on =crdt-visualize-author-mode=. Colored underlines are added to each 
part of the document,
-based on which user authored it.
+   
+Turn on =crdt-visualize-author-mode=. Colored underlines are added to
+each part of the document, based on which user authored it.
 
 ** Synchronizing Org folding status
 
-Turn on =crdt-org-sync-overlay-mode=. All peers that have this enabled have 
their
-folding status synchronized. Peers without enabling this minor mode are 
unaffected.
+Turn on =crdt-org-sync-overlay-mode=. All peers that have this enabled
+have their folding status synchronized. Peers without enabling this
+minor mode are unaffected.
 
 ** Comint integration
 
-Just go ahead and share you comint REPL buffer! Tested: ~shell~ and 
~cmuscheme~.
-By default, when sharing a comint buffer, ~crdt.el~ temporarily reset input 
history (as in =M-n= =M-p=)
-so others don't spy into your =.bash_history= and alike.
-You can customize this behavior using variable 
=crdt-comint-share-input-history=.
+Just go ahead and share you comint REPL buffer! Tested: ~shell~ and
+~cmuscheme~.  By default, when sharing a comint buffer, ~crdt.el~
+temporarily reset input history (as in =M-n= =M-p=) so others don't
+spy into your =.bash_history= and alike.  You can customize this
+behavior using variable =crdt-comint-share-input-history=.
 
 ** What if we don't have a public IP?
 
 There're various workaround.
 
-- You can use [[https://gitlab.com/gjedeer/tuntox][tuntox]] to proxy your 
connection over the [[https://tox.chat][Tox]] protocol.
-  =crdt.el= has experimental built-in integration for =tuntox=.
-  To enable it, you need to install =tuntox=,
-  set up the custom variable =crdt-tuntox-executable= accordingly (the path to 
your =tuntox= binary),
-  and set the custom variable =crdt-use-tuntox=. 
-  Setting it to =t= make =crdt.el= always create =tuntox= proxy for new server 
sessions, 
-  and setting it to ='confirm= make =crdt.el= ask you every time when creating 
new sessions.
-  After starting a session with =tuntox= proxy,
-  you can =M-x crdt-copy-url= to copy a URL recognizable by =M-x crdt-connect= 
and share it to your friends.
-  Be aware that according to my experience, =tuntox= takes significant time to 
establish a connection (sometimes up to half a minute),
+- You can use [[https://gitlab.com/gjedeer/tuntox][tuntox]] to proxy
+  your connection over the [[https://tox.chat][Tox]] protocol.
+  =crdt.el= has experimental built-in integration for =tuntox=.  To
+  enable it, you need to install =tuntox=, set up the custom variable
+  =crdt-tuntox-executable= accordingly (the path to your =tuntox=
+  binary), and set the custom variable =crdt-use-tuntox=.  Setting it
+  to =t= make =crdt.el= always create =tuntox= proxy for new server
+  sessions, and setting it to ='confirm= make =crdt.el= ask you every
+  time when creating new sessions.  After starting a session with
+  =tuntox= proxy, you can =M-x crdt-copy-url= to copy a URL
+  recognizable by =M-x crdt-connect= and share it to your friends.  Be
+  aware that according to my experience, =tuntox= takes significant
+  time to establish a connection (sometimes up to half a minute),
   however it gets much faster after the connection is established.
 
-- You can use Teredo to get a public routable IPv6 address. 
-  One free software implementation is Miredo. Get it from your
-  favorite package manager or from [[https://www.remlab.net/miredo/][their 
website]].
+- You can use Teredo to get a public routable IPv6 address.  One free
+  software implementation is Miredo. Get it from your favorite package
+  manager or from [[https://www.remlab.net/miredo/][their website]].
   A typical usage is (run as root)
   #+BEGIN_SRC
 # /usr/local/sbin/miredo
 # ifconfig teredo
   #+END_SRC
-  The =ifconfig= command should print the information of your IPv6 address.
-  Now your traffic go through IPv6, and once you start a =crdt.el= session,
-  your friends should be able to join using the IPv6 address.
-  For more information, see the user guide on the Miredo website.
+  The =ifconfig= command should print the information of your IPv6
+  address.  Now your traffic go through IPv6, and once you start a
+  =crdt.el= session, your friends should be able to join using the
+  IPv6 address.  For more information, see the user guide on the
+  Miredo website.
 
 - You can use SSH port forwarding if you have a VPS with public IP.
   Example usage:
   #+BEGIN_SRC 
 $ ssh -R EXAMPLE.COM:6530:127.0.0.1:6530 EXAMPLE.COM
   #+END_SRC
-  This make your =crdt.el= session on local port =6530= accessible from
-  =EXAMPLE.COM:6530=.
+  This make your =crdt.el= session on local port =6530= accessible
+  from =EXAMPLE.COM:6530=.
   
-  Note that you need to set the following =/etc/ssh/sshd_config= option on 
-  your VPS
+  Note that you need to set the following =/etc/ssh/sshd_config=
+  option on your VPS
   #+BEGIN_SRC 
 GatewayPorts yes
   #+END_SRC
diff --git a/crdt.el b/crdt.el
index d3768a481d..cfedcc59f3 100644
--- a/crdt.el
+++ b/crdt.el
@@ -370,6 +370,7 @@ Must be used inside CRDT--WITH-INSERTION-INFORMATION."
   next-user-id
   (buffer-table (make-hash-table :test 'equal)) ; maps buffer network name to 
buffer
   follow-user-id
+  my-location-marker ; used to store my location temporarily when 
crdt-goto-{next,prev}-user
   permissions
   (local-fcap-table (make-hash-table))
   (remote-fcap-table (make-hash-table)))
@@ -916,26 +917,78 @@ Directly return the user name under point if in the user 
menu."
       (crdt--read-user session)
       (signal 'quit nil)))
 
-(defun crdt-goto-user (session user-id)
-  "Goto the cursor location of user with USER-ID in SESSION."
+(defun crdt-goto-user (session user-id &optional noswitch)
+  "Goto the cursor location of user with USER-ID in SESSION.
+If NOSWITCH is non-nil, don't switch window."
   (interactive (let ((session (crdt--read-session-maybe)))
                  (list session (crdt--read-user-maybe session))))
   (let ((crdt--session session))
     (if (eq user-id (crdt--session-local-id crdt--session))
-        (funcall (if (eq major-mode 'crdt-user-menu-mode)
-                     #'switch-to-buffer-other-window
-                   #'switch-to-buffer)
-         (gethash (crdt--session-focused-buffer-name crdt--session) 
(crdt--session-buffer-table crdt--session)))
+        (unless noswitch
+          (funcall (if (eq major-mode 'crdt-user-menu-mode)
+                       #'switch-to-buffer-other-window
+                     #'switch-to-buffer)
+                   (gethash (crdt--session-focused-buffer-name crdt--session) 
(crdt--session-buffer-table crdt--session))))
       (unless
           (cl-block nil
             (let* ((metadata (or (gethash user-id (crdt--session-contact-table 
crdt--session)) (cl-return)))
                    (buffer-name (or (crdt--contact-metadata-focus metadata) 
(cl-return))))
               (crdt--with-buffer-name-pull (buffer-name)
-               (switch-to-buffer-other-window (current-buffer))
+               (unless noswitch
+                  (switch-to-buffer-other-window (current-buffer)))
                (ignore-errors (goto-char (overlay-start (car (gethash user-id 
crdt--pseudo-cursor-table)))))
                t)))
         (message "Doesn't have position information for this user yet.")))))
 
+(defun crdt--session-ensure-user-menu-buffer (session)
+  (unless (and (crdt--session-user-menu-buffer session)
+               (buffer-live-p (crdt--session-user-menu-buffer session)))
+    (setf (crdt--session-user-menu-buffer session)
+          (generate-new-buffer (format "*CRDT Users %s*" (crdt--session-urlstr 
session))))
+    (crdt--assimilate-session (crdt--session-user-menu-buffer session))))
+
+(defun crdt--cycle-user (&optional prev)
+  "Move point in user menu buffer and goto its cursor position.
+If user menu buffer does not exist yet, create it.
+If PREV is non-nil, move backward, otherwise move forward.
+When moving into/out of ourselves, push/pop a global marker instead."
+  (unless crdt--session
+    (error "Not a CRDT shared buffer"))
+  (crdt--session-ensure-user-menu-buffer crdt--session)
+  (let ((mark (point-marker)))
+    (with-current-buffer (crdt--session-user-menu-buffer crdt--session)
+      (when (= (point) (point-max))
+        (forward-line -1))
+      (when (eq (tabulated-list-get-id) (crdt--session-local-id crdt--session))
+        (setf (crdt--session-my-location-marker crdt--session) mark)
+        (add-to-history 'global-mark-ring mark global-mark-ring-max t))
+      (if prev
+          (unless (= (forward-line -1) 0)
+            (goto-char (point-max))
+            (forward-line -1))
+        (forward-line)
+        (when (= (point) (point-max))
+          (goto-char (point-min))))
+      (let ((window (get-buffer-window (current-buffer) t)))
+        (when window (set-window-point window (point))))
+      (if (eq (tabulated-list-get-id) (crdt--session-local-id crdt--session))
+          (if (eq (car global-mark-ring) (crdt--session-my-location-marker 
crdt--session))
+              (pop-global-mark)
+            (goto-char (crdt--session-my-location-marker crdt--session)))
+        (crdt-goto-user crdt--session (tabulated-list-get-id) t)))))
+
+(defun crdt-goto-next-user ()
+  "Move point in user menu buffer to next user and goto its cursor position.
+If user menu buffer does not exist yet, create it."
+  (interactive)
+  (crdt--cycle-user))
+
+(defun crdt-goto-prev-user ()
+  "Move point in user menu buffer to previous user and goto its cursor 
position.
+If user menu buffer does not exist yet, create it."
+  (interactive)
+  (crdt--cycle-user t))
+
 (defun crdt-kill-user (session user-id)
   "Disconnect the user with USER-ID in SESSION.
 Only server can perform this action."
@@ -974,10 +1027,7 @@ Only server can perform this action."
     (with-current-buffer (current-buffer)
       (unless crdt--session
         (error "Not a CRDT shared buffer"))
-      (unless (and (crdt--session-user-menu-buffer crdt--session) 
(buffer-live-p (crdt--session-user-menu-buffer crdt--session)))
-        (setf (crdt--session-user-menu-buffer crdt--session)
-              (generate-new-buffer (format "*CRDT Users %s*" 
(crdt--session-urlstr crdt--session))))
-        (crdt--assimilate-session (crdt--session-user-menu-buffer 
crdt--session)))
+      (crdt--session-ensure-user-menu-buffer crdt--session)
       (let ((display-buffer (crdt--session-user-menu-buffer crdt--session)))
         (crdt-refresh-users display-buffer)
         (switch-to-buffer-other-window display-buffer)))))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]