aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
Diffstat (limited to 'lisp')
-rw-r--r--lisp/dired.el2
-rw-r--r--lisp/emacs-lisp/map.el208
-rw-r--r--lisp/isearch.el25
-rw-r--r--lisp/progmodes/flymake.el21
-rw-r--r--lisp/progmodes/ruby-mode.el4
-rw-r--r--lisp/vc/vc-git.el7
-rw-r--r--lisp/vc/vc.el63
7 files changed, 190 insertions, 140 deletions
diff --git a/lisp/dired.el b/lisp/dired.el
index e5dc8623a49..72725dc8a09 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -1530,7 +1530,7 @@ change; the point does."
1530 ;; Sanity check of the point marker. 1530 ;; Sanity check of the point marker.
1531 (when (and (markerp point) 1531 (when (and (markerp point)
1532 (eq (marker-buffer point) buffer)) 1532 (eq (marker-buffer point) buffer))
1533 (unless (and (nth 0 prev) 1533 (unless (and (nth 1 prev)
1534 (dired-goto-file (nth 1 prev))) 1534 (dired-goto-file (nth 1 prev)))
1535 (goto-char (point-min)) 1535 (goto-char (point-min))
1536 (forward-line (1- (nth 2 prev)))) 1536 (forward-line (1- (nth 2 prev))))
diff --git a/lisp/emacs-lisp/map.el b/lisp/emacs-lisp/map.el
index 987521d9d85..35759db6270 100644
--- a/lisp/emacs-lisp/map.el
+++ b/lisp/emacs-lisp/map.el
@@ -92,17 +92,17 @@ Returns the result of evaluating the form associated with MAP-VAR's type."
92 `(cond ((listp ,map-var) ,(plist-get args :list)) 92 `(cond ((listp ,map-var) ,(plist-get args :list))
93 ((hash-table-p ,map-var) ,(plist-get args :hash-table)) 93 ((hash-table-p ,map-var) ,(plist-get args :hash-table))
94 ((arrayp ,map-var) ,(plist-get args :array)) 94 ((arrayp ,map-var) ,(plist-get args :array))
95 (t (error "Unsupported map: %s" ,map-var))))) 95 (t (error "Unsupported map type `%S': %S"
96 (type-of ,map-var) ,map-var)))))
96 97
97(defun map-elt (map key &optional default testfn) 98(cl-defgeneric map-elt (map key &optional default testfn)
98 "Lookup KEY in MAP and return its associated value. 99 "Lookup KEY in MAP and return its associated value.
99If KEY is not found, return DEFAULT which defaults to nil. 100If KEY is not found, return DEFAULT which defaults to nil.
100 101
101If MAP is a list, `eql' is used to lookup KEY. Optional argument 102TESTFN is deprecated. Its default depends on the MAP argument.
102TESTFN, if non-nil, means use its function definition instead of 103If MAP is a list, the default is `eql' to lookup KEY.
103`eql'.
104 104
105MAP can be a list, hash-table or array." 105In the base definition, MAP can be an alist, hash-table, or array."
106 (declare 106 (declare
107 (gv-expander 107 (gv-expander
108 (lambda (do) 108 (lambda (do)
@@ -118,7 +118,7 @@ MAP can be a list, hash-table or array."
118 ,default nil ,testfn) 118 ,default nil ,testfn)
119 do) 119 do)
120 ,(funcall do `(map-elt ,mgetter ,key ,default) 120 ,(funcall do `(map-elt ,mgetter ,key ,default)
121 (lambda (v) `(map--put ,mgetter ,key ,v))))))))) 121 (lambda (v) `(map-put! ,mgetter ,key ,v)))))))))
122 (map--dispatch map 122 (map--dispatch map
123 :list (alist-get key map default nil testfn) 123 :list (alist-get key map default nil testfn)
124 :hash-table (gethash key map default) 124 :hash-table (gethash key map default)
@@ -133,9 +133,10 @@ with VALUE.
133When MAP is a list, test equality with TESTFN if non-nil, otherwise use `eql'. 133When MAP is a list, test equality with TESTFN if non-nil, otherwise use `eql'.
134 134
135MAP can be a list, hash-table or array." 135MAP can be a list, hash-table or array."
136 (declare (obsolete "use map-put! or (setf (map-elt ...) ...) instead" "27.1"))
136 `(setf (map-elt ,map ,key nil ,testfn) ,value)) 137 `(setf (map-elt ,map ,key nil ,testfn) ,value))
137 138
138(defun map-delete (map key) 139(cl-defgeneric map-delete (map key)
139 "Delete KEY from MAP and return MAP. 140 "Delete KEY from MAP and return MAP.
140No error is signaled if KEY is not a key of MAP. If MAP is an 141No error is signaled if KEY is not a key of MAP. If MAP is an
141array, store nil at the index KEY. 142array, store nil at the index KEY.
@@ -160,120 +161,121 @@ Map can be a nested map composed of alists, hash-tables and arrays."
160 map) 161 map)
161 default)) 162 default))
162 163
163(defun map-keys (map) 164(cl-defgeneric map-keys (map)
164 "Return the list of keys in MAP. 165 "Return the list of keys in MAP."
165
166MAP can be a list, hash-table or array."
167 (map-apply (lambda (key _) key) map)) 166 (map-apply (lambda (key _) key) map))
168 167
169(defun map-values (map) 168(cl-defgeneric map-values (map)
170 "Return the list of values in MAP. 169 "Return the list of values in MAP."
171
172MAP can be a list, hash-table or array."
173 (map-apply (lambda (_ value) value) map)) 170 (map-apply (lambda (_ value) value) map))
174 171
175(defun map-pairs (map) 172(cl-defgeneric map-pairs (map)
176 "Return the elements of MAP as key/value association lists. 173 "Return the elements of MAP as key/value association lists."
177
178MAP can be a list, hash-table or array."
179 (map-apply #'cons map)) 174 (map-apply #'cons map))
180 175
181(defun map-length (map) 176(cl-defgeneric map-length (map)
182 "Return the length of MAP. 177 ;; FIXME: Should we rename this to `map-size'?
183 178 "Return the number of elements in the map."
184MAP can be a list, hash-table or array." 179 (cond
185 (length (map-keys map))) 180 ((hash-table-p map) (hash-table-count map))
181 ((or (listp map) (arrayp map)) (length map))
182 (t (length (map-keys map)))))
186 183
187(defun map-copy (map) 184(cl-defgeneric map-copy (map)
188 "Return a copy of MAP. 185 "Return a copy of MAP."
189
190MAP can be a list, hash-table or array."
191 (map--dispatch map 186 (map--dispatch map
192 :list (seq-copy map) 187 :list (seq-copy map)
193 :hash-table (copy-hash-table map) 188 :hash-table (copy-hash-table map)
194 :array (seq-copy map))) 189 :array (seq-copy map)))
195 190
196(defun map-apply (function map) 191(cl-defgeneric map-apply (function map)
197 "Apply FUNCTION to each element of MAP and return the result as a list. 192 "Apply FUNCTION to each element of MAP and return the result as a list.
198FUNCTION is called with two arguments, the key and the value. 193FUNCTION is called with two arguments, the key and the value.
194The default implementation delegates to `map-do'."
195 (let ((res '()))
196 (map-do (lambda (k v) (push (funcall function k v) res)) map)
197 (nreverse res)))
199 198
200MAP can be a list, hash-table or array." 199(cl-defgeneric map-do (function map)
201 (funcall (map--dispatch map
202 :list #'map--apply-alist
203 :hash-table #'map--apply-hash-table
204 :array #'map--apply-array)
205 function
206 map))
207
208(defun map-do (function map)
209 "Apply FUNCTION to each element of MAP and return nil. 200 "Apply FUNCTION to each element of MAP and return nil.
210FUNCTION is called with two arguments, the key and the value." 201FUNCTION is called with two arguments, the key and the value.")
211 (funcall (map--dispatch map
212 :list #'map--do-alist
213 :hash-table #'maphash
214 :array #'map--do-array)
215 function
216 map))
217 202
218(defun map-keys-apply (function map) 203;; FIXME: I wish there was a way to avoid this η-redex!
219 "Return the result of applying FUNCTION to each key of MAP. 204(cl-defmethod map-do (function (map hash-table)) (maphash function map))
220 205
221MAP can be a list, hash-table or array." 206(cl-defgeneric map-keys-apply (function map)
207 "Return the result of applying FUNCTION to each key of MAP.
208The default implementation delegates to `map-apply'."
222 (map-apply (lambda (key _) 209 (map-apply (lambda (key _)
223 (funcall function key)) 210 (funcall function key))
224 map)) 211 map))
225 212
226(defun map-values-apply (function map) 213(cl-defgeneric map-values-apply (function map)
227 "Return the result of applying FUNCTION to each value of MAP. 214 "Return the result of applying FUNCTION to each value of MAP.
228 215The default implementation delegates to `map-apply'."
229MAP can be a list, hash-table or array."
230 (map-apply (lambda (_ val) 216 (map-apply (lambda (_ val)
231 (funcall function val)) 217 (funcall function val))
232 map)) 218 map))
233 219
234(defun map-filter (pred map) 220(cl-defgeneric map-filter (pred map)
235 "Return an alist of key/val pairs for which (PRED key val) is non-nil in MAP. 221 "Return an alist of key/val pairs for which (PRED key val) is non-nil in MAP.
236 222The default implementation delegates to `map-apply'."
237MAP can be a list, hash-table or array."
238 (delq nil (map-apply (lambda (key val) 223 (delq nil (map-apply (lambda (key val)
239 (if (funcall pred key val) 224 (if (funcall pred key val)
240 (cons key val) 225 (cons key val)
241 nil)) 226 nil))
242 map))) 227 map)))
243 228
244(defun map-remove (pred map) 229(cl-defgeneric map-remove (pred map)
245 "Return an alist of the key/val pairs for which (PRED key val) is nil in MAP. 230 "Return an alist of the key/val pairs for which (PRED key val) is nil in MAP.
246 231The default implementation delegates to `map-filter'."
247MAP can be a list, hash-table or array."
248 (map-filter (lambda (key val) (not (funcall pred key val))) 232 (map-filter (lambda (key val) (not (funcall pred key val)))
249 map)) 233 map))
250 234
251(defun mapp (map) 235(cl-defgeneric mapp (map)
252 "Return non-nil if MAP is a map (list, hash-table or array)." 236 "Return non-nil if MAP is a map (alist, hash-table, array, ...)."
253 (or (listp map) 237 (or (listp map)
254 (hash-table-p map) 238 (hash-table-p map)
255 (arrayp map))) 239 (arrayp map)))
256 240
257(defun map-empty-p (map) 241(cl-defgeneric map-empty-p (map)
258 "Return non-nil if MAP is empty. 242 "Return non-nil if MAP is empty.
243The default implementation delegates to `map-length'."
244 (zerop (map-length map)))
245
246(cl-defgeneric map-contains-key (map key &optional testfn)
247 ;; FIXME: The test function to use generally depends on the map object,
248 ;; so specifying `testfn' here is problematic: e.g. for hash-tables
249 ;; we shouldn't use `gethash' unless `testfn' is the same as the map's own
250 ;; test function!
251 "Return non-nil If and only if MAP contains KEY.
252TESTFN is deprecated. Its default depends on MAP.
253The default implementation delegates to `map-do'."
254 (unless testfn (setq testfn #'equal))
255 (catch 'map--catch
256 (map-do (lambda (k _v)
257 (if (funcall testfn key k) (throw 'map--catch t)))
258 map)
259 nil))
259 260
260MAP can be a list, hash-table or array." 261(cl-defmethod map-contains-key ((map list) key &optional testfn)
261 (map--dispatch map 262 (alist-get key map nil nil (or testfn #'equal)))
262 :list (null map)
263 :array (seq-empty-p map)
264 :hash-table (zerop (hash-table-count map))))
265
266(defun map-contains-key (map key &optional testfn)
267 "If MAP contain KEY return KEY, nil otherwise.
268Equality is defined by TESTFN if non-nil or by `equal' if nil.
269 263
270MAP can be a list, hash-table or array." 264(cl-defmethod map-contains-key ((map array) key &optional _testfn)
271 (seq-contains (map-keys map) key testfn)) 265 (and (integerp key)
266 (>= key 0)
267 (< key (length map))))
272 268
273(defun map-some (pred map) 269(cl-defmethod map-contains-key ((map hash-table) key &optional _testfn)
274 "Return a non-nil if (PRED key val) is non-nil for any key/value pair in MAP. 270 (let ((v '(nil)))
271 (not (eq v (gethash key map v)))))
275 272
276MAP can be a list, hash-table or array." 273(cl-defgeneric map-some (pred map)
274 "Return the first non-nil (PRED key val) in MAP.
275The default implementation delegates to `map-apply'."
276 ;; FIXME: Not sure if there's much benefit to defining it as defgeneric,
277 ;; since as defined, I can't think of a map-type where we could provide an
278 ;; algorithmically more efficient algorithm than the default.
277 (catch 'map--break 279 (catch 'map--break
278 (map-apply (lambda (key value) 280 (map-apply (lambda (key value)
279 (let ((result (funcall pred key value))) 281 (let ((result (funcall pred key value)))
@@ -282,10 +284,12 @@ MAP can be a list, hash-table or array."
282 map) 284 map)
283 nil)) 285 nil))
284 286
285(defun map-every-p (pred map) 287(cl-defgeneric map-every-p (pred map)
286 "Return non-nil if (PRED key val) is non-nil for all elements of the map MAP. 288 "Return non-nil if (PRED key val) is non-nil for all elements of the map MAP.
287 289The default implementation delegates to `map-apply'."
288MAP can be a list, hash-table or array." 290 ;; FIXME: Not sure if there's much benefit to defining it as defgeneric,
291 ;; since as defined, I can't think of a map-type where we could provide an
292 ;; algorithmically more efficient algorithm than the default.
289 (catch 'map--break 293 (catch 'map--break
290 (map-apply (lambda (key value) 294 (map-apply (lambda (key value)
291 (or (funcall pred key value) 295 (or (funcall pred key value)
@@ -294,9 +298,7 @@ MAP can be a list, hash-table or array."
294 t)) 298 t))
295 299
296(defun map-merge (type &rest maps) 300(defun map-merge (type &rest maps)
297 "Merge into a map of type TYPE all the key/value pairs in MAPS. 301 "Merge into a map of type TYPE all the key/value pairs in MAPS."
298
299MAP can be a list, hash-table or array."
300 (let ((result (map-into (pop maps) type))) 302 (let ((result (map-into (pop maps) type)))
301 (while maps 303 (while maps
302 ;; FIXME: When `type' is `list', we get an O(N^2) behavior. 304 ;; FIXME: When `type' is `list', we get an O(N^2) behavior.
@@ -310,7 +312,7 @@ MAP can be a list, hash-table or array."
310 312
311(defun map-merge-with (type function &rest maps) 313(defun map-merge-with (type function &rest maps)
312 "Merge into a map of type TYPE all the key/value pairs in MAPS. 314 "Merge into a map of type TYPE all the key/value pairs in MAPS.
313When two maps contain the same key, call FUNCTION on the two 315When two maps contain the same key (`eql'), call FUNCTION on the two
314values and use the value returned by it. 316values and use the value returned by it.
315MAP can be a list, hash-table or array." 317MAP can be a list, hash-table or array."
316 (let ((result (map-into (pop maps) type)) 318 (let ((result (map-into (pop maps) type))
@@ -318,24 +320,22 @@ MAP can be a list, hash-table or array."
318 (while maps 320 (while maps
319 (map-apply (lambda (key value) 321 (map-apply (lambda (key value)
320 (cl-callf (lambda (old) 322 (cl-callf (lambda (old)
321 (if (eq old not-found) 323 (if (eql old not-found)
322 value 324 value
323 (funcall function old value))) 325 (funcall function old value)))
324 (map-elt result key not-found))) 326 (map-elt result key not-found)))
325 (pop maps))) 327 (pop maps)))
326 result)) 328 result))
327 329
328(defun map-into (map type) 330(cl-defgeneric map-into (map type)
329 "Convert the map MAP into a map of type TYPE. 331 "Convert the map MAP into a map of type TYPE.")
332;; FIXME: I wish there was a way to avoid this η-redex!
333(cl-defmethod map-into (map (_type (eql list))) (map-pairs map))
330 334
331TYPE can be one of the following symbols: list or hash-table. 335(cl-defgeneric map-put! (map key v)
332MAP can be a list, hash-table or array." 336 "Associate KEY with VALUE in MAP and return VALUE.
333 (pcase type 337If KEY is already present in MAP, replace the associated value
334 ('list (map-pairs map)) 338with VALUE."
335 ('hash-table (map--into-hash-table map))
336 (_ (error "Not a map type name: %S" type))))
337
338(defun map--put (map key v)
339 (map--dispatch map 339 (map--dispatch map
340 :list (let ((p (assoc key map))) 340 :list (let ((p (assoc key map)))
341 (if p (setcdr p v) 341 (if p (setcdr p v)
@@ -343,24 +343,26 @@ MAP can be a list, hash-table or array."
343 :hash-table (puthash key v map) 343 :hash-table (puthash key v map)
344 :array (aset map key v))) 344 :array (aset map key v)))
345 345
346(defun map--apply-alist (function map) 346;; There shouldn't be old source code referring to `map--put', yet we do
347 "Private function used to apply FUNCTION over MAP, MAP being an alist." 347;; need to keep it for backward compatibility with .elc files where the
348;; expansion of `setf' may call this function.
349(define-obsolete-function-alias 'map--put #'map-put! "27.1")
350
351(cl-defmethod map-apply (function (map list))
348 (seq-map (lambda (pair) 352 (seq-map (lambda (pair)
349 (funcall function 353 (funcall function
350 (car pair) 354 (car pair)
351 (cdr pair))) 355 (cdr pair)))
352 map)) 356 map))
353 357
354(defun map--apply-hash-table (function map) 358(cl-defmethod map-apply (function (map hash-table))
355 "Private function used to apply FUNCTION over MAP, MAP being a hash-table."
356 (let (result) 359 (let (result)
357 (maphash (lambda (key value) 360 (maphash (lambda (key value)
358 (push (funcall function key value) result)) 361 (push (funcall function key value) result))
359 map) 362 map)
360 (nreverse result))) 363 (nreverse result)))
361 364
362(defun map--apply-array (function map) 365(cl-defmethod map-apply (function (map array))
363 "Private function used to apply FUNCTION over MAP, MAP being an array."
364 (let ((index 0)) 366 (let ((index 0))
365 (seq-map (lambda (elt) 367 (seq-map (lambda (elt)
366 (prog1 368 (prog1
@@ -368,7 +370,7 @@ MAP can be a list, hash-table or array."
368 (setq index (1+ index)))) 370 (setq index (1+ index))))
369 map))) 371 map)))
370 372
371(defun map--do-alist (function alist) 373(cl-defmethod map-do (function (alist list))
372 "Private function used to iterate over ALIST using FUNCTION." 374 "Private function used to iterate over ALIST using FUNCTION."
373 (seq-do (lambda (pair) 375 (seq-do (lambda (pair)
374 (funcall function 376 (funcall function
@@ -376,14 +378,16 @@ MAP can be a list, hash-table or array."
376 (cdr pair))) 378 (cdr pair)))
377 alist)) 379 alist))
378 380
379(defun map--do-array (function array) 381(cl-defmethod map-do (function (array array))
380 "Private function used to iterate over ARRAY using FUNCTION." 382 "Private function used to iterate over ARRAY using FUNCTION."
381 (seq-do-indexed (lambda (elt index) 383 (seq-do-indexed (lambda (elt index)
382 (funcall function index elt)) 384 (funcall function index elt))
383 array)) 385 array))
384 386
385(defun map--into-hash-table (map) 387(cl-defmethod map-into (map (_type (eql hash-table)))
386 "Convert MAP into a hash-table." 388 "Convert MAP into a hash-table."
389 ;; FIXME: Just knowing we want a hash-table is insufficient, since that
390 ;; doesn't tell us the test function to use with it!
387 (let ((ht (make-hash-table :size (map-length map) 391 (let ((ht (make-hash-table :size (map-length map)
388 :test 'equal))) 392 :test 'equal)))
389 (map-apply (lambda (key value) 393 (map-apply (lambda (key value)
diff --git a/lisp/isearch.el b/lisp/isearch.el
index dcd119a517c..dd0973d4ea6 100644
--- a/lisp/isearch.el
+++ b/lisp/isearch.el
@@ -2811,10 +2811,10 @@ the bottom."
2811If `shift', extend the search string by motion commands while holding down 2811If `shift', extend the search string by motion commands while holding down
2812the shift key. The search string is extended by yanking text that 2812the shift key. The search string is extended by yanking text that
2813ends at the new position after moving point in the current buffer. 2813ends at the new position after moving point in the current buffer.
2814If t, extend the search string without the shift key pressed 2814If t, extend the search string without the shift key pressed.
2815by motion commands that have the `isearch-move' property on their 2815To enable motion commands, put the `isearch-move' property on their
2816symbols equal to `enabled', or for which the shift-translated command 2816symbols to `enabled', or to disable an automatically detected
2817is not disabled by the value `disabled' of property `isearch-move'." 2817shift-translated command, use the property value `disabled'."
2818 :type '(choice (const :tag "Motion keys exit Isearch" nil) 2818 :type '(choice (const :tag "Motion keys exit Isearch" nil)
2819 (const :tag "Motion keys extend the search string" t) 2819 (const :tag "Motion keys extend the search string" t)
2820 (const :tag "Shifted motion keys extend the search string" shift)) 2820 (const :tag "Shifted motion keys extend the search string" shift))
@@ -2864,14 +2864,15 @@ See more for options in `search-exit-option'."
2864 (read-event) 2864 (read-event)
2865 (setq this-command 'isearch-edit-string)) 2865 (setq this-command 'isearch-edit-string))
2866 ;; Don't terminate the search for motion commands. 2866 ;; Don't terminate the search for motion commands.
2867 ((or (and (eq isearch-yank-on-move t) 2867 ((and isearch-yank-on-move
2868 (symbolp this-command) 2868 (symbolp this-command)
2869 (or (eq (get this-command 'isearch-move) 'enabled) 2869 (not (eq (get this-command 'isearch-move) 'disabled))
2870 (and (not (eq (get this-command 'isearch-move) 'disabled)) 2870 (or (eq (get this-command 'isearch-move) 'enabled)
2871 (stringp (nth 1 (interactive-form this-command))) 2871 (and (eq isearch-yank-on-move t)
2872 (string-match-p "^^" (nth 1 (interactive-form this-command)))))) 2872 (stringp (nth 1 (interactive-form this-command)))
2873 (and (eq isearch-yank-on-move 'shift) 2873 (string-match-p "^^" (nth 1 (interactive-form this-command))))
2874 this-command-keys-shift-translated)) 2874 (and (eq isearch-yank-on-move 'shift)
2875 this-command-keys-shift-translated)))
2875 (setq this-command-keys-shift-translated nil) 2876 (setq this-command-keys-shift-translated nil)
2876 (setq isearch-pre-move-point (point))) 2877 (setq isearch-pre-move-point (point)))
2877 ;; Append control characters to the search string 2878 ;; Append control characters to the search string
diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el
index ad8f50cd7a5..7b100da42b8 100644
--- a/lisp/progmodes/flymake.el
+++ b/lisp/progmodes/flymake.el
@@ -4,7 +4,7 @@
4 4
5;; Author: Pavel Kobyakov <pk_at_work@yahoo.com> 5;; Author: Pavel Kobyakov <pk_at_work@yahoo.com>
6;; Maintainer: João Távora <joaotavora@gmail.com> 6;; Maintainer: João Távora <joaotavora@gmail.com>
7;; Version: 1.0.2 7;; Version: 1.0.3
8;; Package-Requires: ((emacs "26.1")) 8;; Package-Requires: ((emacs "26.1"))
9;; Keywords: c languages tools 9;; Keywords: c languages tools
10 10
@@ -293,7 +293,7 @@ generated it."
293 293
294(cl-defstruct (flymake--diag 294(cl-defstruct (flymake--diag
295 (:constructor flymake--diag-make)) 295 (:constructor flymake--diag-make))
296 buffer beg end type text backend data overlay) 296 buffer beg end type text backend data overlay-properties overlay)
297 297
298;;;###autoload 298;;;###autoload
299(defun flymake-make-diagnostic (buffer 299(defun flymake-make-diagnostic (buffer
@@ -301,13 +301,20 @@ generated it."
301 end 301 end
302 type 302 type
303 text 303 text
304 &optional data) 304 &optional data
305 overlay-properties)
305 "Make a Flymake diagnostic for BUFFER's region from BEG to END. 306 "Make a Flymake diagnostic for BUFFER's region from BEG to END.
306TYPE is a key to symbol and TEXT is a description of the problem 307TYPE is a key to symbol and TEXT is a description of the problem
307detected in this region. DATA is any object that the caller 308detected in this region. DATA is any object that the caller
308wishes to attach to the created diagnostic for later retrieval." 309wishes to attach to the created diagnostic for later retrieval.
310
311OVERLAY-PROPERTIES is an an alist of properties attached to the
312created diagnostic, overriding the default properties and any
313properties of `flymake-overlay-control' of the diagnostic's
314type."
309 (flymake--diag-make :buffer buffer :beg beg :end end 315 (flymake--diag-make :buffer buffer :beg beg :end end
310 :type type :text text :data data)) 316 :type type :text text :data data
317 :overlay-properties overlay-properties))
311 318
312;;;###autoload 319;;;###autoload
313(defun flymake-diagnostics (&optional beg end) 320(defun flymake-diagnostics (&optional beg end)
@@ -600,7 +607,9 @@ associated `flymake-category' return DEFAULT."
600 ;; properties. 607 ;; properties.
601 (cl-loop 608 (cl-loop
602 for (ov-prop . value) in 609 for (ov-prop . value) in
603 (append (reverse ; ensure ealier props override later ones 610 (append (reverse
611 (flymake--diag-overlay-properties diagnostic))
612 (reverse ; ensure ealier props override later ones
604 (flymake--lookup-type-property type 'flymake-overlay-control)) 613 (flymake--lookup-type-property type 'flymake-overlay-control))
605 (alist-get type flymake-diagnostic-types-alist)) 614 (alist-get type flymake-diagnostic-types-alist))
606 do (overlay-put ov ov-prop value)) 615 do (overlay-put ov ov-prop value))
diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el
index 2f68f004e7b..d60899cf182 100644
--- a/lisp/progmodes/ruby-mode.el
+++ b/lisp/progmodes/ruby-mode.el
@@ -517,6 +517,9 @@ It is used when `ruby-encoding-magic-comment-style' is set to `custom'."
517 ((ruby-smie--opening-pipe-p) "opening-|") 517 ((ruby-smie--opening-pipe-p) "opening-|")
518 ((ruby-smie--closing-pipe-p) "closing-|") 518 ((ruby-smie--closing-pipe-p) "closing-|")
519 (t tok))) 519 (t tok)))
520 ((string-match "\\`[^|]+|\\'" tok)
521 (forward-char -1)
522 (substring tok 0 -1))
520 ((and (equal tok "") (looking-at "\\\\\n")) 523 ((and (equal tok "") (looking-at "\\\\\n"))
521 (goto-char (match-end 0)) (ruby-smie--forward-token)) 524 (goto-char (match-end 0)) (ruby-smie--forward-token))
522 ((equal tok "do") 525 ((equal tok "do")
@@ -559,6 +562,7 @@ It is used when `ruby-encoding-magic-comment-style' is set to `custom'."
559 ((ruby-smie--opening-pipe-p) "opening-|") 562 ((ruby-smie--opening-pipe-p) "opening-|")
560 ((ruby-smie--closing-pipe-p) "closing-|") 563 ((ruby-smie--closing-pipe-p) "closing-|")
561 (t tok))) 564 (t tok)))
565 ((string-match-p "\\`[^|]+|\\'" tok) "closing-|")
562 ((string-match-p "\\`|[*&]\\'" tok) 566 ((string-match-p "\\`|[*&]\\'" tok)
563 (forward-char 1) 567 (forward-char 1)
564 (substring tok 1)) 568 (substring tok 1))
diff --git a/lisp/vc/vc-git.el b/lisp/vc/vc-git.el
index f3174005307..aa6809f626e 100644
--- a/lisp/vc/vc-git.el
+++ b/lisp/vc/vc-git.el
@@ -757,6 +757,11 @@ the commit message."
757 (interactive) 757 (interactive)
758 (log-edit-toggle-header "Sign-Off" "yes")) 758 (log-edit-toggle-header "Sign-Off" "yes"))
759 759
760(defun vc-git-log-edit-toggle-no-verify ()
761 "Toggle whether to bypass the pre-commit and commit-msg hooks."
762 (interactive)
763 (log-edit-toggle-header "No-Verify" "yes"))
764
760(defun vc-git-log-edit-toggle-amend () 765(defun vc-git-log-edit-toggle-amend ()
761 "Toggle whether this will amend the previous commit. 766 "Toggle whether this will amend the previous commit.
762If toggling on, also insert its message into the buffer." 767If toggling on, also insert its message into the buffer."
@@ -782,6 +787,7 @@ If toggling on, also insert its message into the buffer."
782(defvar vc-git-log-edit-mode-map 787(defvar vc-git-log-edit-mode-map
783 (let ((map (make-sparse-keymap "Git-Log-Edit"))) 788 (let ((map (make-sparse-keymap "Git-Log-Edit")))
784 (define-key map "\C-c\C-s" 'vc-git-log-edit-toggle-signoff) 789 (define-key map "\C-c\C-s" 'vc-git-log-edit-toggle-signoff)
790 (define-key map "\C-c\C-n" 'vc-git-log-edit-toggle-no-verify)
785 (define-key map "\C-c\C-e" 'vc-git-log-edit-toggle-amend) 791 (define-key map "\C-c\C-e" 'vc-git-log-edit-toggle-amend)
786 map)) 792 map))
787 793
@@ -825,6 +831,7 @@ It is based on `log-edit-mode', and has Git-specific extensions.")
825 `(("Author" . "--author") 831 `(("Author" . "--author")
826 ("Date" . "--date") 832 ("Date" . "--date")
827 ("Amend" . ,(boolean-arg-fn "--amend")) 833 ("Amend" . ,(boolean-arg-fn "--amend"))
834 ("No-Verify" . ,(boolean-arg-fn "--no-verify"))
828 ("Sign-Off" . ,(boolean-arg-fn "--signoff"))) 835 ("Sign-Off" . ,(boolean-arg-fn "--signoff")))
829 comment))) 836 comment)))
830 (when msg-file 837 (when msg-file
diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el
index dbbc3e20380..48b7c98dfac 100644
--- a/lisp/vc/vc.el
+++ b/lisp/vc/vc.el
@@ -1817,7 +1817,7 @@ Return t if the buffer had changes, nil otherwise."
1817 1817
1818;;;###autoload 1818;;;###autoload
1819(defun vc-version-diff (_files rev1 rev2) 1819(defun vc-version-diff (_files rev1 rev2)
1820 "Report diffs between revisions of the fileset in the repository history." 1820 "Report diffs between REV1 and REV2 revisions of the fileset."
1821 (interactive (vc-diff-build-argument-list-internal)) 1821 (interactive (vc-diff-build-argument-list-internal))
1822 ;; All that was just so we could do argument completion! 1822 ;; All that was just so we could do argument completion!
1823 (when (and (not rev1) rev2) 1823 (when (and (not rev1) rev2)
@@ -1828,6 +1828,28 @@ Return t if the buffer had changes, nil otherwise."
1828 (called-interactively-p 'interactive))) 1828 (called-interactively-p 'interactive)))
1829 1829
1830;;;###autoload 1830;;;###autoload
1831(defun vc-root-version-diff (_files rev1 rev2)
1832 "Report diffs between REV1 and REV2 revisions of the whole tree."
1833 (interactive (vc-diff-build-argument-list-internal))
1834 ;; This is a mix of `vc-root-diff' and `vc-version-diff'
1835 (when (and (not rev1) rev2)
1836 (error "Not a valid revision range"))
1837 (let ((backend (vc-deduce-backend))
1838 (default-directory default-directory)
1839 rootdir)
1840 (if backend
1841 (setq rootdir (vc-call-backend backend 'root default-directory))
1842 (setq rootdir (read-directory-name "Directory for VC root-diff: "))
1843 (setq backend (vc-responsible-backend rootdir))
1844 (if backend
1845 (setq default-directory rootdir)
1846 (error "Directory is not version controlled")))
1847 (let ((default-directory rootdir))
1848 (vc-diff-internal
1849 t (list backend (list rootdir)) rev1 rev2
1850 (called-interactively-p 'interactive)))))
1851
1852;;;###autoload
1831(defun vc-diff (&optional historic not-urgent) 1853(defun vc-diff (&optional historic not-urgent)
1832 "Display diffs between file revisions. 1854 "Display diffs between file revisions.
1833Normally this compares the currently selected fileset with their 1855Normally this compares the currently selected fileset with their
@@ -1900,10 +1922,8 @@ The optional argument NOT-URGENT non-nil means it is ok to say no to
1900saving the buffer." 1922saving the buffer."
1901 (interactive (list current-prefix-arg t)) 1923 (interactive (list current-prefix-arg t))
1902 (if historic 1924 (if historic
1903 ;; FIXME: this does not work right, `vc-version-diff' ends up 1925 ;; We want the diff for the VC root dir.
1904 ;; calling `vc-deduce-fileset' to find the files to diff, and 1926 (call-interactively 'vc-root-version-diff)
1905 ;; that's not what we want here, we want the diff for the VC root dir.
1906 (call-interactively 'vc-version-diff)
1907 (when buffer-file-name (vc-buffer-sync not-urgent)) 1927 (when buffer-file-name (vc-buffer-sync not-urgent))
1908 (let ((backend (vc-deduce-backend)) 1928 (let ((backend (vc-deduce-backend))
1909 (default-directory default-directory) 1929 (default-directory default-directory)
@@ -2013,20 +2033,25 @@ Unlike `vc-find-revision-save', doesn't save the buffer to the file."
2013 (with-current-buffer filebuf 2033 (with-current-buffer filebuf
2014 (let ((failed t)) 2034 (let ((failed t))
2015 (unwind-protect 2035 (unwind-protect
2016 (let ((coding-system-for-read 'no-conversion) 2036 (with-current-buffer (or buffer (create-file-buffer filename))
2017 (coding-system-for-write 'no-conversion)) 2037 (unless buffer (setq buffer-file-name filename))
2018 (with-current-buffer (or buffer (create-file-buffer filename)) 2038 (let ((outbuf (current-buffer)))
2019 (unless buffer (setq buffer-file-name filename)) 2039 (with-current-buffer filebuf
2020 (let ((outbuf (current-buffer))) 2040 (if backend
2021 (with-current-buffer filebuf 2041 (vc-call-backend backend 'find-revision file revision outbuf)
2022 (if backend 2042 (vc-call find-revision file revision outbuf))))
2023 (vc-call-backend backend 'find-revision file revision outbuf) 2043 (decode-coding-inserted-region (point-min) (point-max) file)
2024 (vc-call find-revision file revision outbuf)))) 2044 (after-insert-file-set-coding (- (point-max) (point-min)))
2025 (goto-char (point-min)) 2045 (goto-char (point-min))
2026 (if buffer (let ((buffer-file-name file)) (normal-mode)) (normal-mode)) 2046 (if buffer
2027 (set-buffer-modified-p nil) 2047 ;; For non-interactive, skip any questions
2028 (setq buffer-read-only t)) 2048 (let ((enable-local-variables :safe) ;; to find `mode:'
2029 (setq failed nil)) 2049 (buffer-file-name file))
2050 (ignore-errors (set-auto-mode)))
2051 (normal-mode))
2052 (set-buffer-modified-p nil)
2053 (setq buffer-read-only t))
2054 (setq failed nil)
2030 (when (and failed (unless buffer (get-file-buffer filename))) 2055 (when (and failed (unless buffer (get-file-buffer filename)))
2031 (with-current-buffer (get-file-buffer filename) 2056 (with-current-buffer (get-file-buffer filename)
2032 (set-buffer-modified-p nil)) 2057 (set-buffer-modified-p nil))