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)