commit 33dbe23bb8114d6a71ad267b0e172909dab7b387 (HEAD, refs/remotes/origin/master) Author: Dmitry Gutov Date: Thu Feb 14 04:08:44 2019 +0300 Rename project-query-replace to project-query-replace-regexp * lisp/progmodes/project.el (project-query-replace): Rename to project-query-replace-regexp. diff --git a/etc/NEWS b/etc/NEWS index 75c8dc0b8e..1d79b05bc9 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -386,7 +386,7 @@ The mode is automatically enabled in files that start with the 'function' keyword. ** project.el -*** New commands 'project-search' and 'project-query-replace'. +*** New commands 'project-search' and 'project-query-replace-regexp'. ** Etags diff --git a/lisp/ldefs-boot.el b/lisp/ldefs-boot.el index b913b1bb36..a6c7669c70 100644 --- a/lisp/ldefs-boot.el +++ b/lisp/ldefs-boot.el @@ -26459,7 +26459,7 @@ To continue searching for next match, use command \\[fileloop-continue]. \(fn REGEXP)" t nil) -(autoload 'project-query-replace "project" "\ +(autoload 'project-query-replace-regexp "project" "\ Search for REGEXP in all the files of the project. Stops when a match is found. To continue searching for next match, use command \\[fileloop-continue]. diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index fbf761c60c..533e27be7e 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -532,7 +532,7 @@ To continue searching for next match, use command \\[fileloop-continue]." (fileloop-continue)) ;;;###autoload -(defun project-query-replace (from to) +(defun project-query-replace-regexp (from to) "Search for REGEXP in all the files of the project. Stops when a match is found. To continue searching for next match, use command \\[fileloop-continue]." commit a48099ce7ff63cda416a870766fe61f5b8ac7c2c Author: Gregor Zattler Date: Wed Feb 13 21:01:17 2019 +0100 * doc/misc/eshell.texi (Built-ins): Fix alias description Dear eamcs developers, eshells current documentation first states that alias definitions are not saved to an alias file, later that they are saved to an alias file. I tested it and the latter is correct. Please find attached a patch which fixes this. Thanks for working on emacs which is really great, Gregor >From 1fe51cc769ab7a30d0896fb3d6105c0561243fa7 Mon Sep 17 00:00:00 2001 From: Gregor Zattler Date: Wed, 13 Feb 2019 20:19:38 +0100 Subject: * doc/misc/eshell.texi (Built-ins): Fix alias description. Bring description of built-in 'alias' in line with (info "(eshell) Aliases"), which describes the actual behaviur. diff --git a/doc/misc/eshell.texi b/doc/misc/eshell.texi index dcb4aac2d8..3540707318 100644 --- a/doc/misc/eshell.texi +++ b/doc/misc/eshell.texi @@ -280,8 +280,7 @@ with no arguments, prints the current paths in this variable. @item alias @cmindex alias -Define an alias (@pxref{Aliases}). This does not add it to the aliases -file. +Define an alias (@pxref{Aliases}). This adds it to the aliases file. @item clear @cmindex clear commit 9a7519ce8fa4b75e3b442977dec88bb38c2d9844 Author: Paul Eggert Date: Wed Feb 13 15:03:01 2019 -0800 Add missing dependency to ucs-normalize.el * lisp/international/ucs-normalize.el: Require regexp-opt when compiling. Problem reported by hx in: https://lists.gnu.org/r/emacs-devel/2019-02/msg00334.html diff --git a/lisp/international/ucs-normalize.el b/lisp/international/ucs-normalize.el index 9d55470d94..6f1e770c09 100644 --- a/lisp/international/ucs-normalize.el +++ b/lisp/international/ucs-normalize.el @@ -109,7 +109,9 @@ (defconst ucs-normalize-version "1.2") -(eval-when-compile (require 'cl-lib)) +(eval-when-compile + (require 'cl-lib) + (require 'regexp-opt)) (declare-function nfd "ucs-normalize" (char)) commit b0e318d27f10b820f1cfad6ea98793c11fc782a4 Author: João Távora Date: Tue Feb 12 21:55:34 2019 +0000 Score flex-style completions according to match tightness The new completion style needs to score completion matches so that we can use it later on when sorting the completions. This is because "foo" can flex-match "foobar", "frodo" and "barfromsober" but we probably want "foobar" to appear at the top of the completion list. This change introduces a scoring formula and adds scoring hints in the candidate string's `completion-score' property. * lisp/minibuffer.el (completion-pcm--hilit-commonality): Propertize completion with 'completion-score (flex-score-falloff): New variable. diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index c1e3fdc078..daa8dba8c9 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -3042,6 +3042,22 @@ PATTERN is as returned by `completion-pcm--string->pattern'." (when (string-match-p regex c) (push c poss))) (nreverse poss)))))) +(defvar flex-score-falloff -1.5 + "Controls how the `flex' completion style scores its matches. + +Value is a number whose sign and amplitude have subtly different +effects. Positive values make the scoring formula value matches +scattered along the string, while negative values make the +formula value tighter matches. I.e \"foo\" matches both strings +\"barfoobaz\" and \"fabrobazo\", which are of equal length, but +only a negative value will score the former higher than the +second. + +The absolute value of this variable controls the relative order +of different-length strings matched by the same pattern . Its +effect is not completely understood yet, so feel free to play +around with it.") + (defun completion-pcm--hilit-commonality (pattern completions) (when completions (let* ((re (completion-pcm--pattern->regex pattern 'group)) @@ -3056,8 +3072,45 @@ PATTERN is as returned by `completion-pcm--string->pattern'." (let* ((pos (if point-idx (match-beginning point-idx) (match-end 0))) (md (match-data)) (start (pop md)) - (end (pop md))) + (end (pop md)) + (len (length str)) + ;; To understand how this works, consider these bad + ;; ascii(tm) diagrams showing how the pattern \"foo\" + ;; flex-matches \"fabrobazo" and + ;; \"barfoobaz\": + + ;; f abr o baz o + ;; + --- + --- + + + ;; bar foo baz + ;; --- +++ --- + + ;; Where + indicates parts where the pattern matched, + ;; - where it didn't match. The score is a number + ;; bound by ]0..1]: the higher the better and only a + ;; perfect match (pattern equals string) will have + ;; score 1. The formula takes the form of a quotient. + ;; For the numerator, we use the number of +, i.e. the + ;; length of the pattern. For the denominator, it + ;; counts the number of - in each such group, + ;; exponentiates that number to `flex-score-falloff', + ;; adds it to the total, adds one to the final sum, + ;; and then multiples by the length of the string. + (score-numerator 0) + (score-denominator 0) + (last-b 0) + (update-score + (lambda (a b) + "Update score variables given match range (A B)." + (setq + score-numerator (+ score-numerator (- b a)) + score-denominator (+ score-denominator + (expt (- a last-b) + flex-score-falloff)) + last-b b)))) + (funcall update-score 0 start) (while md + (funcall update-score start (car md)) (put-text-property start (pop md) 'font-lock-face 'completions-common-part str) @@ -3065,11 +3118,16 @@ PATTERN is as returned by `completion-pcm--string->pattern'." (put-text-property start end 'font-lock-face 'completions-common-part str) + (funcall update-score start end) (if (> (length str) pos) (put-text-property pos (1+ pos) - 'font-lock-face 'completions-first-difference - str))) - str) + 'font-lock-face 'completions-first-difference + str)) + (unless (zerop (length str)) + (put-text-property + 0 1 'completion-score + (/ score-numerator (* len (1+ score-denominator)) 1.0) str))) + str) completions)))) (defun completion-pcm--find-all-completions (string table pred point commit e4896fcb1189f6739f228d441b6c50118536e3d8 Author: João Távora Date: Tue Feb 12 21:48:24 2019 +0000 Add a new 'flex' completion style * lisp/minibuffer.el (completion-styles-alist): Add flex. (completion-substring--all-completions): Accept transform-pattern-fn arg. (completion-flex-all-completions, completion-flex-try-completion) (completion-flex--make-flex-pattern): New functions. diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index b757eb8a5a..c1e3fdc078 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -788,6 +788,11 @@ Additionally the user can use the char \"*\" as a glob pattern.") I.e. when completing \"foo_bar\" (where _ is the position of point), it will consider all completions candidates matching the glob pattern \"*foo*bar*\".") + (flex + completion-flex-try-completion completion-flex-all-completions + "Completion of an in-order subset of characters. +When completing \"foo\" the glob \"*f*o*o*\" is used, so that +i.e. foo can complete to frodo.") (initials completion-initials-try-completion completion-initials-all-completions "Completion of acronyms and initialisms. @@ -3345,7 +3350,12 @@ the same set of elements." ;;; Substring completion ;; Mostly derived from the code of `basic' completion. -(defun completion-substring--all-completions (string table pred point) +(defun completion-substring--all-completions + (string table pred point &optional transform-pattern-fn) + "Match the presumed substring STRING to the entries in TABLE. +Respect PRED and POINT. The pattern used is a PCM-style +substring pattern, but it be massaged by TRANSFORM-PATTERN-FN, if +that is non-nil." (let* ((beforepoint (substring string 0 point)) (afterpoint (substring string point)) (bounds (completion-boundaries beforepoint table pred afterpoint)) @@ -3356,6 +3366,9 @@ the same set of elements." (pattern (if (not (stringp (car basic-pattern))) basic-pattern (cons 'prefix basic-pattern))) + (pattern (if transform-pattern-fn + (funcall transform-pattern-fn pattern) + pattern)) (all (completion-pcm--all-completions prefix pattern table pred))) (list all pattern prefix suffix (car bounds)))) @@ -3375,6 +3388,52 @@ the same set of elements." (nconc (completion-pcm--hilit-commonality pattern all) (length prefix))))) +;;; "flex" completion, also known as flx/fuzzy/scatter completion +;; Completes "foo" to "frodo" and "farfromsober" + +(defun completion-flex--make-flex-pattern (pattern) + "Convert PCM-style PATTERN into PCM-style flex pattern. + +This turns + (prefix \"foo\" point) +into + (prefix \"f\" any \"o\" any \"o\" any point) +which is at the core of flex logic. The extra +'any' is optimized away later on." + (mapcan (lambda (elem) + (if (stringp elem) + (mapcan (lambda (char) + (list (string char) 'any)) + elem) + (list elem))) + pattern)) + +(defun completion-flex-try-completion (string table pred point) + "Try to flex-complete STRING in TABLE given PRED and POINT." + (pcase-let ((`(,all ,pattern ,prefix ,suffix ,_carbounds) + (completion-substring--all-completions + string table pred point + #'completion-flex--make-flex-pattern))) + (if minibuffer-completing-file-name + (setq all (completion-pcm--filename-try-filter all))) + ;; Try some "merging", meaning add as much as possible to the + ;; user's pattern without losing any possible matches in `all'. + ;; i.e this will augment "cfi" to "config" if all candidates + ;; contain the substring "config". FIXME: this still won't + ;; augment "foo" to "froo" when matching "frodo" and + ;; "farfromsober". + (completion-pcm--merge-try pattern all prefix suffix))) + +(defun completion-flex-all-completions (string table pred point) + "Get flex-completions of STRING in TABLE, given PRED and POINT." + (pcase-let ((`(,all ,pattern ,prefix ,_suffix ,_carbounds) + (completion-substring--all-completions + string table pred point + #'completion-flex--make-flex-pattern))) + (when all + (nconc (completion-pcm--hilit-commonality pattern all) + (length prefix))))) + ;; Initials completion ;; Complete /ums to /usr/monnier/src or lch to list-command-history. commit 10527fca66e39d7067986904161fa33741abcd26 Author: Eli Zaretskii Date: Wed Feb 13 17:39:31 2019 +0200 Avoid crashes upon C-g in nested invocations of 'read_char' * src/keyboard.c (read_char, read_event_from_main_queue): Ensure the global value of getcjmp is restored when the stack is unwound by the likes of 'throw', by calling record_unwind_protect_ptr instead of restoring the value manually. (Bug#34394) (restore_getcjmp): Argument is now 'void *', to match the signature of record_unwind_protect_ptr. diff --git a/src/keyboard.c b/src/keyboard.c index cd1747ea88..1d67c3eaab 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -360,7 +360,7 @@ static Lisp_Object make_lispy_focus_in (Lisp_Object); static Lisp_Object make_lispy_focus_out (Lisp_Object); static bool help_char_p (Lisp_Object); static void save_getcjmp (sys_jmp_buf); -static void restore_getcjmp (sys_jmp_buf); +static void restore_getcjmp (void *); static Lisp_Object apply_modifiers (int, Lisp_Object); static void restore_kboard_configuration (int); static void handle_interrupt (bool); @@ -2126,12 +2126,14 @@ read_event_from_main_queue (struct timespec *end_time, return c; /* Actually read a character, waiting if necessary. */ + ptrdiff_t count = SPECPDL_INDEX (); save_getcjmp (save_jump); + record_unwind_protect_ptr (restore_getcjmp, save_jump); restore_getcjmp (local_getcjmp); if (!end_time) timer_start_idle (); c = kbd_buffer_get_event (&kb, used_mouse_menu, end_time); - restore_getcjmp (save_jump); + unbind_to (count, Qnil); if (! NILP (c) && (kb != current_kboard)) { @@ -2620,10 +2622,12 @@ read_char (int commandflag, Lisp_Object map, { Lisp_Object tem0; + ptrdiff_t count = SPECPDL_INDEX (); save_getcjmp (save_jump); + record_unwind_protect_ptr (restore_getcjmp, save_jump); restore_getcjmp (local_getcjmp); tem0 = sit_for (Vecho_keystrokes, 1, 1); - restore_getcjmp (save_jump); + unbind_to (count, Qnil); if (EQ (tem0, Qt) && ! CONSP (Vunread_command_events)) echo_now (); @@ -2694,10 +2698,12 @@ read_char (int commandflag, Lisp_Object map, timeout = min (timeout, MOST_POSITIVE_FIXNUM / delay_level * 4); timeout = delay_level * timeout / 4; + ptrdiff_t count1 = SPECPDL_INDEX (); save_getcjmp (save_jump); + record_unwind_protect_ptr (restore_getcjmp, save_jump); restore_getcjmp (local_getcjmp); tem0 = sit_for (make_fixnum (timeout), 1, 1); - restore_getcjmp (save_jump); + unbind_to (count1, Qnil); if (EQ (tem0, Qt) && ! CONSP (Vunread_command_events)) @@ -3320,7 +3326,7 @@ save_getcjmp (sys_jmp_buf temp) } static void -restore_getcjmp (sys_jmp_buf temp) +restore_getcjmp (void *temp) { memcpy (getcjmp, temp, sizeof getcjmp); }