commit 6e9f20b3ff49adfc05a7f4b49b1b92daa4fb1ca9 (HEAD, refs/remotes/origin/master) Author: Glenn Morris Date: Tue Jan 16 21:20:43 2018 -0500 Small cus-start fix for custom-delayed-init-variables * lisp/cus-start.el (custom-delayed-init-variables): Only modify it during startup. diff --git a/lisp/cus-start.el b/lisp/cus-start.el index dace6f7954..4529fa1ac9 100644 --- a/lisp/cus-start.el +++ b/lisp/cus-start.el @@ -705,13 +705,15 @@ since it could result in memory overflow and make Emacs crash." (put symbol 'risky-local-variable (cadr prop))) (if (setq prop (memq :set rest)) (put symbol 'custom-set (cadr prop))) - ;; Note this is the _only_ initialize property we handle. - (if (eq (cadr (memq :initialize rest)) 'custom-initialize-delay) - ;; These vars are defined early and should hence be initialized - ;; early, even if this file happens to be loaded late. so add them - ;; to the end of custom-delayed-init-variables. Otherwise, - ;; auto-save-file-name-transforms will appear in M-x customize-rogue. - (add-to-list 'custom-delayed-init-variables symbol 'append)) + ;; Don't re-add to custom-delayed-init-variables post-startup. + (unless after-init-time + ;; Note this is the _only_ initialize property we handle. + (if (eq (cadr (memq :initialize rest)) 'custom-initialize-delay) + ;; These vars are defined early and should hence be initialized + ;; early, even if this file happens to be loaded late. so add them + ;; to the end of custom-delayed-init-variables. Otherwise, + ;; auto-save-file-name-transforms will appear in customize-rogue. + (add-to-list 'custom-delayed-init-variables symbol 'append))) ;; If this is NOT while dumping Emacs, set up the rest of the ;; customization info. This is the stuff that is not needed ;; until someone does M-x customize etc. commit f121b5d7f3aef080d0019eb39a57de51015ceb39 Author: Lars Ingebrigtsen Date: Tue Jan 16 15:22:11 2018 +0100 Introduce a variable to control ecomplete sorting * lisp/ecomplete.el (ecomplete-sort-predicate): New variable. (ecomplete-get-matches): Use it. diff --git a/doc/misc/message.texi b/doc/misc/message.texi index ca06de38d1..0d5f85f3dc 100644 --- a/doc/misc/message.texi +++ b/doc/misc/message.texi @@ -1485,6 +1485,9 @@ choose one of these completions, use the @kbd{M-n} command to move down to the list. Use @kbd{M-n} and @kbd{M-p} to move down and up the list, and @kbd{RET} to choose a completion. +The @code{ecomplete-sort-predicate} variable controls how +@code{ecomplete} matches are sorted. + @node Spelling @section Spelling @cindex spelling diff --git a/etc/NEWS b/etc/NEWS index abbedcf5ec..872bd3113f 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -230,6 +230,10 @@ are implemented in C using the Jansson library. It's a simple convenience function for looking up MIME types based on file name extensions. ++++ +** The ecomplete sorting has changed to a decay-based algorithm. This +can be controlled by the new `ecomplete-sort-predicate' variable. + * Changes in Emacs 27.1 on Non-Free Operating Systems diff --git a/lisp/ecomplete.el b/lisp/ecomplete.el index 43ab8e691e..2197d9512d 100644 --- a/lisp/ecomplete.el +++ b/lisp/ecomplete.el @@ -70,6 +70,19 @@ :type '(symbol :tag "Coding system") :group 'ecomplete) +(defcustom ecomplete-sort-predicate 'ecomplete-decay + "Predicate to use when sorting matched. +The predicate is called with two parameters that represent the +completion. Each parameter is a list where the first element is +the times the completion has been used, the second is the +timestamp of the most recent usage, and the third item is the +string that was matched." + :type '(radio (function-item :tag "Sort by usage and newness" ecomplete-decay) + (function-item :tag "Sort by times used" ecomplete-usage) + (function-item :tag "Sort by newness" ecomplete-newness) + (function :tag "Other")) + :group 'ecomplete) + ;;; Internal variables. (defvar ecomplete-database nil) @@ -122,8 +135,7 @@ (loop for (key count time text) in elems when (string-match match text) collect (list count time text)) - (lambda (l1 l2) - (> (car l1) (car l2)))))) + ecomplete-sort-predicate))) (when (> (length candidates) 10) (setcdr (nthcdr 10 candidates) nil)) (unless (zerop (length candidates)) @@ -189,6 +201,21 @@ matches." (forward-char 1))) (buffer-string))) +(defun ecomplete-usage (l1 l2) + (> (car l1) (car l2))) + +(defun ecomplete-newness (l1 l2) + (> (cadr l1) (cadr l2))) + +(defun ecomplete-decay (l1 l2) + (> (ecomplete-decay-1 l1) (ecomplete-decay-1 l2))) + +(defun ecomplete-decay-1 (elem) + ;; We subtract 5% from the item for each week it hasn't been used. + (/ (car elem) + (expt 1.05 (/ (- (float-time) (cadr elem)) + (* 7 24 60 60))))) + (provide 'ecomplete) ;;; ecomplete.el ends here commit b02a06317b04b56d54f73a7d97568a0bc150a18b Author: Alan Mackenzie Date: Tue Jan 16 21:59:03 2018 +0000 C++ Mode: Fontify correctly uniform initialisation with inner parentheses. E.g.: someStruct x ( (nullptr != y) ? 3 : 4 ) Also fontify declarations of function pointers correctly. * lisp/progmodes/cc-engine.el (c-forward-decl-or-cast-1): While testing for a typeless declaration, additionally test the variable `got-prefix' to recognize a function pointer in parentheses. Allow c-fdoc-shift-type-backward to be invoked when we have nested parens. diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index e997260281..5a0088df50 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el @@ -8605,6 +8605,7 @@ comment at the start of cc-engine.el for more info." ;; construct here in C, since we want to recognize this as a ;; typeless function declaration. (not (and (c-major-mode-is 'c-mode) + (not got-prefix) (or (eq context 'top) make-top) (eq (char-after) ?\))))) (if (eq (char-after) ?\)) @@ -8634,31 +8635,39 @@ comment at the start of cc-engine.el for more info." ;; (con|de)structors in C++ and `c-typeless-decl-kwds' ;; style declarations. That isn't applicable in an ;; arglist context, though. - (when (and (= paren-depth 1) - (not got-prefix-before-parens) - (not (eq at-type t)) - (or backup-at-type - maybe-typeless - backup-maybe-typeless - (when c-recognize-typeless-decls - (and (memq context '(nil top)) - ;; Deal with C++11's "copy-initialization" - ;; where we have (), by - ;; contrasting with a typeless - ;; (, ...). - (save-excursion - (goto-char after-paren-pos) - (c-forward-syntactic-ws) - (or (c-forward-type) - ;; Recognize a top-level typeless - ;; function declaration in C. - (and (c-major-mode-is 'c-mode) - (or (eq context 'top) make-top) - (eq (char-after) ?\)))))))) - (setq pos (c-up-list-forward (point))) - (eq (char-before pos) ?\))) + (when (and (> paren-depth 0) + (not got-prefix-before-parens) + (not (eq at-type t)) + (or backup-at-type + maybe-typeless + backup-maybe-typeless + (when c-recognize-typeless-decls + (and (memq context '(nil top)) + ;; Deal with C++11's "copy-initialization" + ;; where we have (), by + ;; contrasting with a typeless + ;; (, ...). + (save-excursion + (goto-char after-paren-pos) + (c-forward-syntactic-ws) + (or (c-forward-type) + ;; Recognize a top-level typeless + ;; function declaration in C. + (and (c-major-mode-is 'c-mode) + (or (eq context 'top) make-top) + (eq (char-after) ?\)))))))) + (let ((pd paren-depth)) + (setq pos (point)) + (catch 'pd + (while (> pd 0) + (setq pos (c-up-list-forward pos)) + (when (or (null pos) + (not (eq (char-before pos) ?\)))) + (throw 'pd nil)) + (goto-char pos) + (setq pd (1- pd))) + t))) (c-fdoc-shift-type-backward) - (goto-char pos) t))) (c-forward-syntactic-ws)) commit 743323e570dcb2fdb98a9067073176811fb5428c Author: Lars Ingebrigtsen Date: Tue Jan 16 14:53:11 2018 +0100 Add documentation to ecomplete.el * lisp/ecomplete.el: Add doc strings and document the format. diff --git a/lisp/ecomplete.el b/lisp/ecomplete.el index 87052e34e8..43ab8e691e 100644 --- a/lisp/ecomplete.el +++ b/lisp/ecomplete.el @@ -22,6 +22,35 @@ ;;; Commentary: +;; ecomplete stores matches in a file that looks like this: +;; +;; ((mail +;; ("larsi@gnus.org" 38154 1516109510 "Lars Ingebrigtsen ") +;; ("kfogel@red-bean.com" 10 1516065455 "Karl Fogel ") +;; ... +;; )) +;; +;; That is, it's an alist map where the key is the "type" of match (so +;; that you can have one list of things for `mail' and one for, say, +;; `twitter'). In each of these sections you then have a list where +;; each item is on the form +;; +;; (KEY TIMES-USED LAST-TIME-USED STRING) +;; +;; If you call `ecomplete-display-matches', it will then display all +;; items that match STRING. KEY is unique and is used to identify the +;; item, and is used for updates. For instance, if given the above +;; data, you call +;; +;; (ecomplete-add-item "larsi@gnus.org" 'mail "Lars Magne Ingebrigtsen ") +;; +;; the "larsi@gnus.org" entry will then be updated with that new STRING. + +;; The interface functions are `ecomplete-add-item' and +;; `ecomplete-display-matches', while `ecomplete-setup' should be +;; called to read the .ecompleterc file, and `ecomplete-save' are +;; called to save the file. + ;;; Code: (eval-when-compile @@ -47,6 +76,7 @@ ;;;###autoload (defun ecomplete-setup () + "Read the .ecompleterc file." (when (file-exists-p ecomplete-database-file) (with-temp-buffer (let ((coding-system-for-read ecomplete-database-file-coding-system)) @@ -54,6 +84,7 @@ (setq ecomplete-database (read (current-buffer))))))) (defun ecomplete-add-item (type key text) + "Add item TEXT of TYPE to the database, using KEY as the identifier." (let ((elems (assq type ecomplete-database)) (now (string-to-number (format-time-string "%s"))) entry) @@ -64,9 +95,11 @@ (nconc elems (list (list key 1 now text)))))) (defun ecomplete-get-item (type key) + "Return the text for the item identified by KEY of the required TYPE." (assoc key (cdr (assq type ecomplete-database)))) (defun ecomplete-save () + "Write the .ecompleterc file." (with-temp-buffer (let ((coding-system-for-write ecomplete-database-file-coding-system)) (insert "(") @@ -105,6 +138,9 @@ (buffer-string))))) (defun ecomplete-display-matches (type word &optional choose) + "Display the top-rated elements TYPE that match WORD. +If CHOOSE, allow the user to choose interactively between the +matches." (let* ((matches (ecomplete-get-matches type word)) (line 0) (max-lines (when matches (- (length (split-string matches "\n")) 2)))