branch: elpa/annotate commit f5711b4f27ab877dadf61191bb812237a6553bec Author: cage <cage-invalid@invalid> Commit: cage <cage-invalid@invalid>
- prevent crash and error when a frame's width is less than value of 'annotate-annotation-column'. --- README.md | 53 ++++++++++++++++------------- annotate.el | 108 +++++++++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 108 insertions(+), 53 deletions(-) diff --git a/README.md b/README.md index 24081991d2..dd2cc63027 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Annotate.el [![MELPA][mi]][m] [![MELPA-STABLE][msi]][ms] [msi]: http://stable.melpa.org/packages/annotate-badge.svg [ms]: http://stable.melpa.org/#/annotate -This package provides a minor mode `annotate-mode`, which can add annotations to arbitrary files without changing the files themselves. This is very useful for code reviews. When `annotate-mode` is active, `C-c C-a` will create, edit, or delete annotations. +This package provides a minor mode `annotate-mode`, which can add annotations to arbitrary files without changing the files themselves. This is very useful for code reviews. When `annotate-mode` is active, `C-c C-a` will create, edit, or delete annotations.  @@ -28,65 +28,72 @@ Alternatively, they can be integrated `annotate-integrate-annotations` as commen - annotations in org-mode source blocks will be underlined, but the annotations don't show up. This is likely a fundamental incompatibility with the way source blocks are highlighted and the way annotations are displayed. +Portion of the code © 2019 Universita' degli Studi di Palermo + This package is released under the MIT license. + + ### Changelog -- **2015-06-12 V0.1 Bastian Bechtold** +- **2015-06-12 V0.1 Bastian Bechtold** First working release. -- **2015-06-12 V0.1.1 Bastian Bechtold** +- **2015-06-12 V0.1.1 Bastian Bechtold** Improve documentation and add license. -- **2015-06-12 V0.1.2 Bastian Bechtold** +- **2015-06-12 V0.1.2 Bastian Bechtold** Fix typo and version error. -- **2015-06-15 V0.1.3 Bastian Bechtold** +- **2015-06-15 V0.1.3 Bastian Bechtold** Improve README and auto-remove empty annotations created by earlier bug. -- **2015-06-15 V0.1.4 Bastian Bechtold** +- **2015-06-15 V0.1.4 Bastian Bechtold** Minor bug fixes. -- **2015-06-15 V0.1.5 Bastian Bechtold** +- **2015-06-15 V0.1.5 Bastian Bechtold** Annotations now work on long lines. -- **2015-06-19 V0.2.0 Bastian Bechtold** - Annotations can be exported as unified diff files. +- **2015-06-19 V0.2.0 Bastian Bechtold** + Annotations can be exported as unified diff files. Several smaller bug fixes. -- **2015-06-19 V0.2.1 Bastian Bechtold** +- **2015-06-19 V0.2.1 Bastian Bechtold** Now with fewer compile warnings (turns out, not really). -- **2015-06-19 V0.2.2 Bastian Bechtold** +- **2015-06-19 V0.2.2 Bastian Bechtold** Now with more compile warnings (0.2.1 didn't work). -- **2015-07-02 V0.2.3 Bastian Bechtold** +- **2015-07-02 V0.2.3 Bastian Bechtold** Can now disable minibuffer messages. -- **2015-09-17 V0.2.4 Bastian Bechtold** +- **2015-09-17 V0.2.4 Bastian Bechtold** Load and Clear don't mark buffer as modified any more. -- **2015-09-21 V0.3.0 Bastian Bechtold** +- **2015-09-21 V0.3.0 Bastian Bechtold** Add key bindings for jumping to next/previous annotation. -- **2015-09-22 V0.3.1 Bastian Bechtold** - Change key bindings for jumping as to conform with Emacs' standards. +- **2015-09-22 V0.3.1 Bastian Bechtold** + Change key bindings for jumping as to conform with Emacs' standards. Didn't change the main key binding though, because I don't know a good alternative. -- **2015-09-23 V0.4.0 Bastian Bechtold** +- **2015-09-23 V0.4.0 Bastian Bechtold** Completely reworked the display engine for annotations. You can now have several annotations per line, and annotations should not move any more when editing the line they are on. Finally, annotations can now span several lines. -- **2015-10-06 V0.4.3 Bastian Bechtold** +- **2015-10-06 V0.4.3 Bastian Bechtold** Bugfixes. No more hidden newlines, no more annotations in undo-list, no more error messages with annotations at bol, mark deactivated after creating annotation, annotations auto-reflow on frame size change. -- **2015-10-06 V0.4.4 Bastian Bechtold** +- **2015-10-06 V0.4.4 Bastian Bechtold** Added a new export system. Let's see if it turns out to be more useful than the previous one. - -- **2016-08-25 V0.4.5 Bastian Bechtold** + +- **2016-08-25 V0.4.5 Bastian Bechtold** Bugfix release for unicode annotations and multiline annotations. -- **2016-09-07 V0.4.6 Bastian Bechtold** +- **2016-09-07 V0.4.6 Bastian Bechtold** Bugfix release for annotations ending on an empty line. -- **2016-10-06 V0.4.7 Bastian Bechtold** +- **2016-10-06 V0.4.7 Bastian Bechtold** Bugfix release for buffers without a file name. + +- **2019-08-29 V0.4.8 cage** + Bugfix release for annotation on narrow frames. diff --git a/annotate.el b/annotate.el index 09aa162f43..d3097a55a7 100644 --- a/annotate.el +++ b/annotate.el @@ -5,7 +5,7 @@ ;; Maintainer: Bastian Bechtold ;; URL: https://github.com/bastibe/annotate.el ;; Created: 2015-06-10 -;; Version: 0.4.7 +;; Version: 0.4.8 ;; This file is NOT part of GNU Emacs. @@ -391,37 +391,85 @@ annotation plus the newline." (re-search-forward "\\(.*\\(\n\\)\\)") t))) +(cl-defstruct group + words + start-word) + +(defun group-by-width (text maximum-width) + "Groups text in a list formed by chunks of maximum size equal +to 'maximum-width'." + (cl-labels ((next-word (words) + (or (cl-first words) + "")) + (join-until-width (words &optional (word nil)) + (cond + ((null words) + (make-group :words nil + :start-word word)) + (t + (let* ((next-word (next-word words)) + (new-word (if word + (concat word " " next-word) + next-word))) + (if (<= (string-width new-word) + maximum-width) + (join-until-width (cl-rest words) new-word) + (make-group :words words + :start-word (or word next-word))))))) + (%group (words so-far) + (cond + ((null words) + so-far) + ((<= (string-width (cl-first words)) + maximum-width) + (let* ((potential-start (join-until-width words)) + (word (group-start-word potential-start)) + (nonjoined-words (group-words potential-start)) + (next-word (cl-first nonjoined-words)) + (rest-words nonjoined-words) + (potential-start word)) + (%group rest-words + (append (list potential-start) + so-far)))) + (t + (let* ((word (cl-first words)) + (rest-words (cl-rest words)) + (prefix (cl-subseq word 0 maximum-width)) + (next-word (if rest-words + (cl-first rest-words) + "")) + (raw-suffix (cl-subseq word maximum-width)) + (suffix (if rest-words + (concat raw-suffix " " next-word) + raw-suffix))) + (%group (append (list suffix) + (cl-rest rest-words)) + (append (list prefix) + so-far))))))) + (if (< maximum-width 1) + nil + (let* ((words (split-string text " " t)) + (grouped (reverse (%group words '())))) + grouped)))) + (defun annotate-lineate (text line-width) "Breaks `text` into lines to fit in the annotation space" - (let ((available-width (- (window-body-width) - annotate-annotation-column)) - ;; if the annotation won't fit at the end of the line: - (lineated (if (< line-width annotate-annotation-column) "" "\n")) - (current-pos 0)) - (while (< current-pos (length text)) - (let ((current-line - (substring text current-pos - (min (length text) - (+ current-pos available-width -1))))) - ;; discard characters until the string fits within the available width - ;; this can happen with unicode characters that are wider than one col - (while (> (string-width current-line) available-width) - (setq current-line (substring current-line 0 -1))) - ;; strip partial last word if necessary, for word wrap: - (when (and (string-match "[^ ]$" current-line) - (< (+ current-pos (length current-line)) (length text))) - (string-match "[ ][^ ]+$" current-line) - (setq current-line (replace-match " " nil nil current-line))) - ;; append white space to the end of continued lines - (let ((postfix (if (< (length current-line) (length text)) - (make-string (- available-width (string-width current-line) 1) ? ) - ""))) - (setq lineated (concat lineated current-line postfix "\n") - current-pos (+ current-pos (length current-line)))))) - ;; strip trailing newline, if any - (if (string= (substring lineated (1- (length lineated))) "\n") - (substring lineated 0 (1- (length lineated))) - lineated))) + (let* ((theoretical-line-width (- (window-body-width) + annotate-annotation-column)) + (available-width (if (> theoretical-line-width 0) + theoretical-line-width + line-width)) + (lineated-list (group-by-width text available-width)) + (lineated (cl-mapcar (lambda (a) + (let* ((size (string-width a)) + (rest-width (max (- available-width + size) + 0)) + (padding (make-string rest-width + ? ))) + (concat a padding "\n"))) + lineated-list))) + (apply #'concat lineated))) (defun annotate--annotation-builder () "Searches the line before point for annotations, and returns a