diff options
| author | Stephen Leake | 2018-12-13 14:39:02 -0800 |
|---|---|---|
| committer | Stephen Leake | 2018-12-13 14:39:02 -0800 |
| commit | 87bef630bf0f45e8da74e43ba614aa2292b296ef (patch) | |
| tree | efdead3c0d7dd227bacbd4dfc5c1ff9b4d5c13c3 | |
| parent | 4d3f7b77cc7dea072d2ecb9f137c2e497bc52da1 (diff) | |
| parent | d08b75abe0f0cf9ade812b189c374809a2c7836e (diff) | |
| download | emacs-87bef630bf0f45e8da74e43ba614aa2292b296ef.tar.gz emacs-87bef630bf0f45e8da74e43ba614aa2292b296ef.zip | |
Merge commit 'd08b75abe0f0cf9ade812b189c374809a2c7836e'
| -rw-r--r-- | doc/emacs/maintaining.texi | 9 | ||||
| -rw-r--r-- | doc/misc/tramp.texi | 2 | ||||
| -rw-r--r-- | etc/NEWS | 10 | ||||
| -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 | ||||
| -rw-r--r-- | src/fileio.c | 28 | ||||
| -rw-r--r-- | src/textprop.c | 87 | ||||
| -rw-r--r-- | src/xdisp.c | 2 | ||||
| -rw-r--r-- | test/Makefile.in | 8 | ||||
| -rw-r--r-- | test/lisp/eshell/em-ls-tests.el | 14 | ||||
| -rw-r--r-- | test/lisp/net/secrets-tests.el | 7 | ||||
| -rw-r--r-- | test/lisp/progmodes/ruby-mode-tests.el | 90 | ||||
| -rw-r--r-- | test/src/fileio-tests.el | 4 |
18 files changed, 381 insertions, 210 deletions
diff --git a/doc/emacs/maintaining.texi b/doc/emacs/maintaining.texi index 4527c23d9e7..6a848f9d148 100644 --- a/doc/emacs/maintaining.texi +++ b/doc/emacs/maintaining.texi | |||
| @@ -831,6 +831,14 @@ working tree containing the current VC fileset). If you invoke this | |||
| 831 | command from a Dired buffer, it applies to the working tree containing | 831 | command from a Dired buffer, it applies to the working tree containing |
| 832 | the directory. | 832 | the directory. |
| 833 | 833 | ||
| 834 | @findex vc-root-version-diff | ||
| 835 | @kindex C-u C-x v D | ||
| 836 | To compare two arbitrary revisions of the whole trees, call | ||
| 837 | @code{vc-root-diff} with a prefix argument: @kbd{C-u C-x v D}. This | ||
| 838 | prompts for two revision IDs (@pxref{VCS Concepts}), and displays a | ||
| 839 | diff between those versions of the entire version-controlled directory | ||
| 840 | trees (RCS, SCCS, CVS, and SRC do not support this feature). | ||
| 841 | |||
| 834 | @vindex vc-diff-switches | 842 | @vindex vc-diff-switches |
| 835 | You can customize the @command{diff} options that @kbd{C-x v =} and | 843 | You can customize the @command{diff} options that @kbd{C-x v =} and |
| 836 | @kbd{C-x v D} use for generating diffs. The options used are taken | 844 | @kbd{C-x v D} use for generating diffs. The options used are taken |
| @@ -963,6 +971,7 @@ and the maximum number of revisions to display. | |||
| 963 | Directory Mode}) or a Dired buffer (@pxref{Dired}), it applies to the | 971 | Directory Mode}) or a Dired buffer (@pxref{Dired}), it applies to the |
| 964 | file listed on the current line. | 972 | file listed on the current line. |
| 965 | 973 | ||
| 974 | @kindex C-x v L | ||
| 966 | @findex vc-print-root-log | 975 | @findex vc-print-root-log |
| 967 | @findex log-view-toggle-entry-display | 976 | @findex log-view-toggle-entry-display |
| 968 | @kbd{C-x v L} (@code{vc-print-root-log}) displays a | 977 | @kbd{C-x v L} (@code{vc-print-root-log}) displays a |
diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index 5c5402133a7..a4946f0b8de 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi | |||
| @@ -2741,6 +2741,8 @@ proxy @samp{bird@@bastion} to a remote file on @samp{you@@remotehost}: | |||
| 2741 | 2741 | ||
| 2742 | Each involved method must be an inline method (@pxref{Inline methods}). | 2742 | Each involved method must be an inline method (@pxref{Inline methods}). |
| 2743 | 2743 | ||
| 2744 | Proxies can take patterns @code{%h} or @code{%u}. | ||
| 2745 | |||
| 2744 | @value{tramp} adds the ad-hoc definitions on the fly to | 2746 | @value{tramp} adds the ad-hoc definitions on the fly to |
| 2745 | @code{tramp-default-proxies-alist} and is available for re-use | 2747 | @code{tramp-default-proxies-alist} and is available for re-use |
| 2746 | during that Emacs session. Subsequent @value{tramp} connections to | 2748 | during that Emacs session. Subsequent @value{tramp} connections to |
| @@ -304,6 +304,12 @@ the node "(emacs) Directory Variables" of the user manual. | |||
| 304 | 304 | ||
| 305 | * Changes in Specialized Modes and Packages in Emacs 27.1 | 305 | * Changes in Specialized Modes and Packages in Emacs 27.1 |
| 306 | 306 | ||
| 307 | ** map.el | ||
| 308 | *** Now defined via generic functions that can be extended via cl-defmethod. | ||
| 309 | *** Deprecate the 'map-put' macro in favor of a new 'map-put!' function. | ||
| 310 | *** map-contains-key now returns a boolean rather than the key. | ||
| 311 | *** Deprecate the 'testfn' args of 'map-elt' and 'map-contains-key'. | ||
| 312 | |||
| 307 | --- | 313 | --- |
| 308 | ** Follow mode | 314 | ** Follow mode |
| 309 | In the current follow group of windows, "ghost" cursors are no longer | 315 | In the current follow group of windows, "ghost" cursors are no longer |
| @@ -398,6 +404,10 @@ with conflicts existed in earlier versions of Emacs, but incorrectly | |||
| 398 | never detected a conflict due to invalid assumptions about cached | 404 | never detected a conflict due to invalid assumptions about cached |
| 399 | values. | 405 | values. |
| 400 | 406 | ||
| 407 | +++ | ||
| 408 | *** 'C-u C-x v D' ('vc-root-version-diff') prompts for two revisions | ||
| 409 | and compares their entire trees. | ||
| 410 | |||
| 401 | ** Diff mode | 411 | ** Diff mode |
| 402 | *** Hunks are now automatically refined by default. | 412 | *** Hunks are now automatically refined by default. |
| 403 | To disable it, set the new defcustom 'diff-font-lock-refine' to nil. | 413 | To disable it, set the new defcustom 'diff-font-lock-refine' to nil. |
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)) |
diff --git a/src/fileio.c b/src/fileio.c index d9795715f9e..687f6ec7452 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -1692,6 +1692,34 @@ get_homedir (void) | |||
| 1692 | if (!home) | 1692 | if (!home) |
| 1693 | return ""; | 1693 | return ""; |
| 1694 | } | 1694 | } |
| 1695 | #ifdef DOS_NT | ||
| 1696 | /* If home is a drive-relative directory, expand it. */ | ||
| 1697 | if (IS_DRIVE (*home) | ||
| 1698 | && IS_DEVICE_SEP (home[1]) | ||
| 1699 | && !IS_DIRECTORY_SEP (home[2])) | ||
| 1700 | { | ||
| 1701 | # ifdef WINDOWSNT | ||
| 1702 | static char hdir[MAX_UTF8_PATH]; | ||
| 1703 | # else | ||
| 1704 | static char hdir[MAXPATHLEN]; | ||
| 1705 | # endif | ||
| 1706 | if (!getdefdir (c_toupper (*home) - 'A' + 1, hdir)) | ||
| 1707 | { | ||
| 1708 | hdir[0] = c_toupper (*home); | ||
| 1709 | hdir[1] = ':'; | ||
| 1710 | hdir[2] = '/'; | ||
| 1711 | hdir[3] = '\0'; | ||
| 1712 | } | ||
| 1713 | if (home[2]) | ||
| 1714 | { | ||
| 1715 | size_t homelen = strlen (hdir); | ||
| 1716 | if (!IS_DIRECTORY_SEP (hdir[homelen - 1])) | ||
| 1717 | strcat (hdir, "/"); | ||
| 1718 | strcat (hdir, home + 2); | ||
| 1719 | } | ||
| 1720 | home = hdir; | ||
| 1721 | } | ||
| 1722 | #endif | ||
| 1695 | if (IS_ABSOLUTE_FILE_NAME (home)) | 1723 | if (IS_ABSOLUTE_FILE_NAME (home)) |
| 1696 | return home; | 1724 | return home; |
| 1697 | if (!emacs_wd) | 1725 | if (!emacs_wd) |
diff --git a/src/textprop.c b/src/textprop.c index 8e8baf43d9f..8a06f0ffad1 100644 --- a/src/textprop.c +++ b/src/textprop.c | |||
| @@ -111,9 +111,6 @@ CHECK_STRING_OR_BUFFER (Lisp_Object x) | |||
| 111 | to by BEGIN and END may be integers or markers; if the latter, they | 111 | to by BEGIN and END may be integers or markers; if the latter, they |
| 112 | are coerced to integers. | 112 | are coerced to integers. |
| 113 | 113 | ||
| 114 | When OBJECT is a string, we increment *BEGIN and *END | ||
| 115 | to make them origin-one. | ||
| 116 | |||
| 117 | Note that buffer points don't correspond to interval indices. | 114 | Note that buffer points don't correspond to interval indices. |
| 118 | For example, point-max is 1 greater than the index of the last | 115 | For example, point-max is 1 greater than the index of the last |
| 119 | character. This difference is handled in the caller, which uses | 116 | character. This difference is handled in the caller, which uses |
| @@ -175,9 +172,6 @@ validate_interval_range (Lisp_Object object, Lisp_Object *begin, | |||
| 175 | if (! (0 <= XFIXNUM (*begin) && XFIXNUM (*begin) <= XFIXNUM (*end) | 172 | if (! (0 <= XFIXNUM (*begin) && XFIXNUM (*begin) <= XFIXNUM (*end) |
| 176 | && XFIXNUM (*end) <= len)) | 173 | && XFIXNUM (*end) <= len)) |
| 177 | args_out_of_range (*begin, *end); | 174 | args_out_of_range (*begin, *end); |
| 178 | XSETFASTINT (*begin, XFIXNAT (*begin)); | ||
| 179 | if (begin != end) | ||
| 180 | XSETFASTINT (*end, XFIXNAT (*end)); | ||
| 181 | i = string_intervals (object); | 175 | i = string_intervals (object); |
| 182 | 176 | ||
| 183 | if (len == 0) | 177 | if (len == 0) |
| @@ -1348,13 +1342,9 @@ Lisp_Object | |||
| 1348 | set_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object properties, | 1342 | set_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object properties, |
| 1349 | Lisp_Object object, Lisp_Object coherent_change_p) | 1343 | Lisp_Object object, Lisp_Object coherent_change_p) |
| 1350 | { | 1344 | { |
| 1351 | register INTERVAL i; | 1345 | INTERVAL i; |
| 1352 | Lisp_Object ostart, oend; | ||
| 1353 | bool first_time = true; | 1346 | bool first_time = true; |
| 1354 | 1347 | ||
| 1355 | ostart = start; | ||
| 1356 | oend = end; | ||
| 1357 | |||
| 1358 | properties = validate_plist (properties); | 1348 | properties = validate_plist (properties); |
| 1359 | 1349 | ||
| 1360 | if (NILP (object)) | 1350 | if (NILP (object)) |
| @@ -1382,11 +1372,6 @@ set_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object properties, | |||
| 1382 | if (NILP (properties)) | 1372 | if (NILP (properties)) |
| 1383 | return Qnil; | 1373 | return Qnil; |
| 1384 | 1374 | ||
| 1385 | /* Restore the original START and END values | ||
| 1386 | because validate_interval_range increments them for strings. */ | ||
| 1387 | start = ostart; | ||
| 1388 | end = oend; | ||
| 1389 | |||
| 1390 | i = validate_interval_range (object, &start, &end, hard); | 1375 | i = validate_interval_range (object, &start, &end, hard); |
| 1391 | /* This can return if start == end. */ | 1376 | /* This can return if start == end. */ |
| 1392 | if (!i) | 1377 | if (!i) |
| @@ -1421,34 +1406,25 @@ set_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object properties, | |||
| 1421 | /* Replace properties of text from START to END with new list of | 1406 | /* Replace properties of text from START to END with new list of |
| 1422 | properties PROPERTIES. OBJECT is the buffer or string containing | 1407 | properties PROPERTIES. OBJECT is the buffer or string containing |
| 1423 | the text. This does not obey any hooks. | 1408 | the text. This does not obey any hooks. |
| 1424 | You should provide the interval that START is located in as I. | 1409 | I is the interval that START is located in. */ |
| 1425 | START and END can be in any order. */ | ||
| 1426 | 1410 | ||
| 1427 | void | 1411 | void |
| 1428 | set_text_properties_1 (Lisp_Object start, Lisp_Object end, Lisp_Object properties, Lisp_Object object, INTERVAL i) | 1412 | set_text_properties_1 (Lisp_Object start, Lisp_Object end, |
| 1413 | Lisp_Object properties, Lisp_Object object, INTERVAL i) | ||
| 1429 | { | 1414 | { |
| 1430 | register INTERVAL prev_changed = NULL; | 1415 | INTERVAL prev_changed = NULL; |
| 1431 | register ptrdiff_t s, len; | 1416 | ptrdiff_t s = XFIXNUM (start); |
| 1432 | INTERVAL unchanged; | 1417 | ptrdiff_t len = XFIXNUM (end) - s; |
| 1433 | 1418 | ||
| 1434 | if (XFIXNUM (start) < XFIXNUM (end)) | 1419 | if (len == 0) |
| 1435 | { | ||
| 1436 | s = XFIXNUM (start); | ||
| 1437 | len = XFIXNUM (end) - s; | ||
| 1438 | } | ||
| 1439 | else if (XFIXNUM (end) < XFIXNUM (start)) | ||
| 1440 | { | ||
| 1441 | s = XFIXNUM (end); | ||
| 1442 | len = XFIXNUM (start) - s; | ||
| 1443 | } | ||
| 1444 | else | ||
| 1445 | return; | 1420 | return; |
| 1421 | eassert (0 < len); | ||
| 1446 | 1422 | ||
| 1447 | eassert (i); | 1423 | eassert (i); |
| 1448 | 1424 | ||
| 1449 | if (i->position != s) | 1425 | if (i->position != s) |
| 1450 | { | 1426 | { |
| 1451 | unchanged = i; | 1427 | INTERVAL unchanged = i; |
| 1452 | i = split_interval_right (unchanged, s - unchanged->position); | 1428 | i = split_interval_right (unchanged, s - unchanged->position); |
| 1453 | 1429 | ||
| 1454 | if (LENGTH (i) > len) | 1430 | if (LENGTH (i) > len) |
| @@ -1896,45 +1872,30 @@ Lisp_Object | |||
| 1896 | copy_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object src, | 1872 | copy_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object src, |
| 1897 | Lisp_Object pos, Lisp_Object dest, Lisp_Object prop) | 1873 | Lisp_Object pos, Lisp_Object dest, Lisp_Object prop) |
| 1898 | { | 1874 | { |
| 1899 | INTERVAL i; | 1875 | INTERVAL i = validate_interval_range (src, &start, &end, soft); |
| 1900 | Lisp_Object res; | ||
| 1901 | Lisp_Object stuff; | ||
| 1902 | Lisp_Object plist; | ||
| 1903 | ptrdiff_t s, e, e2, p, len; | ||
| 1904 | bool modified = false; | ||
| 1905 | |||
| 1906 | i = validate_interval_range (src, &start, &end, soft); | ||
| 1907 | if (!i) | 1876 | if (!i) |
| 1908 | return Qnil; | 1877 | return Qnil; |
| 1909 | 1878 | ||
| 1910 | CHECK_FIXNUM_COERCE_MARKER (pos); | 1879 | CHECK_FIXNUM_COERCE_MARKER (pos); |
| 1911 | { | ||
| 1912 | Lisp_Object dest_start, dest_end; | ||
| 1913 | |||
| 1914 | e = XFIXNUM (pos) + (XFIXNUM (end) - XFIXNUM (start)); | ||
| 1915 | if (MOST_POSITIVE_FIXNUM < e) | ||
| 1916 | args_out_of_range (pos, end); | ||
| 1917 | dest_start = pos; | ||
| 1918 | XSETFASTINT (dest_end, e); | ||
| 1919 | /* Apply this to a copy of pos; it will try to increment its arguments, | ||
| 1920 | which we don't want. */ | ||
| 1921 | validate_interval_range (dest, &dest_start, &dest_end, soft); | ||
| 1922 | } | ||
| 1923 | 1880 | ||
| 1924 | s = XFIXNUM (start); | 1881 | EMACS_INT dest_e = XFIXNUM (pos) + (XFIXNUM (end) - XFIXNUM (start)); |
| 1925 | e = XFIXNUM (end); | 1882 | if (MOST_POSITIVE_FIXNUM < dest_e) |
| 1926 | p = XFIXNUM (pos); | 1883 | args_out_of_range (pos, end); |
| 1884 | Lisp_Object dest_end = make_fixnum (dest_e); | ||
| 1885 | validate_interval_range (dest, &pos, &dest_end, soft); | ||
| 1886 | |||
| 1887 | ptrdiff_t s = XFIXNUM (start), e = XFIXNUM (end), p = XFIXNUM (pos); | ||
| 1927 | 1888 | ||
| 1928 | stuff = Qnil; | 1889 | Lisp_Object stuff = Qnil; |
| 1929 | 1890 | ||
| 1930 | while (s < e) | 1891 | while (s < e) |
| 1931 | { | 1892 | { |
| 1932 | e2 = i->position + LENGTH (i); | 1893 | ptrdiff_t e2 = i->position + LENGTH (i); |
| 1933 | if (e2 > e) | 1894 | if (e2 > e) |
| 1934 | e2 = e; | 1895 | e2 = e; |
| 1935 | len = e2 - s; | 1896 | ptrdiff_t len = e2 - s; |
| 1936 | 1897 | ||
| 1937 | plist = i->plist; | 1898 | Lisp_Object plist = i->plist; |
| 1938 | if (! NILP (prop)) | 1899 | if (! NILP (prop)) |
| 1939 | while (! NILP (plist)) | 1900 | while (! NILP (plist)) |
| 1940 | { | 1901 | { |
| @@ -1959,9 +1920,11 @@ copy_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object src, | |||
| 1959 | s = i->position; | 1920 | s = i->position; |
| 1960 | } | 1921 | } |
| 1961 | 1922 | ||
| 1923 | bool modified = false; | ||
| 1924 | |||
| 1962 | while (! NILP (stuff)) | 1925 | while (! NILP (stuff)) |
| 1963 | { | 1926 | { |
| 1964 | res = Fcar (stuff); | 1927 | Lisp_Object res = Fcar (stuff); |
| 1965 | res = Fadd_text_properties (Fcar (res), Fcar (Fcdr (res)), | 1928 | res = Fadd_text_properties (Fcar (res), Fcar (Fcdr (res)), |
| 1966 | Fcar (Fcdr (Fcdr (res))), dest); | 1929 | Fcar (Fcdr (Fcdr (res))), dest); |
| 1967 | if (! NILP (res)) | 1930 | if (! NILP (res)) |
diff --git a/src/xdisp.c b/src/xdisp.c index 4d9990cf46c..cb21397e7b9 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -23041,7 +23041,7 @@ Emacs UBA implementation, in particular with the test suite. */) | |||
| 23041 | } | 23041 | } |
| 23042 | else | 23042 | else |
| 23043 | { | 23043 | { |
| 23044 | CHECK_FIXNUM_COERCE_MARKER (vpos); | 23044 | CHECK_FIXNUM (vpos); |
| 23045 | nrow = XFIXNUM (vpos); | 23045 | nrow = XFIXNUM (vpos); |
| 23046 | } | 23046 | } |
| 23047 | 23047 | ||
diff --git a/test/Makefile.in b/test/Makefile.in index adb316c3d9c..4548323f26a 100644 --- a/test/Makefile.in +++ b/test/Makefile.in | |||
| @@ -190,6 +190,12 @@ else | |||
| 190 | maybe_exclude_module_tests := -name emacs-module-tests.el -prune -o | 190 | maybe_exclude_module_tests := -name emacs-module-tests.el -prune -o |
| 191 | endif | 191 | endif |
| 192 | 192 | ||
| 193 | ## Optional list of .el files to exclude from testing. | ||
| 194 | ## Intended for use in automated testing where one or more files | ||
| 195 | ## has some problem and needs to be excluded. | ||
| 196 | ## To avoid writing full name, can use eg %foo-tests.el. | ||
| 197 | EXCLUDE_TESTS = | ||
| 198 | |||
| 193 | ## To speed up parallel builds, put these slow test files (which can | 199 | ## To speed up parallel builds, put these slow test files (which can |
| 194 | ## take longer than all the rest combined) at the start of the list. | 200 | ## take longer than all the rest combined) at the start of the list. |
| 195 | SLOW_TESTS = ${srcdir}/lisp/net/tramp-tests.el | 201 | SLOW_TESTS = ${srcdir}/lisp/net/tramp-tests.el |
| @@ -202,6 +208,8 @@ ELFILES := $(sort $(shell find ${srcdir} -path "${srcdir}/manual" -prune -o \ | |||
| 202 | 208 | ||
| 203 | $(foreach slow,${SLOW_TESTS},$(eval ELFILES:= ${slow} $(filter-out ${slow},${ELFILES}))) | 209 | $(foreach slow,${SLOW_TESTS},$(eval ELFILES:= ${slow} $(filter-out ${slow},${ELFILES}))) |
| 204 | 210 | ||
| 211 | $(foreach exclude,${EXCLUDE_TESTS},$(eval ELFILES:= $(filter-out ${exclude},${ELFILES}))) | ||
| 212 | |||
| 205 | ## .log files may be in a different directory for out of source builds | 213 | ## .log files may be in a different directory for out of source builds |
| 206 | LOGFILES := $(patsubst %.el,%.log, \ | 214 | LOGFILES := $(patsubst %.el,%.log, \ |
| 207 | $(patsubst $(srcdir)/%,%,$(ELFILES))) | 215 | $(patsubst $(srcdir)/%,%,$(ELFILES))) |
diff --git a/test/lisp/eshell/em-ls-tests.el b/test/lisp/eshell/em-ls-tests.el index c5c9eac3249..b89a54641bd 100644 --- a/test/lisp/eshell/em-ls-tests.el +++ b/test/lisp/eshell/em-ls-tests.el | |||
| @@ -78,6 +78,11 @@ | |||
| 78 | 78 | ||
| 79 | (ert-deftest em-ls-test-bug27844 () | 79 | (ert-deftest em-ls-test-bug27844 () |
| 80 | "Test for https://debbugs.gnu.org/27844 ." | 80 | "Test for https://debbugs.gnu.org/27844 ." |
| 81 | ;; FIXME: it would be better to use something other than source-directory | ||
| 82 | ;; in this test. | ||
| 83 | (skip-unless (and source-directory | ||
| 84 | (file-exists-p | ||
| 85 | (expand-file-name "lisp/subr.el" source-directory)))) | ||
| 81 | (let ((orig eshell-ls-use-in-dired) | 86 | (let ((orig eshell-ls-use-in-dired) |
| 82 | (dired-use-ls-dired 'unspecified) | 87 | (dired-use-ls-dired 'unspecified) |
| 83 | buf insert-directory-program) | 88 | buf insert-directory-program) |
| @@ -89,6 +94,15 @@ | |||
| 89 | (should (cdr (dired-get-marked-files))) | 94 | (should (cdr (dired-get-marked-files))) |
| 90 | (kill-buffer buf) | 95 | (kill-buffer buf) |
| 91 | (setq buf (dired (expand-file-name "lisp/subr.el" source-directory))) | 96 | (setq buf (dired (expand-file-name "lisp/subr.el" source-directory))) |
| 97 | (when (getenv "EMACS_HYDRA_CI") | ||
| 98 | (message "X1%s" (buffer-substring-no-properties | ||
| 99 | (point-min) (point-max))) | ||
| 100 | (message "X2%s" (buffer-substring-no-properties | ||
| 101 | (line-beginning-position) | ||
| 102 | (line-end-position))) | ||
| 103 | (message "X3%s" (buffer-substring-no-properties | ||
| 104 | (point) | ||
| 105 | (line-end-position)))) | ||
| 92 | (should (looking-at "subr\\.el"))) | 106 | (should (looking-at "subr\\.el"))) |
| 93 | (customize-set-variable 'eshell-ls-use-in-dired orig) | 107 | (customize-set-variable 'eshell-ls-use-in-dired orig) |
| 94 | (and (buffer-live-p buf) (kill-buffer))))) | 108 | (and (buffer-live-p buf) (kill-buffer))))) |
diff --git a/test/lisp/net/secrets-tests.el b/test/lisp/net/secrets-tests.el index de3ce731bec..d34b0021952 100644 --- a/test/lisp/net/secrets-tests.el +++ b/test/lisp/net/secrets-tests.el | |||
| @@ -90,10 +90,6 @@ | |||
| 90 | (unwind-protect | 90 | (unwind-protect |
| 91 | (progn | 91 | (progn |
| 92 | (should (secrets-open-session)) | 92 | (should (secrets-open-session)) |
| 93 | |||
| 94 | ;; There must be at least the collections "Login" and "session". | ||
| 95 | (should (or (member "Login" (secrets-list-collections)) | ||
| 96 | (member "login" (secrets-list-collections)))) | ||
| 97 | (should (member "session" (secrets-list-collections))) | 93 | (should (member "session" (secrets-list-collections))) |
| 98 | 94 | ||
| 99 | ;; Create a random collection. This asks for a password | 95 | ;; Create a random collection. This asks for a password |
| @@ -160,9 +156,6 @@ | |||
| 160 | 156 | ||
| 161 | ;; There shall be no items in the "session" collection. | 157 | ;; There shall be no items in the "session" collection. |
| 162 | (should-not (secrets-list-items "session")) | 158 | (should-not (secrets-list-items "session")) |
| 163 | ;; There shall be items in the "Login" collection. | ||
| 164 | (should (or (secrets-list-items "Login") | ||
| 165 | (secrets-list-items "login"))) | ||
| 166 | 159 | ||
| 167 | ;; Create a new item. | 160 | ;; Create a new item. |
| 168 | (should (setq item-path (secrets-create-item "session" "foo" "secret"))) | 161 | (should (setq item-path (secrets-create-item "session" "foo" "secret"))) |
diff --git a/test/lisp/progmodes/ruby-mode-tests.el b/test/lisp/progmodes/ruby-mode-tests.el index 72d83affaef..afd6d65c9d1 100644 --- a/test/lisp/progmodes/ruby-mode-tests.el +++ b/test/lisp/progmodes/ruby-mode-tests.el | |||
| @@ -718,6 +718,96 @@ VALUES-PLIST is a list with alternating index and value elements." | |||
| 718 | (ruby-backward-sexp) | 718 | (ruby-backward-sexp) |
| 719 | (should (= 2 (line-number-at-pos))))) | 719 | (should (= 2 (line-number-at-pos))))) |
| 720 | 720 | ||
| 721 | (ert-deftest ruby-forward-sexp-jumps-do-end-block-with-no-args () | ||
| 722 | (ruby-with-temp-buffer | ||
| 723 | (ruby-test-string | ||
| 724 | "proc do | ||
| 725 | |end") | ||
| 726 | (search-backward "do\n") | ||
| 727 | (ruby-forward-sexp) | ||
| 728 | (should (eobp)))) | ||
| 729 | |||
| 730 | (ert-deftest ruby-backward-sexp-jumps-do-end-block-with-no-args () | ||
| 731 | (ruby-with-temp-buffer | ||
| 732 | (ruby-test-string | ||
| 733 | "proc do | ||
| 734 | |end") | ||
| 735 | (goto-char (point-max)) | ||
| 736 | (ruby-backward-sexp) | ||
| 737 | (should (looking-at "do$")))) | ||
| 738 | |||
| 739 | (ert-deftest ruby-forward-sexp-jumps-do-end-block-with-empty-args () | ||
| 740 | (ruby-with-temp-buffer | ||
| 741 | (ruby-test-string | ||
| 742 | "proc do || | ||
| 743 | |end") | ||
| 744 | (search-backward "do ") | ||
| 745 | (ruby-forward-sexp) | ||
| 746 | (should (eobp)))) | ||
| 747 | |||
| 748 | (ert-deftest ruby-backward-sexp-jumps-do-end-block-with-empty-args () | ||
| 749 | (ruby-with-temp-buffer | ||
| 750 | (ruby-test-string | ||
| 751 | "proc do || | ||
| 752 | |end") | ||
| 753 | (goto-char (point-max)) | ||
| 754 | (ruby-backward-sexp) | ||
| 755 | (should (looking-at "do ")))) | ||
| 756 | |||
| 757 | (ert-deftest ruby-forward-sexp-jumps-do-end-block-with-args () | ||
| 758 | (ruby-with-temp-buffer | ||
| 759 | (ruby-test-string | ||
| 760 | "proc do |a,b| | ||
| 761 | |end") | ||
| 762 | (search-backward "do ") | ||
| 763 | (ruby-forward-sexp) | ||
| 764 | (should (eobp)))) | ||
| 765 | |||
| 766 | (ert-deftest ruby-backward-sexp-jumps-do-end-block-with-args () | ||
| 767 | (ruby-with-temp-buffer | ||
| 768 | (ruby-test-string | ||
| 769 | "proc do |a,b| | ||
| 770 | |end") | ||
| 771 | (goto-char (point-max)) | ||
| 772 | (ruby-backward-sexp) | ||
| 773 | (should (looking-at "do ")))) | ||
| 774 | |||
| 775 | (ert-deftest ruby-forward-sexp-jumps-do-end-block-with-any-args () | ||
| 776 | (ruby-with-temp-buffer | ||
| 777 | (ruby-test-string | ||
| 778 | "proc do |*| | ||
| 779 | |end") | ||
| 780 | (search-backward "do ") | ||
| 781 | (ruby-forward-sexp) | ||
| 782 | (should (eobp)))) | ||
| 783 | |||
| 784 | (ert-deftest ruby-forward-sexp-jumps-do-end-block-with-expanded-one-arg () | ||
| 785 | (ruby-with-temp-buffer | ||
| 786 | (ruby-test-string | ||
| 787 | "proc do |a,| | ||
| 788 | |end") | ||
| 789 | (search-backward "do ") | ||
| 790 | (ruby-forward-sexp) | ||
| 791 | (should (eobp)))) | ||
| 792 | |||
| 793 | (ert-deftest ruby-forward-sexp-jumps-do-end-block-with-one-and-any-args () | ||
| 794 | (ruby-with-temp-buffer | ||
| 795 | (ruby-test-string | ||
| 796 | "proc do |a,*| | ||
| 797 | |end") | ||
| 798 | (search-backward "do ") | ||
| 799 | (ruby-forward-sexp) | ||
| 800 | (should (eobp)))) | ||
| 801 | |||
| 802 | (ert-deftest ruby-backward-sexp-jumps-do-end-block-with-one-and-any-args () | ||
| 803 | (ruby-with-temp-buffer | ||
| 804 | (ruby-test-string | ||
| 805 | "proc do |a,*| | ||
| 806 | |end") | ||
| 807 | (goto-char (point-max)) | ||
| 808 | (ruby-backward-sexp) | ||
| 809 | (should (looking-at "do ")))) | ||
| 810 | |||
| 721 | (ert-deftest ruby-toggle-string-quotes-quotes-correctly () | 811 | (ert-deftest ruby-toggle-string-quotes-quotes-correctly () |
| 722 | (let ((pairs | 812 | (let ((pairs |
| 723 | '(("puts '\"foo\"\\''" . "puts \"\\\"foo\\\"'\"") | 813 | '(("puts '\"foo\"\\''" . "puts \"\\\"foo\\\"'\"") |
diff --git a/test/src/fileio-tests.el b/test/src/fileio-tests.el index b7b78bbda09..a74bcea41f2 100644 --- a/test/src/fileio-tests.el +++ b/test/src/fileio-tests.el | |||
| @@ -102,4 +102,8 @@ Also check that an encoding error can appear in a symlink." | |||
| 102 | (setenv "HOME" "a/b/c") | 102 | (setenv "HOME" "a/b/c") |
| 103 | (should (equal (expand-file-name "~/foo") | 103 | (should (equal (expand-file-name "~/foo") |
| 104 | (expand-file-name "a/b/c/foo"))) | 104 | (expand-file-name "a/b/c/foo"))) |
| 105 | (when (memq system-type '(ms-dos windows-nt)) | ||
| 106 | ;; Test expansion of drive-relative file names. | ||
| 107 | (setenv "HOME" "x:foo") | ||
| 108 | (should (equal (expand-file-name "~/bar") "x:/foo/bar"))) | ||
| 105 | (setenv "HOME" old-home))) | 109 | (setenv "HOME" old-home))) |