diff options
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/dired.el | 2 | ||||
| -rw-r--r-- | lisp/emacs-lisp/map.el | 208 | ||||
| -rw-r--r-- | lisp/isearch.el | 25 | ||||
| -rw-r--r-- | lisp/progmodes/flymake.el | 21 | ||||
| -rw-r--r-- | lisp/progmodes/ruby-mode.el | 4 | ||||
| -rw-r--r-- | lisp/vc/vc-git.el | 7 | ||||
| -rw-r--r-- | lisp/vc/vc.el | 63 |
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. |
| 99 | If KEY is not found, return DEFAULT which defaults to nil. | 100 | If KEY is not found, return DEFAULT which defaults to nil. |
| 100 | 101 | ||
| 101 | If MAP is a list, `eql' is used to lookup KEY. Optional argument | 102 | TESTFN is deprecated. Its default depends on the MAP argument. |
| 102 | TESTFN, if non-nil, means use its function definition instead of | 103 | If MAP is a list, the default is `eql' to lookup KEY. |
| 103 | `eql'. | ||
| 104 | 104 | ||
| 105 | MAP can be a list, hash-table or array." | 105 | In 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. | |||
| 133 | When MAP is a list, test equality with TESTFN if non-nil, otherwise use `eql'. | 133 | When MAP is a list, test equality with TESTFN if non-nil, otherwise use `eql'. |
| 134 | 134 | ||
| 135 | MAP can be a list, hash-table or array." | 135 | MAP 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. |
| 140 | No error is signaled if KEY is not a key of MAP. If MAP is an | 141 | No error is signaled if KEY is not a key of MAP. If MAP is an |
| 141 | array, store nil at the index KEY. | 142 | array, 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 | |||
| 166 | MAP 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 | |||
| 172 | MAP 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 | |||
| 178 | MAP 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." | |
| 184 | MAP 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 | |||
| 190 | MAP 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. |
| 198 | FUNCTION is called with two arguments, the key and the value. | 193 | FUNCTION is called with two arguments, the key and the value. |
| 194 | The 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 | ||
| 200 | MAP 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. |
| 210 | FUNCTION is called with two arguments, the key and the value." | 201 | FUNCTION 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 | ||
| 221 | MAP 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. | ||
| 208 | The 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 | 215 | The default implementation delegates to `map-apply'." | |
| 229 | MAP 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 | 222 | The default implementation delegates to `map-apply'." | |
| 237 | MAP 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 | 231 | The default implementation delegates to `map-filter'." | |
| 247 | MAP 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. |
| 243 | The 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. | ||
| 252 | TESTFN is deprecated. Its default depends on MAP. | ||
| 253 | The 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 | ||
| 260 | MAP 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. | ||
| 268 | Equality is defined by TESTFN if non-nil or by `equal' if nil. | ||
| 269 | 263 | ||
| 270 | MAP 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 | ||
| 276 | MAP 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. | ||
| 275 | The 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 | 289 | The default implementation delegates to `map-apply'." | |
| 288 | MAP 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 | |||
| 299 | MAP 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. |
| 313 | When two maps contain the same key, call FUNCTION on the two | 315 | When two maps contain the same key (`eql'), call FUNCTION on the two |
| 314 | values and use the value returned by it. | 316 | values and use the value returned by it. |
| 315 | MAP can be a list, hash-table or array." | 317 | MAP 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 | ||
| 331 | TYPE can be one of the following symbols: list or hash-table. | 335 | (cl-defgeneric map-put! (map key v) |
| 332 | MAP can be a list, hash-table or array." | 336 | "Associate KEY with VALUE in MAP and return VALUE. |
| 333 | (pcase type | 337 | If KEY is already present in MAP, replace the associated value |
| 334 | ('list (map-pairs map)) | 338 | with 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." | |||
| 2811 | If `shift', extend the search string by motion commands while holding down | 2811 | If `shift', extend the search string by motion commands while holding down |
| 2812 | the shift key. The search string is extended by yanking text that | 2812 | the shift key. The search string is extended by yanking text that |
| 2813 | ends at the new position after moving point in the current buffer. | 2813 | ends at the new position after moving point in the current buffer. |
| 2814 | If t, extend the search string without the shift key pressed | 2814 | If t, extend the search string without the shift key pressed. |
| 2815 | by motion commands that have the `isearch-move' property on their | 2815 | To enable motion commands, put the `isearch-move' property on their |
| 2816 | symbols equal to `enabled', or for which the shift-translated command | 2816 | symbols to `enabled', or to disable an automatically detected |
| 2817 | is not disabled by the value `disabled' of property `isearch-move'." | 2817 | shift-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. |
| 306 | TYPE is a key to symbol and TEXT is a description of the problem | 307 | TYPE is a key to symbol and TEXT is a description of the problem |
| 307 | detected in this region. DATA is any object that the caller | 308 | detected in this region. DATA is any object that the caller |
| 308 | wishes to attach to the created diagnostic for later retrieval." | 309 | wishes to attach to the created diagnostic for later retrieval. |
| 310 | |||
| 311 | OVERLAY-PROPERTIES is an an alist of properties attached to the | ||
| 312 | created diagnostic, overriding the default properties and any | ||
| 313 | properties of `flymake-overlay-control' of the diagnostic's | ||
| 314 | type." | ||
| 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. |
| 762 | If toggling on, also insert its message into the buffer." | 767 | If 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. |
| 1833 | Normally this compares the currently selected fileset with their | 1855 | Normally 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 | |||
| 1900 | saving the buffer." | 1922 | saving 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)) |