branch: externals/cm-mode
commit 493e3a5d9c29d267439d37dad0b0e792655346e8
Author: Joost Kremers <[email protected]>
Commit: Joost Kremers <[email protected]>

    Add navigation functions.
---
 README.md  |   5 +++
 cm-mode.el | 148 ++++++++++++++++++++++++-------------------------------------
 2 files changed, 63 insertions(+), 90 deletions(-)

diff --git a/README.md b/README.md
index be48e86abf..ba72231a4d 100644
--- a/README.md
+++ b/README.md
@@ -34,6 +34,11 @@ If you set the variable `cm-auto-comment` to a string, this 
string is automatica
 The variable `cm-auto-comment` can be set globally through Customize (or with 
`setq-default`), or buffer-locally. The latter can be done interactively, with 
`C-c * C`, or by using a file-local variable.
 
 
+## Navigating changes ##
+
+You can jump to the previous/next change with the commands `C-c * b` and `C-c 
* f`, respectively. If point is inside a change, you can jump out of it with 
`C-c * *`.
+
+
 ## Accepting or rejecting changes ##
 
 One can interactively accept or reject a change by putting the cursor inside 
it and hitting `C-c * i`. For additions, deletions and substitutions, you get a 
choice between `a` to accept the change or `r` to reject it. There are two 
other choices, `s` to skip this change or `q` to quit. Both leave the change 
untouched and if you're just dealing with the change at point, they are 
essentially identical. {>>They have different functions when accepting or 
rejecting all changes interactively,  [...]
diff --git a/cm-mode.el b/cm-mode.el
index 288543cd31..34c5bc6a19 100644
--- a/cm-mode.el
+++ b/cm-mode.el
@@ -35,94 +35,33 @@
 
 ;; CriticMarkup for Emacs
 ;; ======================
-;;
-;; cm-mode is a minor mode that provides support for CriticMarkup in Emacs.
-;;
+;; 
+;; `cm-mode' is a minor mode that provides support for CriticMarkup in Emacs.
+;; 
 ;; CriticMarkup defines the following patterns for marking changes to a
 ;; text:
+;; 
+;; - Addition {++ ++}
+;; - Deletion {-- --}
+;; - Substitution {~~ ~> ~~}
+;; - Comment {>> <<}
+;; - Highlight {{ }}{>> <<}
+;; 
+;; `cm-mode' provides the following functionality:
 ;;
-;; -   Addition {++ ++}
-;; -   Deletion {-- --}
-;; -   Substitution {~~ ~> ~~}
-;; -   Comment {>> <<}
-;; -   Highlight {{ }}{>> <<}
-;;
-;; Activating cm-mode provides key bindings to insert the markup above and
-;; thus mark one's changes to the text. The provided key bindings are:
-;;
-;; -   C-c * a: add text
-;; -   C-c * d: delete text
-;; -   C-c * s: substitute text
-;; -   C-c * c: insert a comment (possibly with highlight)
-;;
-;; The commands to delete or substitute text operate on the region. The
-;; command to insert a comment can be used with an active region, in which
-;; case the text in the region will be highlighted. It can also be used
-;; inside an existing markup to add a comment to it. If it is used anywhere
-;; else, it just adds a lone comment. The commands for inserting and
-;; substituting text and for inserting a comment all put the cursor at the
-;; correct position, so you can start typing right away.
-;;
-;; Follow changes mode
-;; -------------------
-;;
-;; cm-mode also provides a simple 'follow changes' mode. When activated,
-;; changes you make to the buffer are automatically marked as insertions or
-;; deletions. Substitutions cannot be made automatically (that is, if you
-;; mark a word, delete it and then type a replacement, it will still be
-;; marked as sequence of deletion+insertion, not as a substitution), but
-;; they can still be made manually with C-c * s. You can activate and
-;; deactivate follow changes mode with C-c * F. When it's active, the
-;; modeline indicator for cm-mode changes from cm to cm*.
-;;
-;; Follow changes mode should be considered experimental, so try at your
-;; own risk. If you run into problems, open an issue on Github or send me
-;; an email.
-;;
-;; Accepting or rejecting changes
-;; ------------------------------
-;;
-;; One can interactively accept or reject a change by putting the cursor
-;; inside it and hitting C-c * i. For additions, deletions and
-;; substitutions, you get a choice between a to accept the change or r to
-;; reject it. There are two other choices, s to skip this change or q to
-;; quit. Both leave the change untouched and if you're just dealing with
-;; the change at point, they are essentially identical.
-;;
-;; For comments and highlights, the choices are different: d to delete the
-;; comment or highlight (whereby the latter of course retains the
-;; highlighted text, but the comment and the markup are removed), or k to
-;; keep the comment or highlight. Again q quits and is essentially
-;; identical to k. (Note that you can also use s instead of k, in case you
-;; get used to skipping changes that way.)
-;;
-;; You can interactively accept or reject all changes with C-c * I (that is
-;; a capital i). This will go through each change asking you whether you
-;; want to accept, reject or skip it, or delete or keep it. Typing q quits
-;; the accept/reject session.
-;;
-;; Font lock
-;; ---------
-;;
-;; cm-mode also adds the markup patterns defined by CriticMarkup to
-;; font-lock-keywords and provides customisable faces to highlight them.
-;; The customisation group is called criticmarkup.
-;;
-;; You may notice that changes that span multiple lines are not
-;; highlighted. The reason for this is that multiline font lock in Emacs is
-;; not straightforward. There are ways to deal with this, but since cm-mode
-;; is a minor mode, it could interfere with the major mode's font locking
-;; mechanism if it did that.
-;;
-;; To mitigate this problem, you can use soft wrap (with visual-line-mode).
-;; Since each paragraph is then essentially a single line, font lock works
-;; even across multiple (visual) lines.
+;; - font lock support
+;; - key bindings to insert CriticMarkup.
+;; - 'follow changes' mode: automatically record changes to the buffer.
+;; - accept/reject changes interactively.
+;; - navigation to move between changes.
 ;;
+;; See README.md for details.
+;; 
 ;; TODO
 ;; ----
-;;
-;; -   Commands to accept or reject all changes in one go.
-;; -   Mouse support?
+;; 
+;; - Commands to accept or reject all changes in one go.
+;; - Mouse support?
 
 ;;; Code:
 
@@ -224,6 +163,10 @@ flag to indicate this. (Though they should actually use 
the macro
     (define-key map "\C-c*c" 'cm-comment)
     (define-key map "\C-c*i" 'cm-accept/reject-change-at-point)
     (define-key map "\C-c*I" 'cm-accept/reject-all-changes)
+    (define-key map "\C-c**" 'cm-forward-out-of-change)
+    (define-key map "\C-c*f" 'cm-forward-change)
+    (define-key map "\C-c*b" 'cm-backward-change)
+    (define-key map "\C-c*C" 'cm-set-auto-comment)
     (define-key map "\C-c*F" 'cm-follow-changes)
     map)
   "Keymap for cm-mode.")
@@ -421,7 +364,7 @@ If point is in an existing change, the comment is added 
after it."
 
 (defun cm-point-at-delim (delim &optional end strict)
   "Return non-NIL if point is at a delimiter.
-If DELIM is an end delimiter, optional argument END must be T.
+If DELIM is an end delimiter, optional argument END must be T. 
 
 Point counts as being at delim if it is in a delimiter or
 directly outside, but not when it is directly inside. So `|{++',
@@ -654,7 +597,7 @@ is of any other type, check if there's a commend and 
include it."
      ((eq (car change) 'cm-comment)
       (save-excursion
         (cm-beginning-of-comment)
-        (backward-char 3)               ; hard-coded adjustment of point
+        (backward-char 3)               ; hard-coded adjustment of point 
         (let ((preceding (cm-markup-at-point)))
           (if preceding
               (list (car preceding) (concat (second preceding) (second 
change)) (third preceding) (fourth change))
@@ -689,7 +632,7 @@ is NIL."
                                                 (capitalize (substring 
(symbol-name (car change)) 3)))
                                         '(?d ?k ?s ?q) t)))))
         (delete-overlay cm-current-markup-overlay)
-        (when (and (not interactive) (eq action ?q)) ; if the user aborted
+        (when (and (not interactive) (eq action ?q)) ; if the user aborted 
           (throw 'quit nil))                         ; get out
         (cond
          ((memq action '(?a ?r ?d))
@@ -735,11 +678,36 @@ substitutions, `d' for comments and highlights."
   "Accept/reject all changes interactively."
   (interactive)
   (catch 'quit
-    (let ((delims-regexp (regexp-opt (mapcar #'second cm-delimiters))))
-      (goto-char (point-min))
-      (while (re-search-forward delims-regexp nil t)
-        (let ((pos (cm-accept/reject-change-at-point)))
-          (when pos (goto-char pos))))))) ; move to the end of current change
+    (goto-char (point-min))
+    (while (cm-forward-change)
+      (let ((pos (cm-accept/reject-change-at-point)))
+        (when pos (goto-char pos)))))) ; move to the end of current change
+
+(defun cm-forward-out-of-change ()
+  "Move forward out of the change at point."
+  (interactive)
+  (let ((change (cm-expand-change (cm-markup-at-point))))
+    (if change
+        (goto-char (fourth change)))))
+
+(defun cm-forward-change (&optional n)
+  "Move forward to the N'th next change."
+  (interactive "p")
+  (or n (setq n 1))
+  (funcall (if (> n 0)
+               're-search-forward
+             're-search-backward)
+           (regexp-opt (mapcar #'second cm-delimiters)) nil t (abs n)))
+
+(defun cm-backward-change (&optional n)
+  "Move backward to the N'th preceding change."
+  (interactive "p")
+  (cm-forward-change (- n)))
+
+(defun cm-set-auto-comment (str)
+  "Set the auto-comment string."
+  (interactive "sSet auto-comment to: ")
+  (setq cm-auto-comment (if (string= str "") nil str)))
 
 (provide 'cm-mode)
 

Reply via email to