diff options
| author | Joakim Verona | 2015-02-01 00:37:46 +0100 |
|---|---|---|
| committer | Joakim Verona | 2015-02-01 00:37:46 +0100 |
| commit | 69815dfe3704f8a8c733843f1fd04546cbb0f4d0 (patch) | |
| tree | cee6910753a51b9a5ee88e2431c9bcad099e8ba8 /lisp | |
| parent | 4edad429cafb2f0b1fda028be58367286ab04f1c (diff) | |
| parent | a2c32b0cfc9f6d3410e2832d8ea0d4f1df576d1e (diff) | |
| download | emacs-69815dfe3704f8a8c733843f1fd04546cbb0f4d0.tar.gz emacs-69815dfe3704f8a8c733843f1fd04546cbb0f4d0.zip | |
Merge branch 'master' into xwidget
Diffstat (limited to 'lisp')
37 files changed, 1638 insertions, 1168 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 80dfeef3750..0a3c7c95929 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,15 +1,233 @@ | |||
| 1 | 2015-01-31 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 2 | |||
| 3 | * emacs-lisp/eieio.el (defclass): Use new eieio-make-class-predicate | ||
| 4 | and eieio-make-child-predicate. | ||
| 5 | (eieio-class-parents): Use eieio--class-object. | ||
| 6 | (slot-boundp, find-class, eieio-override-prin1): Avoid class-p. | ||
| 7 | (slot-exists-p): Use find-class. | ||
| 8 | |||
| 9 | * emacs-lisp/eieio-opt.el (eieio-help-class, eieio-help-constructor): | ||
| 10 | Use find-lisp-object-file-name, help-fns-short-filename and new calling | ||
| 11 | convention for eieio-class-def. | ||
| 12 | (eieio-build-class-list): Remove function, unused. | ||
| 13 | (eieio-method-def): Remove button type, unused. | ||
| 14 | (eieio-class-def): Inherit from help-function-def. | ||
| 15 | (eieio--defclass-regexp): New constant. | ||
| 16 | (find-function-regexp-alist): Use it. | ||
| 17 | (eieio--specializers-apply-to-class-p): Handle eieio--static as well. | ||
| 18 | (eieio-help-find-method-definition, eieio-help-find-class-definition): | ||
| 19 | Remove functions. | ||
| 20 | |||
| 21 | * emacs-lisp/eieio-core.el (eieio--check-type): Remove. | ||
| 22 | Use cl-check-type everywhere instead. | ||
| 23 | (eieio-class-object): Remove, use find-class instead when needed. | ||
| 24 | (class-p): Don't inline. | ||
| 25 | (eieio-object-p): Check more thoroughly, so we don't treat cl-structs, | ||
| 26 | such as eieio classes, as objects. Don't inline. | ||
| 27 | (object-p): Mark as obsolete. | ||
| 28 | (eieio-defclass-autoload, eieio-defclass-internal, eieio-oref) | ||
| 29 | (eieio--generic-tagcode): Avoid `class-p'. | ||
| 30 | (eieio-make-class-predicate, eieio-make-child-predicate): New functions. | ||
| 31 | (eieio-defclass-internal): Use current-load-list rather than | ||
| 32 | `class-location'. | ||
| 33 | |||
| 34 | * emacs-lisp/cl-generic.el (cl--generic-search-method): Fix regexp. | ||
| 35 | |||
| 36 | 2015-01-30 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 37 | |||
| 38 | * emacs-lisp/backquote.el (backquote-delay-process): Don't reuse `s' | ||
| 39 | since it may be "equivalent" in some sense, yet different (bug#19734). | ||
| 40 | |||
| 41 | 2015-01-30 Oleh Krehel <ohwoeowho@gmail.com> | ||
| 42 | |||
| 43 | * outline.el (outline-font-lock-face): Add docstring. | ||
| 44 | (outline-invisible-p): Improve docstring. | ||
| 45 | (outline-invent-heading): Add docstring. | ||
| 46 | (outline-promote): Improve docstring. | ||
| 47 | (outline-demote): Improve docstring. | ||
| 48 | (outline-head-from-level): Improve docstring. | ||
| 49 | (outline-end-of-heading): Add docstring. | ||
| 50 | (outline-next-visible-heading): Improve docstring. | ||
| 51 | (outline-previous-visible-heading): Improve docstring. | ||
| 52 | (outline-hide-region-body): Improve docstring. | ||
| 53 | (outline-flag-subtree): Add docstring. | ||
| 54 | (outline-end-of-subtree): Add docstring. | ||
| 55 | (outline-headers-as-kill): Improve docstring. | ||
| 56 | |||
| 57 | 2015-01-30 Oleh Krehel <ohwoeowho@gmail.com> | ||
| 58 | |||
| 59 | * outline.el (outline-hide-entry): Rename from `hide-entry'. | ||
| 60 | (hide-entry): Declare as obsolete. | ||
| 61 | (outline-show-entry): Rename from `show-entry'. | ||
| 62 | (show-entry): Declare as obsolete. | ||
| 63 | (outline-hide-body): Rename from `hide-body'. | ||
| 64 | (hide-body): Declare as obsolete. | ||
| 65 | (outline-hide-region-body): Rename from `hide-region-body'. | ||
| 66 | (hide-region-body): Declare as obsolete. | ||
| 67 | (outline-show-all): Rename from `show-all'. | ||
| 68 | (show-all): Declare as obsolete. | ||
| 69 | (outline-hide-subtree): Rename from `hide-subtree'. | ||
| 70 | (hide-subtree): Declare as obsolete. | ||
| 71 | (outline-hide-leaves): Rename from `hide-leaves'. | ||
| 72 | (hide-leaves): Declare as obsolete. | ||
| 73 | (outline-show-subtree): Rename from `show-subtree'. | ||
| 74 | (show-subtree): Declare as obsolete. | ||
| 75 | (outline-hide-sublevels): Rename from `hide-sublevels'. | ||
| 76 | (hide-sublevels): Declare as obsolete. | ||
| 77 | (outline-hide-other): Rename from `hide-other'. | ||
| 78 | (hide-other): Declare as obsolete. | ||
| 79 | (outline-show-children): Rename from `show-children'. | ||
| 80 | (show-children): Declare as obsolete. | ||
| 81 | (outline-show-branches): Rename from `show-branches'. | ||
| 82 | (show-branches): Declare as obsolete. | ||
| 83 | |||
| 84 | 2015-01-30 Oleh Krehel <ohwoeowho@gmail.com> | ||
| 85 | |||
| 86 | * outline.el (outline-mode): Clean up docstring. | ||
| 87 | (font-lock-warning-face): Remove obsolete declaration. | ||
| 88 | (outline-font-lock-face): Remove obsolete comment. | ||
| 89 | |||
| 90 | 2015-01-30 Oleh Krehel <ohwoeowho@gmail.com> | ||
| 91 | |||
| 92 | * lisp/custom.el (defface): Set `indent' to 1. | ||
| 93 | |||
| 94 | 2015-01-30 Oleh Krehel <ohwoeowho@gmail.com> | ||
| 95 | |||
| 96 | * emacs-lisp/easy-mmode.el (define-minor-mode): Set `indent' to 1. | ||
| 97 | |||
| 98 | 2015-01-30 Michal Nazarewicz <mina86@mina86.com> | ||
| 99 | |||
| 100 | * lisp/files.el (save-buffers-kill-emacs): If `confirm-kill-emacs' | ||
| 101 | is set, but user has just been asked whether they really want to | ||
| 102 | kill Emacs (for example with a ‘Modified buffers exist; exit | ||
| 103 | anyway?’ prompt), do not ask them for another confirmation. | ||
| 104 | |||
| 105 | 2015-01-29 Jay Belanger <jay.p.belanger@gmail.com> | ||
| 106 | |||
| 107 | * lisp/calc/calc-units.el (calc-convert-exact-units): New function. | ||
| 108 | (calc-convert-units): Check for missing units. | ||
| 109 | (math-consistent-units-p): Strengthen the test for consistent units. | ||
| 110 | |||
| 111 | * lisp/calc/calc-ext.el (calc-init-extensions): Autoload | ||
| 112 | `calc-convert-exact-units' and assign it a keybinding. | ||
| 113 | |||
| 114 | * lisp/calc/calc-help (calc-u-prefix-help): Add help for the | ||
| 115 | "un" keybinding. | ||
| 116 | |||
| 117 | 2015-01-28 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 118 | |||
| 119 | * emacs-lisp/cl.el (cl--function-convert): Simplify. | ||
| 120 | |||
| 121 | 2015-01-28 Tassilo Horn <tsdh@gnu.org> | ||
| 122 | |||
| 123 | * textmodes/reftex.el (reftex-syntax-table-for-bib): Give ( and ) | ||
| 124 | punctuation syntax since to allow bibtex fields with values such | ||
| 125 | as {Test 1) and 2)} (bug#19205, bug#19707). | ||
| 126 | (reftex--prepare-syntax-tables): New function. | ||
| 127 | (reftex-mode): Use it. | ||
| 128 | |||
| 129 | 2015-01-28 Fabián Ezequiel Gallina <fgallina@gnu.org> | ||
| 130 | |||
| 131 | python.el: New non-global state dependent indentation engine. | ||
| 132 | (Bug#18319, Bug#19595) | ||
| 133 | * progmodes/python.el (python-syntax-comment-or-string-p): | ||
| 134 | Accept PPSS as argument. | ||
| 135 | (python-syntax-closing-paren-p): New function. | ||
| 136 | (python-indent-current-level) | ||
| 137 | (python-indent-levels): Mark obsolete. | ||
| 138 | (python-indent-context): Return more context cases. | ||
| 139 | (python-indent--calculate-indentation) | ||
| 140 | (python-indent--calculate-levels): New functions. | ||
| 141 | (python-indent-calculate-levels): Use them. | ||
| 142 | (python-indent-calculate-indentation, python-indent-line): | ||
| 143 | (python-indent-line-function): Rewritten to use new API. | ||
| 144 | (python-indent-dedent-line): Simplify logic. | ||
| 145 | (python-indent-dedent-line-backspace): Use `unless`. | ||
| 146 | (python-indent-toggle-levels): Delete function. | ||
| 147 | |||
| 148 | 2015-01-28 Daniel Koning <dk@danielkoning.com> (tiny change) | ||
| 149 | |||
| 150 | * subr.el (posnp): Correct docstring of `posnp'. | ||
| 151 | (posn-col-row): Make it work with all mouse position objects. | ||
| 152 | * textmodes/artist.el (artist-mouse-draw-continously): | ||
| 153 | Cancel timers if an error occurs during continuous drawing. (Bug#6130) | ||
| 154 | |||
| 155 | 2015-01-28 Eli Zaretskii <eliz@gnu.org> | ||
| 156 | |||
| 157 | * button.el (button-activate, push-button): Doc fix. (Bug#19628) | ||
| 158 | |||
| 159 | 2015-01-28 Michael Albinus <michael.albinus@gmx.de> | ||
| 160 | |||
| 161 | * filenotify.el (file-notify-descriptors, file-notify-handle-event): | ||
| 162 | Adapt docstring. | ||
| 163 | (file-notify--descriptor): New defun. | ||
| 164 | (file-notify-callback, file-notify-add-watch, file-notify-rm-watch): | ||
| 165 | Adapt docstring. Handle multiple values for | ||
| 166 | `file-notify-descriptors' entries. (Bug#18880) | ||
| 167 | |||
| 168 | * net/tramp.el (tramp-handle-file-notify-rm-watch): Do not check | ||
| 169 | `file-notify-descriptors', the implementation has been changed. | ||
| 170 | |||
| 171 | 2015-01-28 Eli Zaretskii <eliz@gnu.org> | ||
| 172 | |||
| 173 | * net/net-utils.el (net-utils-run-program, net-utils-run-simple): | ||
| 174 | On MS-Windows, bind coding-system-for-read to the console output | ||
| 175 | codepage. (Bug#19458) | ||
| 176 | |||
| 177 | 2015-01-28 Dmitry Gutov <dgutov@yandex.ru> | ||
| 178 | |||
| 179 | Unbreak `mouse-action' property in text buttons. | ||
| 180 | * button.el (push-button): Fix regression from 2012-12-06. | ||
| 181 | |||
| 182 | 2015-01-28 Glenn Morris <rgm@gnu.org> | ||
| 183 | |||
| 184 | * progmodes/sh-script.el (sh-mode): Doc fix. | ||
| 185 | (sh-basic-indent-line): Handle electric newline. (Bug#18756) | ||
| 186 | |||
| 187 | 2015-01-28 Paul Eggert <eggert@cs.ucla.edu> | ||
| 188 | |||
| 189 | Fix dired quoting bug with "Hit`N`Hide". Fixes Bug#19498. | ||
| 190 | * files.el (shell-quote-wildcard-pattern): Also quote "`". | ||
| 191 | |||
| 192 | 2015-01-28 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 193 | |||
| 194 | Tighten up the tagcode used for eieio and cl-struct objects. | ||
| 195 | * loadup.el: Load cl-preloaded. | ||
| 196 | * emacs-lisp/eieio-core.el (eieio-defclass-internal): Set the function | ||
| 197 | slot of the tag symbol to :quick-object-witness-check. | ||
| 198 | (eieio-object-p): Use :quick-object-witness-check. | ||
| 199 | (eieio--generic-tagcode): Use cl--generic-struct-tag. | ||
| 200 | * emacs-lisp/cl-preloaded.el: New file. | ||
| 201 | * emacs-lisp/cl-macs.el (cl--bind-inits): Remove, unused. | ||
| 202 | (cl--transform-lambda, cl-destructuring-bind): Remove cl--bind-inits. | ||
| 203 | (cl--make-usage-args): Strip away &aux args. | ||
| 204 | (cl-case, cl-typecase, cl--parse-loop-clause): Use macroexp-let2. | ||
| 205 | (cl-the, cl-check-type): Use macroexp-let2 and cl-typep. | ||
| 206 | (cl-defstruct): Use `declare' and cl-struct-define. | ||
| 207 | * emacs-lisp/cl-generic.el (cl--generic-struct-tag): New function. | ||
| 208 | (cl--generic-struct-tagcode): Use it to tighten the tagcode. | ||
| 209 | |||
| 210 | 2015-01-27 Katsumi Yamaoka <yamaoka@jpl.org> | ||
| 211 | |||
| 212 | * emacs-lisp/cl.el (cl--function-convert): | ||
| 213 | Merge cache that cl--labels-convert adds (bug#19699). | ||
| 214 | |||
| 215 | 2015-01-27 Ivan Shmakov <ivan@siamics.net> | ||
| 216 | |||
| 217 | * tar-mode.el: Allow for adding new archive members. (Bug#19274) | ||
| 218 | (tar-new-regular-file-header, tar--pad-to, tar--put-at) | ||
| 219 | (tar-header-serialize): New functions. | ||
| 220 | (tar-current-position): Split from tar-current-descriptor. | ||
| 221 | (tar-current-descriptor): Use it. | ||
| 222 | (tar-new-entry): New command. | ||
| 223 | (tar-mode-map): Bind it. | ||
| 224 | |||
| 1 | 2015-01-27 Sam Steingold <sds@gnu.org> | 225 | 2015-01-27 Sam Steingold <sds@gnu.org> |
| 2 | 226 | ||
| 3 | * progmodes/python.el (python-check-custom-command): Buffer local | 227 | * progmodes/python.el (python-check-custom-command): Buffer local |
| 4 | because it usually includes the buffer name. | 228 | because it usually includes the buffer name. |
| 5 | (python-check-command): Set to epylint when pyflakes is not available. | 229 | (python-check-command): Set to epylint when pyflakes is not available. |
| 6 | 230 | ||
| 7 | 2015-01-27 Thomas Fitzsimmons <fitzsim@fitzsim.org> | ||
| 8 | |||
| 9 | * net/eudcb-bbdb.el, net/eudcb-ldap.el, net/eudcb-mab.el, | ||
| 10 | net/eudc-bob.el, net/eudcb-ph.el, net/eudc.el, net/eudc-export.el, | ||
| 11 | net/eudc-hotlist.el, net/eudc-vars.el: New maintainer. | ||
| 12 | |||
| 13 | 2015-01-27 Artur Malabarba <bruce.connor.am@gmail.com> | 231 | 2015-01-27 Artur Malabarba <bruce.connor.am@gmail.com> |
| 14 | 232 | ||
| 15 | * isearch.el (isearch-process-search-char): Add docstring. | 233 | * isearch.el (isearch-process-search-char): Add docstring. |
| @@ -70,6 +288,8 @@ | |||
| 70 | 2015-01-26 Lars Ingebrigtsen <larsi@gnus.org> | 288 | 2015-01-26 Lars Ingebrigtsen <larsi@gnus.org> |
| 71 | 289 | ||
| 72 | * net/shr.el (shr-make-table-1): Fix colspan typo. | 290 | * net/shr.el (shr-make-table-1): Fix colspan typo. |
| 291 | (shr-make-table-1): Add comments. | ||
| 292 | (shr-make-table-1): Make colspan display more sensibly. | ||
| 73 | 293 | ||
| 74 | * net/eww.el (eww-add-bookmark): Fix prompt and clean up the code | 294 | * net/eww.el (eww-add-bookmark): Fix prompt and clean up the code |
| 75 | slightly. | 295 | slightly. |
| @@ -1742,8 +1962,7 @@ | |||
| 1742 | 2014-12-14 Steve Purcell <steve@sanityinc.com> (tiny change) | 1962 | 2014-12-14 Steve Purcell <steve@sanityinc.com> (tiny change) |
| 1743 | 1963 | ||
| 1744 | * emacs-lisp/package.el (package-menu-mode): Use an extra column | 1964 | * emacs-lisp/package.el (package-menu-mode): Use an extra column |
| 1745 | for the "Version" column, to accomodate date-and-time-based | 1965 | for the "Version" column, to accomodate date-and-time-based versions. |
| 1746 | versions. | ||
| 1747 | 1966 | ||
| 1748 | 2014-12-14 Cameron Desautels <camdez@gmail.com> | 1967 | 2014-12-14 Cameron Desautels <camdez@gmail.com> |
| 1749 | 1968 | ||
diff --git a/lisp/button.el b/lisp/button.el index 189a1c23a4d..e7602dd7050 100644 --- a/lisp/button.el +++ b/lisp/button.el | |||
| @@ -224,10 +224,10 @@ changes to a supertype are not reflected in its subtypes)." | |||
| 224 | prop val)))) | 224 | prop val)))) |
| 225 | 225 | ||
| 226 | (defun button-activate (button &optional use-mouse-action) | 226 | (defun button-activate (button &optional use-mouse-action) |
| 227 | "Call BUTTON's action property. | 227 | "Call BUTTON's `action' property. |
| 228 | If USE-MOUSE-ACTION is non-nil, invoke the button's mouse-action | 228 | If USE-MOUSE-ACTION is non-nil, invoke the button's `mouse-action' |
| 229 | instead of its normal action; if the button has no mouse-action, | 229 | property instead of `action'; if the button has no `mouse-action', |
| 230 | the normal action is used instead. | 230 | the value of `action' is used instead. |
| 231 | 231 | ||
| 232 | The action can either be a marker or a function. If it's a | 232 | The action can either be a marker or a function. If it's a |
| 233 | marker then goto it. Otherwise it it is a function then it is | 233 | marker then goto it. Otherwise it it is a function then it is |
| @@ -429,11 +429,13 @@ instead of starting at the next button." | |||
| 429 | (defun push-button (&optional pos use-mouse-action) | 429 | (defun push-button (&optional pos use-mouse-action) |
| 430 | "Perform the action specified by a button at location POS. | 430 | "Perform the action specified by a button at location POS. |
| 431 | POS may be either a buffer position or a mouse-event. If | 431 | POS may be either a buffer position or a mouse-event. If |
| 432 | USE-MOUSE-ACTION is non-nil, invoke the button's mouse-action | 432 | USE-MOUSE-ACTION is non-nil, invoke the button's `mouse-action' |
| 433 | instead of its normal action; if the button has no mouse-action, | 433 | property instead of its `action' property; if the button has no |
| 434 | the normal action is used instead. The action may be either a | 434 | `mouse-action', the value of `action' is used instead. |
| 435 | function to call or a marker to display and is invoked using | 435 | |
| 436 | `button-activate' (which see). | 436 | The action in both cases may be either a function to call or a |
| 437 | marker to display and is invoked using `button-activate' (which | ||
| 438 | see). | ||
| 437 | 439 | ||
| 438 | POS defaults to point, except when `push-button' is invoked | 440 | POS defaults to point, except when `push-button' is invoked |
| 439 | interactively as the result of a mouse-event, in which case, the | 441 | interactively as the result of a mouse-event, in which case, the |
diff --git a/lisp/calc/calc-ext.el b/lisp/calc/calc-ext.el index c3acb89e417..67d0c2701d2 100644 --- a/lisp/calc/calc-ext.el +++ b/lisp/calc/calc-ext.el | |||
| @@ -561,6 +561,7 @@ | |||
| 561 | (define-key calc-mode-map "ud" 'calc-define-unit) | 561 | (define-key calc-mode-map "ud" 'calc-define-unit) |
| 562 | (define-key calc-mode-map "ue" 'calc-explain-units) | 562 | (define-key calc-mode-map "ue" 'calc-explain-units) |
| 563 | (define-key calc-mode-map "ug" 'calc-get-unit-definition) | 563 | (define-key calc-mode-map "ug" 'calc-get-unit-definition) |
| 564 | (define-key calc-mode-map "un" 'calc-convert-exact-units) | ||
| 564 | (define-key calc-mode-map "up" 'calc-permanent-units) | 565 | (define-key calc-mode-map "up" 'calc-permanent-units) |
| 565 | (define-key calc-mode-map "ur" 'calc-remove-units) | 566 | (define-key calc-mode-map "ur" 'calc-remove-units) |
| 566 | (define-key calc-mode-map "us" 'calc-simplify-units) | 567 | (define-key calc-mode-map "us" 'calc-simplify-units) |
| @@ -1176,7 +1177,8 @@ calc-trail-scroll-right calc-trail-yank) | |||
| 1176 | ("calc-undo" calc-last-args calc-redo) | 1177 | ("calc-undo" calc-last-args calc-redo) |
| 1177 | 1178 | ||
| 1178 | ("calc-units" calc-autorange-units calc-base-units | 1179 | ("calc-units" calc-autorange-units calc-base-units |
| 1179 | calc-convert-temperature calc-convert-units calc-define-unit | 1180 | calc-convert-temperature calc-convert-units |
| 1181 | calc-convert-exact-units calc-define-unit | ||
| 1180 | calc-enter-units-table calc-explain-units calc-extract-units | 1182 | calc-enter-units-table calc-explain-units calc-extract-units |
| 1181 | calc-get-unit-definition calc-permanent-units calc-quick-units | 1183 | calc-get-unit-definition calc-permanent-units calc-quick-units |
| 1182 | calc-remove-units calc-simplify-units calc-undefine-unit | 1184 | calc-remove-units calc-simplify-units calc-undefine-unit |
diff --git a/lisp/calc/calc-help.el b/lisp/calc/calc-help.el index 511e208ddea..17e5b0fdead 100644 --- a/lisp/calc/calc-help.el +++ b/lisp/calc/calc-help.el | |||
| @@ -647,7 +647,7 @@ C-w Describe how there is no warranty for Calc." | |||
| 647 | (defun calc-u-prefix-help () | 647 | (defun calc-u-prefix-help () |
| 648 | (interactive) | 648 | (interactive) |
| 649 | (calc-do-prefix-help | 649 | (calc-do-prefix-help |
| 650 | '("Simplify, Convert, Temperature-convert, Base-units" | 650 | '("Simplify, Convert, coNvert exact, Temperature-convert, Base-units" |
| 651 | "Autorange; Remove, eXtract; Explain; View-table; 0-9" | 651 | "Autorange; Remove, eXtract; Explain; View-table; 0-9" |
| 652 | "Define, Undefine, Get-defn, Permanent" | 652 | "Define, Undefine, Get-defn, Permanent" |
| 653 | "SHIFT + View-table-other-window" | 653 | "SHIFT + View-table-other-window" |
diff --git a/lisp/calc/calc-units.el b/lisp/calc/calc-units.el index 05950864a52..f3d02340fe3 100644 --- a/lisp/calc/calc-units.el +++ b/lisp/calc/calc-units.el | |||
| @@ -470,6 +470,8 @@ If COMP or STD is non-nil, put that in the units table instead." | |||
| 470 | (if (string-match "\\` */" uoldname) | 470 | (if (string-match "\\` */" uoldname) |
| 471 | (setq uoldname (concat "1" uoldname))) | 471 | (setq uoldname (concat "1" uoldname))) |
| 472 | (math-read-expr uoldname)))))) | 472 | (math-read-expr uoldname)))))) |
| 473 | (unless (math-units-in-expr-p uold t) | ||
| 474 | (error "No units specified")) | ||
| 473 | (when (eq (car-safe uold) 'error) | 475 | (when (eq (car-safe uold) 'error) |
| 474 | (error "Bad format in units expression: %s" (nth 1 uold))) | 476 | (error "Bad format in units expression: %s" (nth 1 uold))) |
| 475 | (setq expr (math-mul expr uold)))) | 477 | (setq expr (math-mul expr uold)))) |
| @@ -514,6 +516,38 @@ If COMP or STD is non-nil, put that in the units table instead." | |||
| 514 | (math-put-default-units (if noold units res) (if comp units))) | 516 | (math-put-default-units (if noold units res) (if comp units))) |
| 515 | (calc-enter-result 1 "cvun" res)))))) | 517 | (calc-enter-result 1 "cvun" res)))))) |
| 516 | 518 | ||
| 519 | (defun calc-convert-exact-units () | ||
| 520 | (interactive) | ||
| 521 | (calc-slow-wrapper | ||
| 522 | (let* ((expr (calc-top-n 1))) | ||
| 523 | (unless (math-units-in-expr-p expr t) | ||
| 524 | (error "No units in expression.")) | ||
| 525 | (let* ((old-units (math-extract-units expr)) | ||
| 526 | (defunits (math-get-default-units expr)) | ||
| 527 | units | ||
| 528 | (new-units | ||
| 529 | (read-string (concat "New units" | ||
| 530 | (if defunits | ||
| 531 | (concat | ||
| 532 | " (default " | ||
| 533 | defunits | ||
| 534 | "): ") | ||
| 535 | ": "))))) | ||
| 536 | (if (and | ||
| 537 | (string= new-units "") | ||
| 538 | defunits) | ||
| 539 | (setq new-units defunits)) | ||
| 540 | (setq units (math-read-expr new-units)) | ||
| 541 | (when (eq (car-safe units) 'error) | ||
| 542 | (error "Bad format in units expression: %s" (nth 2 units))) | ||
| 543 | (math-check-unit-consistency old-units units) | ||
| 544 | (let ((res | ||
| 545 | (list '* (math-mul (math-remove-units expr) | ||
| 546 | (math-simplify-units | ||
| 547 | (math-to-standard-units (list '/ old-units units) nil))) | ||
| 548 | units))) | ||
| 549 | (calc-enter-result 1 "cvxu" res)))))) | ||
| 550 | |||
| 517 | (defun calc-autorange-units (arg) | 551 | (defun calc-autorange-units (arg) |
| 518 | (interactive "P") | 552 | (interactive "P") |
| 519 | (calc-wrapper | 553 | (calc-wrapper |
| @@ -945,7 +979,7 @@ If COMP or STD is non-nil, put that in the units table instead." | |||
| 945 | (or | 979 | (or |
| 946 | (and (eq (car-safe newunits) 'var) | 980 | (and (eq (car-safe newunits) 'var) |
| 947 | (assq (nth 1 newunits) math-standard-units-systems)) | 981 | (assq (nth 1 newunits) math-standard-units-systems)) |
| 948 | (math-numberp (math-get-units (list '/ expr newunits))))) | 982 | (math-numberp (math-get-units (math-to-standard-units (list '/ expr newunits) nil))))) |
| 949 | 983 | ||
| 950 | (defun math-check-unit-consistency (expr units) | 984 | (defun math-check-unit-consistency (expr units) |
| 951 | "Give an error if EXPR and UNITS do not have consistent units." | 985 | "Give an error if EXPR and UNITS do not have consistent units." |
diff --git a/lisp/custom.el b/lisp/custom.el index 779e585c04f..e5fe0ebaedd 100644 --- a/lisp/custom.el +++ b/lisp/custom.el | |||
| @@ -411,7 +411,8 @@ In the ATTS property list, possible attributes are `:family', | |||
| 411 | 411 | ||
| 412 | See Info node `(elisp) Faces' in the Emacs Lisp manual for more | 412 | See Info node `(elisp) Faces' in the Emacs Lisp manual for more |
| 413 | information." | 413 | information." |
| 414 | (declare (doc-string 3)) | 414 | (declare (doc-string 3) |
| 415 | (indent 1)) | ||
| 415 | ;; It is better not to use backquote in this file, | 416 | ;; It is better not to use backquote in this file, |
| 416 | ;; because that makes a bootstrapping problem | 417 | ;; because that makes a bootstrapping problem |
| 417 | ;; if you need to recompile all the Lisp files using interpreted code. | 418 | ;; if you need to recompile all the Lisp files using interpreted code. |
diff --git a/lisp/emacs-lisp/backquote.el b/lisp/emacs-lisp/backquote.el index 082955e0823..d5cdca2b1b5 100644 --- a/lisp/emacs-lisp/backquote.el +++ b/lisp/emacs-lisp/backquote.el | |||
| @@ -120,9 +120,7 @@ Vectors work just like lists. Nested backquotes are permitted." | |||
| 120 | This simply recurses through the body." | 120 | This simply recurses through the body." |
| 121 | (let ((exp (backquote-listify (list (cons 0 (list 'quote (car s)))) | 121 | (let ((exp (backquote-listify (list (cons 0 (list 'quote (car s)))) |
| 122 | (backquote-process (cdr s) level)))) | 122 | (backquote-process (cdr s) level)))) |
| 123 | (if (eq (car-safe exp) 'quote) | 123 | (cons (if (eq (car-safe exp) 'quote) 0 1) exp))) |
| 124 | (cons 0 (list 'quote s)) | ||
| 125 | (cons 1 exp)))) | ||
| 126 | 124 | ||
| 127 | (defun backquote-process (s &optional level) | 125 | (defun backquote-process (s &optional level) |
| 128 | "Process the body of a backquote. | 126 | "Process the body of a backquote. |
diff --git a/lisp/emacs-lisp/cl-generic.el b/lisp/emacs-lisp/cl-generic.el index 1bb70963a57..72ec8ec1801 100644 --- a/lisp/emacs-lisp/cl-generic.el +++ b/lisp/emacs-lisp/cl-generic.el | |||
| @@ -635,7 +635,8 @@ Can only be used from within the lexical body of a primary or around method." | |||
| 635 | 635 | ||
| 636 | (defun cl--generic-search-method (met-name) | 636 | (defun cl--generic-search-method (met-name) |
| 637 | (let ((base-re (concat "(\\(?:cl-\\)?defmethod[ \t]+" | 637 | (let ((base-re (concat "(\\(?:cl-\\)?defmethod[ \t]+" |
| 638 | (regexp-quote (format "%s\\_>" (car met-name)))))) | 638 | (regexp-quote (format "%s" (car met-name))) |
| 639 | "\\_>"))) | ||
| 639 | (or | 640 | (or |
| 640 | (re-search-forward | 641 | (re-search-forward |
| 641 | (concat base-re "[^&\"\n]*" | 642 | (concat base-re "[^&\"\n]*" |
| @@ -724,6 +725,14 @@ Can only be used from within the lexical body of a primary or around method." | |||
| 724 | 725 | ||
| 725 | (add-function :before-until cl-generic-tagcode-function | 726 | (add-function :before-until cl-generic-tagcode-function |
| 726 | #'cl--generic-struct-tagcode) | 727 | #'cl--generic-struct-tagcode) |
| 728 | |||
| 729 | (defun cl--generic-struct-tag (name) | ||
| 730 | `(and (vectorp ,name) | ||
| 731 | (> (length ,name) 0) | ||
| 732 | (let ((tag (aref ,name 0))) | ||
| 733 | (if (eq (symbol-function tag) :quick-object-witness-check) | ||
| 734 | tag)))) | ||
| 735 | |||
| 727 | (defun cl--generic-struct-tagcode (type name) | 736 | (defun cl--generic-struct-tagcode (type name) |
| 728 | (and (symbolp type) | 737 | (and (symbolp type) |
| 729 | (get type 'cl-struct-type) | 738 | (get type 'cl-struct-type) |
| @@ -733,12 +742,19 @@ Can only be used from within the lexical body of a primary or around method." | |||
| 733 | (or (equal '(cl-tag-slot) (car (get type 'cl-struct-slots))) | 742 | (or (equal '(cl-tag-slot) (car (get type 'cl-struct-slots))) |
| 734 | (error "Can't dispatch on cl-struct %S: no tag in slot 0" | 743 | (error "Can't dispatch on cl-struct %S: no tag in slot 0" |
| 735 | type)) | 744 | type)) |
| 736 | ;; We could/should check the vector has length >0, | 745 | ;; It's tempting to use (and (vectorp ,name) (aref ,name 0)) |
| 737 | ;; but really, mixing vectors and structs is a bad idea, | 746 | ;; but that would suffer from some problems: |
| 738 | ;; so let's not waste time trying to handle the case | 747 | ;; - the vector may have size 0. |
| 739 | ;; of an empty vector. | 748 | ;; - when called on an actual vector (rather than an object), we'd |
| 740 | ;; BEWARE: this returns a bogus tag for non-struct vectors. | 749 | ;; end up returning an arbitrary value, possibly colliding with |
| 741 | `(50 . (and (vectorp ,name) (aref ,name 0))))) | 750 | ;; other tagcode's values. |
| 751 | ;; - it can also result in returning all kinds of irrelevant | ||
| 752 | ;; values which would end up filling up the method-cache with | ||
| 753 | ;; lots of irrelevant/redundant entries. | ||
| 754 | ;; FIXME: We could speed this up by introducing a dedicated | ||
| 755 | ;; vector type at the C level, so we could do something like | ||
| 756 | ;; (and (vector-objectp ,name) (aref ,name 0)) | ||
| 757 | `(50 . ,(cl--generic-struct-tag name)))) | ||
| 742 | 758 | ||
| 743 | (add-function :before-until cl-generic-tag-types-function | 759 | (add-function :before-until cl-generic-tag-types-function |
| 744 | #'cl--generic-struct-tag-types) | 760 | #'cl--generic-struct-tag-types) |
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index 38f15b89b0e..eaec2c5263c 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el | |||
| @@ -221,7 +221,7 @@ The name is made by appending a number to PREFIX, default \"G\"." | |||
| 221 | '(&optional &rest &key &allow-other-keys &aux &whole &body &environment)) | 221 | '(&optional &rest &key &allow-other-keys &aux &whole &body &environment)) |
| 222 | 222 | ||
| 223 | (defvar cl--bind-block) (defvar cl--bind-defs) (defvar cl--bind-enquote) | 223 | (defvar cl--bind-block) (defvar cl--bind-defs) (defvar cl--bind-enquote) |
| 224 | (defvar cl--bind-inits) (defvar cl--bind-lets) (defvar cl--bind-forms) | 224 | (defvar cl--bind-lets) (defvar cl--bind-forms) |
| 225 | 225 | ||
| 226 | (defun cl--transform-lambda (form bind-block) | 226 | (defun cl--transform-lambda (form bind-block) |
| 227 | "Transform a function form FORM of name BIND-BLOCK. | 227 | "Transform a function form FORM of name BIND-BLOCK. |
| @@ -229,9 +229,11 @@ BIND-BLOCK is the name of the symbol to which the function will be bound, | |||
| 229 | and which will be used for the name of the `cl-block' surrounding the | 229 | and which will be used for the name of the `cl-block' surrounding the |
| 230 | function's body. | 230 | function's body. |
| 231 | FORM is of the form (ARGS . BODY)." | 231 | FORM is of the form (ARGS . BODY)." |
| 232 | ;; FIXME: (lambda (a &aux b) 1) expands to (lambda (a &rest --cl-rest--) ...) | ||
| 233 | ;; where the --cl-rest-- is clearly undesired. | ||
| 232 | (let* ((args (car form)) (body (cdr form)) (orig-args args) | 234 | (let* ((args (car form)) (body (cdr form)) (orig-args args) |
| 233 | (cl--bind-block bind-block) (cl--bind-defs nil) (cl--bind-enquote nil) | 235 | (cl--bind-block bind-block) (cl--bind-defs nil) (cl--bind-enquote nil) |
| 234 | (cl--bind-inits nil) (cl--bind-lets nil) (cl--bind-forms nil) | 236 | (cl--bind-lets nil) (cl--bind-forms nil) |
| 235 | (header nil) (simple-args nil)) | 237 | (header nil) (simple-args nil)) |
| 236 | (while (or (stringp (car body)) | 238 | (while (or (stringp (car body)) |
| 237 | (memq (car-safe (car body)) '(interactive declare cl-declare))) | 239 | (memq (car-safe (car body)) '(interactive declare cl-declare))) |
| @@ -244,10 +246,10 @@ FORM is of the form (ARGS . BODY)." | |||
| 244 | (if (setq cl--bind-enquote (memq '&cl-quote args)) | 246 | (if (setq cl--bind-enquote (memq '&cl-quote args)) |
| 245 | (setq args (delq '&cl-quote args))) | 247 | (setq args (delq '&cl-quote args))) |
| 246 | (if (memq '&whole args) (error "&whole not currently implemented")) | 248 | (if (memq '&whole args) (error "&whole not currently implemented")) |
| 247 | (let* ((p (memq '&environment args)) (v (cadr p)) | 249 | (let* ((p (memq '&environment args)) |
| 248 | (env-exp 'macroexpand-all-environment)) | 250 | (v (cadr p))) |
| 249 | (if p (setq args (nconc (delq (car p) (delq v args)) | 251 | (if p (setq args (nconc (delq (car p) (delq v args)) |
| 250 | (list '&aux (list v env-exp)))))) | 252 | `(&aux (,v macroexpand-all-environment)))))) |
| 251 | (while (and args (symbolp (car args)) | 253 | (while (and args (symbolp (car args)) |
| 252 | (not (memq (car args) '(nil &rest &body &key &aux))) | 254 | (not (memq (car args) '(nil &rest &body &key &aux))) |
| 253 | (not (and (eq (car args) '&optional) | 255 | (not (and (eq (car args) '&optional) |
| @@ -261,8 +263,7 @@ FORM is of the form (ARGS . BODY)." | |||
| 261 | (cl--do-arglist args nil (- (length simple-args) | 263 | (cl--do-arglist args nil (- (length simple-args) |
| 262 | (if (memq '&optional simple-args) 1 0))) | 264 | (if (memq '&optional simple-args) 1 0))) |
| 263 | (setq cl--bind-lets (nreverse cl--bind-lets)) | 265 | (setq cl--bind-lets (nreverse cl--bind-lets)) |
| 264 | (cl-list* (and cl--bind-inits `(cl-eval-when (compile load eval) | 266 | (cl-list* nil |
| 265 | ,@(nreverse cl--bind-inits))) | ||
| 266 | (nconc (nreverse simple-args) | 267 | (nconc (nreverse simple-args) |
| 267 | (list '&rest (car (pop cl--bind-lets)))) | 268 | (list '&rest (car (pop cl--bind-lets)))) |
| 268 | (nconc (let ((hdr (nreverse header))) | 269 | (nconc (let ((hdr (nreverse header))) |
| @@ -390,6 +391,11 @@ its argument list allows full Common Lisp conventions." | |||
| 390 | (t x))) | 391 | (t x))) |
| 391 | 392 | ||
| 392 | (defun cl--make-usage-args (arglist) | 393 | (defun cl--make-usage-args (arglist) |
| 394 | (let ((aux (ignore-errors (cl-position '&aux arglist)))) | ||
| 395 | (when aux | ||
| 396 | ;; `&aux' args aren't arguments, so let's just drop them from the | ||
| 397 | ;; usage info. | ||
| 398 | (setq arglist (cl-subseq arglist 0 aux)))) | ||
| 393 | (if (cdr-safe (last arglist)) ;Not a proper list. | 399 | (if (cdr-safe (last arglist)) ;Not a proper list. |
| 394 | (let* ((last (last arglist)) | 400 | (let* ((last (last arglist)) |
| 395 | (tail (cdr last))) | 401 | (tail (cdr last))) |
| @@ -426,7 +432,7 @@ its argument list allows full Common Lisp conventions." | |||
| 426 | )))) | 432 | )))) |
| 427 | arglist)))) | 433 | arglist)))) |
| 428 | 434 | ||
| 429 | (defun cl--do-arglist (args expr &optional num) ; uses bind-* | 435 | (defun cl--do-arglist (args expr &optional num) ; uses cl--bind-* |
| 430 | (if (nlistp args) | 436 | (if (nlistp args) |
| 431 | (if (or (memq args cl--lambda-list-keywords) (not (symbolp args))) | 437 | (if (or (memq args cl--lambda-list-keywords) (not (symbolp args))) |
| 432 | (error "Invalid argument name: %s" args) | 438 | (error "Invalid argument name: %s" args) |
| @@ -441,9 +447,9 @@ its argument list allows full Common Lisp conventions." | |||
| 441 | (keys nil) | 447 | (keys nil) |
| 442 | (laterarg nil) (exactarg nil) minarg) | 448 | (laterarg nil) (exactarg nil) minarg) |
| 443 | (or num (setq num 0)) | 449 | (or num (setq num 0)) |
| 444 | (if (listp (cadr restarg)) | 450 | (setq restarg (if (listp (cadr restarg)) |
| 445 | (setq restarg (make-symbol "--cl-rest--")) | 451 | (make-symbol "--cl-rest--") |
| 446 | (setq restarg (cadr restarg))) | 452 | (cadr restarg))) |
| 447 | (push (list restarg expr) cl--bind-lets) | 453 | (push (list restarg expr) cl--bind-lets) |
| 448 | (if (eq (car args) '&whole) | 454 | (if (eq (car args) '&whole) |
| 449 | (push (list (cl--pop2 args) restarg) cl--bind-lets)) | 455 | (push (list (cl--pop2 args) restarg) cl--bind-lets)) |
| @@ -570,12 +576,11 @@ its argument list allows full Common Lisp conventions." | |||
| 570 | "Bind the variables in ARGS to the result of EXPR and execute BODY." | 576 | "Bind the variables in ARGS to the result of EXPR and execute BODY." |
| 571 | (declare (indent 2) | 577 | (declare (indent 2) |
| 572 | (debug (&define cl-macro-list def-form cl-declarations def-body))) | 578 | (debug (&define cl-macro-list def-form cl-declarations def-body))) |
| 573 | (let* ((cl--bind-lets nil) (cl--bind-forms nil) (cl--bind-inits nil) | 579 | (let* ((cl--bind-lets nil) (cl--bind-forms nil) |
| 574 | (cl--bind-defs nil) (cl--bind-block 'cl-none) (cl--bind-enquote nil)) | 580 | (cl--bind-defs nil) (cl--bind-block 'cl-none) (cl--bind-enquote nil)) |
| 575 | (cl--do-arglist (or args '(&aux)) expr) | 581 | (cl--do-arglist (or args '(&aux)) expr) |
| 576 | (append '(progn) cl--bind-inits | 582 | (macroexp-let* (nreverse cl--bind-lets) |
| 577 | (list `(let* ,(nreverse cl--bind-lets) | 583 | (macroexp-progn (append (nreverse cl--bind-forms) body))))) |
| 578 | ,@(nreverse cl--bind-forms) ,@body))))) | ||
| 579 | 584 | ||
| 580 | 585 | ||
| 581 | ;;; The `cl-eval-when' form. | 586 | ;;; The `cl-eval-when' form. |
| @@ -655,30 +660,26 @@ allowed only in the final clause, and matches if no other keys match. | |||
| 655 | Key values are compared by `eql'. | 660 | Key values are compared by `eql'. |
| 656 | \n(fn EXPR (KEYLIST BODY...)...)" | 661 | \n(fn EXPR (KEYLIST BODY...)...)" |
| 657 | (declare (indent 1) (debug (form &rest (sexp body)))) | 662 | (declare (indent 1) (debug (form &rest (sexp body)))) |
| 658 | (let* ((temp (if (cl--simple-expr-p expr 3) expr (make-symbol "--cl-var--"))) | 663 | (macroexp-let2 macroexp-copyable-p temp expr |
| 659 | (head-list nil) | 664 | (let* ((head-list nil)) |
| 660 | (body (cons | 665 | `(cond |
| 661 | 'cond | 666 | ,@(mapcar |
| 662 | (mapcar | 667 | (lambda (c) |
| 663 | (function | 668 | (cons (cond ((memq (car c) '(t otherwise)) t) |
| 664 | (lambda (c) | 669 | ((eq (car c) 'cl--ecase-error-flag) |
| 665 | (cons (cond ((memq (car c) '(t otherwise)) t) | 670 | `(error "cl-ecase failed: %s, %s" |
| 666 | ((eq (car c) 'cl--ecase-error-flag) | 671 | ,temp ',(reverse head-list))) |
| 667 | `(error "cl-ecase failed: %s, %s" | 672 | ((listp (car c)) |
| 668 | ,temp ',(reverse head-list))) | 673 | (setq head-list (append (car c) head-list)) |
| 669 | ((listp (car c)) | 674 | `(cl-member ,temp ',(car c))) |
| 670 | (setq head-list (append (car c) head-list)) | 675 | (t |
| 671 | `(cl-member ,temp ',(car c))) | 676 | (if (memq (car c) head-list) |
| 672 | (t | 677 | (error "Duplicate key in case: %s" |
| 673 | (if (memq (car c) head-list) | 678 | (car c))) |
| 674 | (error "Duplicate key in case: %s" | 679 | (push (car c) head-list) |
| 675 | (car c))) | 680 | `(eql ,temp ',(car c)))) |
| 676 | (push (car c) head-list) | 681 | (or (cdr c) '(nil)))) |
| 677 | `(eql ,temp ',(car c)))) | 682 | clauses))))) |
| 678 | (or (cdr c) '(nil))))) | ||
| 679 | clauses)))) | ||
| 680 | (if (eq temp expr) body | ||
| 681 | `(let ((,temp ,expr)) ,body)))) | ||
| 682 | 683 | ||
| 683 | ;;;###autoload | 684 | ;;;###autoload |
| 684 | (defmacro cl-ecase (expr &rest clauses) | 685 | (defmacro cl-ecase (expr &rest clauses) |
| @@ -698,24 +699,22 @@ final clause, and matches if no other keys match. | |||
| 698 | \n(fn EXPR (TYPE BODY...)...)" | 699 | \n(fn EXPR (TYPE BODY...)...)" |
| 699 | (declare (indent 1) | 700 | (declare (indent 1) |
| 700 | (debug (form &rest ([&or cl-type-spec "otherwise"] body)))) | 701 | (debug (form &rest ([&or cl-type-spec "otherwise"] body)))) |
| 701 | (let* ((temp (if (cl--simple-expr-p expr 3) expr (make-symbol "--cl-var--"))) | 702 | (macroexp-let2 macroexp-copyable-p temp expr |
| 702 | (type-list nil) | 703 | (let* ((type-list nil)) |
| 703 | (body (cons | 704 | (cons |
| 704 | 'cond | 705 | 'cond |
| 705 | (mapcar | 706 | (mapcar |
| 706 | (function | 707 | (function |
| 707 | (lambda (c) | 708 | (lambda (c) |
| 708 | (cons (cond ((eq (car c) 'otherwise) t) | 709 | (cons (cond ((eq (car c) 'otherwise) t) |
| 709 | ((eq (car c) 'cl--ecase-error-flag) | 710 | ((eq (car c) 'cl--ecase-error-flag) |
| 710 | `(error "cl-etypecase failed: %s, %s" | 711 | `(error "cl-etypecase failed: %s, %s" |
| 711 | ,temp ',(reverse type-list))) | 712 | ,temp ',(reverse type-list))) |
| 712 | (t | 713 | (t |
| 713 | (push (car c) type-list) | 714 | (push (car c) type-list) |
| 714 | (cl--make-type-test temp (car c)))) | 715 | `(cl-typep ,temp ',(car c)))) |
| 715 | (or (cdr c) '(nil))))) | 716 | (or (cdr c) '(nil))))) |
| 716 | clauses)))) | 717 | clauses))))) |
| 717 | (if (eq temp expr) body | ||
| 718 | `(let ((,temp ,expr)) ,body)))) | ||
| 719 | 718 | ||
| 720 | ;;;###autoload | 719 | ;;;###autoload |
| 721 | (defmacro cl-etypecase (expr &rest clauses) | 720 | (defmacro cl-etypecase (expr &rest clauses) |
| @@ -1439,16 +1438,14 @@ For more details, see Info node `(cl)Loop Facility'. | |||
| 1439 | (push `(progn (if ,what (cl-incf ,var)) t) cl--loop-body))) | 1438 | (push `(progn (if ,what (cl-incf ,var)) t) cl--loop-body))) |
| 1440 | 1439 | ||
| 1441 | ((memq word '(minimize minimizing maximize maximizing)) | 1440 | ((memq word '(minimize minimizing maximize maximizing)) |
| 1442 | (let* ((what (pop cl--loop-args)) | 1441 | (push `(progn ,(macroexp-let2 macroexp-copyable-p temp |
| 1443 | (temp (if (cl--simple-expr-p what) what | 1442 | (pop cl--loop-args) |
| 1444 | (make-symbol "--cl-var--"))) | 1443 | (let* ((var (cl--loop-handle-accum nil)) |
| 1445 | (var (cl--loop-handle-accum nil)) | 1444 | (func (intern (substring (symbol-name word) |
| 1446 | (func (intern (substring (symbol-name word) 0 3))) | 1445 | 0 3)))) |
| 1447 | (set `(setq ,var (if ,var (,func ,var ,temp) ,temp)))) | 1446 | `(setq ,var (if ,var (,func ,var ,temp) ,temp)))) |
| 1448 | (push `(progn ,(if (eq temp what) set | 1447 | t) |
| 1449 | `(let ((,temp ,what)) ,set)) | 1448 | cl--loop-body)) |
| 1450 | t) | ||
| 1451 | cl--loop-body))) | ||
| 1452 | 1449 | ||
| 1453 | ((eq word 'with) | 1450 | ((eq word 'with) |
| 1454 | (let ((bindings nil)) | 1451 | (let ((bindings nil)) |
| @@ -2104,14 +2101,11 @@ values. For compatibility, (cl-values A B C) is a synonym for (list A B C). | |||
| 2104 | (< cl--optimize-speed 3) | 2101 | (< cl--optimize-speed 3) |
| 2105 | (= cl--optimize-safety 3))) | 2102 | (= cl--optimize-safety 3))) |
| 2106 | form | 2103 | form |
| 2107 | (let* ((temp (if (cl--simple-expr-p form 3) | 2104 | (macroexp-let2 macroexp-copyable-p temp form |
| 2108 | form (make-symbol "--cl-var--"))) | 2105 | `(progn (unless (cl-typep ,temp ',type) |
| 2109 | (body `(progn (unless ,(cl--make-type-test temp type) | 2106 | (signal 'wrong-type-argument |
| 2110 | (signal 'wrong-type-argument | 2107 | (list ',type ,temp ',form))) |
| 2111 | (list ',type ,temp ',form))) | 2108 | ,temp)))) |
| 2112 | ,temp))) | ||
| 2113 | (if (eq temp form) body | ||
| 2114 | `(let ((,temp ,form)) ,body))))) | ||
| 2115 | 2109 | ||
| 2116 | (defvar cl--proclaim-history t) ; for future compilers | 2110 | (defvar cl--proclaim-history t) ; for future compilers |
| 2117 | (defvar cl--declare-stack t) ; for future compilers | 2111 | (defvar cl--declare-stack t) ; for future compilers |
| @@ -2425,15 +2419,11 @@ non-nil value, that slot cannot be set via `setf'. | |||
| 2425 | (tag (intern (format "cl-struct-%s" name))) | 2419 | (tag (intern (format "cl-struct-%s" name))) |
| 2426 | (tag-symbol (intern (format "cl-struct-%s-tags" name))) | 2420 | (tag-symbol (intern (format "cl-struct-%s-tags" name))) |
| 2427 | (include-descs nil) | 2421 | (include-descs nil) |
| 2428 | (side-eff nil) | ||
| 2429 | (type nil) | 2422 | (type nil) |
| 2430 | (named nil) | 2423 | (named nil) |
| 2431 | (forms nil) | 2424 | (forms nil) |
| 2425 | (docstring (if (stringp (car descs)) (pop descs))) | ||
| 2432 | pred-form pred-check) | 2426 | pred-form pred-check) |
| 2433 | (if (stringp (car descs)) | ||
| 2434 | (push `(put ',name 'structure-documentation | ||
| 2435 | ,(pop descs)) | ||
| 2436 | forms)) | ||
| 2437 | (setq descs (cons '(cl-tag-slot) | 2427 | (setq descs (cons '(cl-tag-slot) |
| 2438 | (mapcar (function (lambda (x) (if (consp x) x (list x)))) | 2428 | (mapcar (function (lambda (x) (if (consp x) x (list x)))) |
| 2439 | descs))) | 2429 | descs))) |
| @@ -2458,6 +2448,7 @@ non-nil value, that slot cannot be set via `setf'. | |||
| 2458 | ((eq opt :predicate) | 2448 | ((eq opt :predicate) |
| 2459 | (if args (setq predicate (car args)))) | 2449 | (if args (setq predicate (car args)))) |
| 2460 | ((eq opt :include) | 2450 | ((eq opt :include) |
| 2451 | (when include (error "Can't :include more than once")) | ||
| 2461 | (setq include (car args) | 2452 | (setq include (car args) |
| 2462 | include-descs (mapcar (function | 2453 | include-descs (mapcar (function |
| 2463 | (lambda (x) | 2454 | (lambda (x) |
| @@ -2511,20 +2502,19 @@ non-nil value, that slot cannot be set via `setf'. | |||
| 2511 | (if named (setq tag name))) | 2502 | (if named (setq tag name))) |
| 2512 | (setq type 'vector named 'true))) | 2503 | (setq type 'vector named 'true))) |
| 2513 | (or named (setq descs (delq (assq 'cl-tag-slot descs) descs))) | 2504 | (or named (setq descs (delq (assq 'cl-tag-slot descs) descs))) |
| 2514 | (push `(defvar ,tag-symbol) forms) | ||
| 2515 | (when (and (null predicate) named) | 2505 | (when (and (null predicate) named) |
| 2516 | (setq predicate (intern (format "cl--struct-%s-p" name)))) | 2506 | (setq predicate (intern (format "cl--struct-%s-p" name)))) |
| 2517 | (setq pred-form (and named | 2507 | (setq pred-form (and named |
| 2518 | (let ((pos (- (length descs) | 2508 | (let ((pos (- (length descs) |
| 2519 | (length (memq (assq 'cl-tag-slot descs) | 2509 | (length (memq (assq 'cl-tag-slot descs) |
| 2520 | descs))))) | 2510 | descs))))) |
| 2521 | (if (eq type 'vector) | 2511 | (cond |
| 2522 | `(and (vectorp cl-x) | 2512 | ((eq type 'vector) |
| 2523 | (>= (length cl-x) ,(length descs)) | 2513 | `(and (vectorp cl-x) |
| 2524 | (memq (aref cl-x ,pos) ,tag-symbol)) | 2514 | (>= (length cl-x) ,(length descs)) |
| 2525 | (if (= pos 0) | 2515 | (memq (aref cl-x ,pos) ,tag-symbol))) |
| 2526 | `(memq (car-safe cl-x) ,tag-symbol) | 2516 | ((= pos 0) `(memq (car-safe cl-x) ,tag-symbol)) |
| 2527 | `(and (consp cl-x) | 2517 | (t `(and (consp cl-x) |
| 2528 | (memq (nth ,pos cl-x) ,tag-symbol)))))) | 2518 | (memq (nth ,pos cl-x) ,tag-symbol)))))) |
| 2529 | pred-check (and pred-form (> safety 0) | 2519 | pred-check (and pred-form (> safety 0) |
| 2530 | (if (and (eq (cl-caadr pred-form) 'vectorp) | 2520 | (if (and (eq (cl-caadr pred-form) 'vectorp) |
| @@ -2546,6 +2536,7 @@ non-nil value, that slot cannot be set via `setf'. | |||
| 2546 | (push slot slots) | 2536 | (push slot slots) |
| 2547 | (push (nth 1 desc) defaults) | 2537 | (push (nth 1 desc) defaults) |
| 2548 | (push `(cl-defsubst ,accessor (cl-x) | 2538 | (push `(cl-defsubst ,accessor (cl-x) |
| 2539 | (declare (side-effect-free t)) | ||
| 2549 | ,@(and pred-check | 2540 | ,@(and pred-check |
| 2550 | (list `(or ,pred-check | 2541 | (list `(or ,pred-check |
| 2551 | (error "%s accessing a non-%s" | 2542 | (error "%s accessing a non-%s" |
| @@ -2554,7 +2545,6 @@ non-nil value, that slot cannot be set via `setf'. | |||
| 2554 | (if (= pos 0) '(car cl-x) | 2545 | (if (= pos 0) '(car cl-x) |
| 2555 | `(nth ,pos cl-x)))) | 2546 | `(nth ,pos cl-x)))) |
| 2556 | forms) | 2547 | forms) |
| 2557 | (push (cons accessor t) side-eff) | ||
| 2558 | (if (cadr (memq :read-only (cddr desc))) | 2548 | (if (cadr (memq :read-only (cddr desc))) |
| 2559 | (push `(gv-define-expander ,accessor | 2549 | (push `(gv-define-expander ,accessor |
| 2560 | (lambda (_cl-do _cl-x) | 2550 | (lambda (_cl-do _cl-x) |
| @@ -2587,15 +2577,14 @@ non-nil value, that slot cannot be set via `setf'. | |||
| 2587 | defaults (nreverse defaults)) | 2577 | defaults (nreverse defaults)) |
| 2588 | (when pred-form | 2578 | (when pred-form |
| 2589 | (push `(cl-defsubst ,predicate (cl-x) | 2579 | (push `(cl-defsubst ,predicate (cl-x) |
| 2580 | (declare (side-effect-free error-free)) | ||
| 2590 | ,(if (eq (car pred-form) 'and) | 2581 | ,(if (eq (car pred-form) 'and) |
| 2591 | (append pred-form '(t)) | 2582 | (append pred-form '(t)) |
| 2592 | `(and ,pred-form t))) | 2583 | `(and ,pred-form t))) |
| 2593 | forms) | 2584 | forms) |
| 2594 | (push `(put ',name 'cl-deftype-satisfies ',predicate) forms) | 2585 | (push `(put ',name 'cl-deftype-satisfies ',predicate) forms)) |
| 2595 | (push (cons predicate 'error-free) side-eff)) | ||
| 2596 | (and copier | 2586 | (and copier |
| 2597 | (progn (push `(defun ,copier (x) (copy-sequence x)) forms) | 2587 | (push `(defalias ',copier #'copy-sequence) forms)) |
| 2598 | (push (cons copier t) side-eff))) | ||
| 2599 | (if constructor | 2588 | (if constructor |
| 2600 | (push (list constructor | 2589 | (push (list constructor |
| 2601 | (cons '&key (delq nil (copy-sequence slots)))) | 2590 | (cons '&key (delq nil (copy-sequence slots)))) |
| @@ -2607,11 +2596,11 @@ non-nil value, that slot cannot be set via `setf'. | |||
| 2607 | (make (cl-mapcar (function (lambda (s d) (if (memq s anames) s d))) | 2596 | (make (cl-mapcar (function (lambda (s d) (if (memq s anames) s d))) |
| 2608 | slots defaults))) | 2597 | slots defaults))) |
| 2609 | (push `(cl-defsubst ,name | 2598 | (push `(cl-defsubst ,name |
| 2610 | (&cl-defs '(nil ,@descs) ,@args) | 2599 | (&cl-defs '(nil ,@descs) ,@args) |
| 2600 | ,@(if (cl--safe-expr-p `(progn ,@(mapcar #'cl-second descs))) | ||
| 2601 | '((declare (side-effect-free t)))) | ||
| 2611 | (,type ,@make)) | 2602 | (,type ,@make)) |
| 2612 | forms) | 2603 | forms))) |
| 2613 | (if (cl--safe-expr-p `(progn ,@(mapcar #'cl-second descs))) | ||
| 2614 | (push (cons name t) side-eff)))) | ||
| 2615 | (if print-auto (nconc print-func (list '(princ ")" cl-s) t))) | 2604 | (if print-auto (nconc print-func (list '(princ ")" cl-s) t))) |
| 2616 | ;; Don't bother adding to cl-custom-print-functions since it's not used | 2605 | ;; Don't bother adding to cl-custom-print-functions since it's not used |
| 2617 | ;; by anything anyway! | 2606 | ;; by anything anyway! |
| @@ -2624,17 +2613,14 @@ non-nil value, that slot cannot be set via `setf'. | |||
| 2624 | ;; (and ,pred-form ,print-func)) | 2613 | ;; (and ,pred-form ,print-func)) |
| 2625 | ;; cl-custom-print-functions)) | 2614 | ;; cl-custom-print-functions)) |
| 2626 | ;; forms)) | 2615 | ;; forms)) |
| 2627 | (push `(setq ,tag-symbol (list ',tag)) forms) | 2616 | `(progn |
| 2628 | (push `(cl-eval-when (compile load eval) | 2617 | (defvar ,tag-symbol) |
| 2629 | (put ',name 'cl-struct-slots ',descs) | 2618 | ,@(nreverse forms) |
| 2630 | (put ',name 'cl-struct-type ',(list type (eq named t))) | 2619 | (eval-and-compile |
| 2631 | (put ',name 'cl-struct-include ',include) | 2620 | (cl-struct-define ',name ,docstring ',include |
| 2632 | (put ',name 'cl-struct-print ,print-auto) | 2621 | ',type ,(eq named t) ',descs ',tag-symbol ',tag |
| 2633 | ,@(mapcar (lambda (x) | 2622 | ',print-auto)) |
| 2634 | `(function-put ',(car x) 'side-effect-free ',(cdr x))) | 2623 | ',name))) |
| 2635 | side-eff)) | ||
| 2636 | forms) | ||
| 2637 | `(progn ,@(nreverse (cons `',name forms))))) | ||
| 2638 | 2624 | ||
| 2639 | (defun cl-struct-sequence-type (struct-type) | 2625 | (defun cl-struct-sequence-type (struct-type) |
| 2640 | "Return the sequence used to build STRUCT-TYPE. | 2626 | "Return the sequence used to build STRUCT-TYPE. |
| @@ -2741,14 +2727,11 @@ STRING is an optional description of the desired type." | |||
| 2741 | (declare (debug (place cl-type-spec &optional stringp))) | 2727 | (declare (debug (place cl-type-spec &optional stringp))) |
| 2742 | (and (or (not (cl--compiling-file)) | 2728 | (and (or (not (cl--compiling-file)) |
| 2743 | (< cl--optimize-speed 3) (= cl--optimize-safety 3)) | 2729 | (< cl--optimize-speed 3) (= cl--optimize-safety 3)) |
| 2744 | (let* ((temp (if (cl--simple-expr-p form 3) | 2730 | (macroexp-let2 macroexp-copyable-p temp form |
| 2745 | form (make-symbol "--cl-var--"))) | 2731 | `(progn (or (cl-typep ,temp ',type) |
| 2746 | (body `(or ,(cl--make-type-test temp type) | 2732 | (signal 'wrong-type-argument |
| 2747 | (signal 'wrong-type-argument | 2733 | (list ,(or string `',type) ,temp ',form))) |
| 2748 | (list ,(or string `',type) | 2734 | nil)))) |
| 2749 | ,temp ',form))))) | ||
| 2750 | (if (eq temp form) `(progn ,body nil) | ||
| 2751 | `(let ((,temp ,form)) ,body nil))))) | ||
| 2752 | 2735 | ||
| 2753 | ;;;###autoload | 2736 | ;;;###autoload |
| 2754 | (defmacro cl-assert (form &optional show-args string &rest args) | 2737 | (defmacro cl-assert (form &optional show-args string &rest args) |
diff --git a/lisp/emacs-lisp/cl-preloaded.el b/lisp/emacs-lisp/cl-preloaded.el new file mode 100644 index 00000000000..c9867b412a1 --- /dev/null +++ b/lisp/emacs-lisp/cl-preloaded.el | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | ;;; cl-preloaded.el --- Preloaded part of the CL library -*- lexical-binding: t; -*- | ||
| 2 | |||
| 3 | ;; Copyright (C) 2015 Free Software Foundation, Inc | ||
| 4 | |||
| 5 | ;; Author: Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 6 | |||
| 7 | ;; This file is part of GNU Emacs. | ||
| 8 | |||
| 9 | ;; GNU Emacs is free software: you can redistribute it and/or modify | ||
| 10 | ;; it under the terms of the GNU General Public License as published by | ||
| 11 | ;; the Free Software Foundation, either version 3 of the License, or | ||
| 12 | ;; (at your option) any later version. | ||
| 13 | |||
| 14 | ;; GNU Emacs is distributed in the hope that it will be useful, | ||
| 15 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 17 | ;; GNU General Public License for more details. | ||
| 18 | |||
| 19 | ;; You should have received a copy of the GNU General Public License | ||
| 20 | ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | ||
| 21 | |||
| 22 | ;;; Commentary: | ||
| 23 | |||
| 24 | ;; The expectation is that structs defined with cl-defstruct do not | ||
| 25 | ;; need cl-lib at run-time, but we'd like to hide the details of the | ||
| 26 | ;; cl-struct metadata behind the cl-struct-define function, so we put | ||
| 27 | ;; it in this pre-loaded file. | ||
| 28 | |||
| 29 | ;;; Code: | ||
| 30 | |||
| 31 | (defun cl-struct-define (name docstring parent type named slots children-sym | ||
| 32 | tag print-auto) | ||
| 33 | (if (boundp children-sym) | ||
| 34 | (add-to-list children-sym tag) | ||
| 35 | (set children-sym (list tag))) | ||
| 36 | ;; If the cl-generic support, we need to be able to check | ||
| 37 | ;; if a vector is a cl-struct object, without knowing its particular type. | ||
| 38 | ;; So we use the (otherwise) unused function slots of the tag symbol | ||
| 39 | ;; to put a special witness value, to make the check easy and reliable. | ||
| 40 | (unless named (fset tag :quick-object-witness-check)) | ||
| 41 | (put name 'cl-struct-slots slots) | ||
| 42 | (put name 'cl-struct-type (list type named)) | ||
| 43 | (if parent (put name 'cl-struct-include parent)) | ||
| 44 | (if print-auto (put name 'cl-struct-print print-auto)) | ||
| 45 | (if docstring (put name 'structure-documentation docstring))) | ||
| 46 | |||
| 47 | (provide 'cl-preloaded) | ||
| 48 | ;;; cl-preloaded.el ends here | ||
diff --git a/lisp/emacs-lisp/cl.el b/lisp/emacs-lisp/cl.el index 1cd7bd76b0e..5da1cea6bb3 100644 --- a/lisp/emacs-lisp/cl.el +++ b/lisp/emacs-lisp/cl.el | |||
| @@ -376,7 +376,6 @@ The two cases that are handled are: | |||
| 376 | (setq cl--function-convert-cache (cons newf res)) | 376 | (setq cl--function-convert-cache (cons newf res)) |
| 377 | res)))) | 377 | res)))) |
| 378 | (t | 378 | (t |
| 379 | (setq cl--labels-convert-cache cl--function-convert-cache) | ||
| 380 | (cl--labels-convert f)))) | 379 | (cl--labels-convert f)))) |
| 381 | 380 | ||
| 382 | (defmacro lexical-let (bindings &rest body) | 381 | (defmacro lexical-let (bindings &rest body) |
diff --git a/lisp/emacs-lisp/easy-mmode.el b/lisp/emacs-lisp/easy-mmode.el index 7e6f56518a2..f7e8619948a 100644 --- a/lisp/emacs-lisp/easy-mmode.el +++ b/lisp/emacs-lisp/easy-mmode.el | |||
| @@ -149,11 +149,12 @@ For example, you could write | |||
| 149 | ...BODY CODE...)" | 149 | ...BODY CODE...)" |
| 150 | (declare (doc-string 2) | 150 | (declare (doc-string 2) |
| 151 | (debug (&define name string-or-null-p | 151 | (debug (&define name string-or-null-p |
| 152 | [&optional [¬ keywordp] sexp | 152 | [&optional [¬ keywordp] sexp |
| 153 | &optional [¬ keywordp] sexp | 153 | &optional [¬ keywordp] sexp |
| 154 | &optional [¬ keywordp] sexp] | 154 | &optional [¬ keywordp] sexp] |
| 155 | [&rest [keywordp sexp]] | 155 | [&rest [keywordp sexp]] |
| 156 | def-body))) | 156 | def-body)) |
| 157 | (indent 1)) | ||
| 157 | 158 | ||
| 158 | ;; Allow skipping the first three args. | 159 | ;; Allow skipping the first three args. |
| 159 | (cond | 160 | (cond |
diff --git a/lisp/emacs-lisp/eieio-base.el b/lisp/emacs-lisp/eieio-base.el index feb06711cb3..46585ee76c6 100644 --- a/lisp/emacs-lisp/eieio-base.el +++ b/lisp/emacs-lisp/eieio-base.el | |||
| @@ -219,7 +219,7 @@ for CLASS. Optional ALLOW-SUBCLASS says that it is ok for | |||
| 219 | being pedantic." | 219 | being pedantic." |
| 220 | (unless class | 220 | (unless class |
| 221 | (message "Unsafe call to `eieio-persistent-read'.")) | 221 | (message "Unsafe call to `eieio-persistent-read'.")) |
| 222 | (when class (eieio--check-type class-p class)) | 222 | (when class (cl-check-type class class)) |
| 223 | (let ((ret nil) | 223 | (let ((ret nil) |
| 224 | (buffstr nil)) | 224 | (buffstr nil)) |
| 225 | (unwind-protect | 225 | (unwind-protect |
| @@ -481,7 +481,7 @@ instance." | |||
| 481 | 481 | ||
| 482 | (cl-defmethod eieio-object-set-name-string ((obj eieio-named) name) | 482 | (cl-defmethod eieio-object-set-name-string ((obj eieio-named) name) |
| 483 | "Set the string which is OBJ's NAME." | 483 | "Set the string which is OBJ's NAME." |
| 484 | (eieio--check-type stringp name) | 484 | (cl-check-type name string) |
| 485 | (eieio-oset obj 'object-name name)) | 485 | (eieio-oset obj 'object-name name)) |
| 486 | 486 | ||
| 487 | (cl-defmethod clone ((obj eieio-named) &rest params) | 487 | (cl-defmethod clone ((obj eieio-named) &rest params) |
diff --git a/lisp/emacs-lisp/eieio-core.el b/lisp/emacs-lisp/eieio-core.el index 7492f0522ab..77d8c01388b 100644 --- a/lisp/emacs-lisp/eieio-core.el +++ b/lisp/emacs-lisp/eieio-core.el | |||
| @@ -40,6 +40,8 @@ | |||
| 40 | (declare-function slot-unbound "eieio") | 40 | (declare-function slot-unbound "eieio") |
| 41 | (declare-function slot-missing "eieio") | 41 | (declare-function slot-missing "eieio") |
| 42 | (declare-function child-of-class-p "eieio") | 42 | (declare-function child-of-class-p "eieio") |
| 43 | (declare-function same-class-p "eieio") | ||
| 44 | (declare-function object-of-class-p "eieio") | ||
| 43 | 45 | ||
| 44 | 46 | ||
| 45 | ;;; | 47 | ;;; |
| @@ -154,15 +156,6 @@ Currently under control of this var: | |||
| 154 | 156 | ||
| 155 | 157 | ||
| 156 | ;;; Important macros used internally in eieio. | 158 | ;;; Important macros used internally in eieio. |
| 157 | ;; | ||
| 158 | (defmacro eieio--check-type (type obj) | ||
| 159 | (unless (symbolp obj) | ||
| 160 | (error "eieio--check-type wants OBJ to be a variable")) | ||
| 161 | `(if (not ,(cond | ||
| 162 | ((eq 'or (car-safe type)) | ||
| 163 | `(or ,@(mapcar (lambda (type) `(,type ,obj)) (cdr type)))) | ||
| 164 | (t `(,type ,obj)))) | ||
| 165 | (signal 'wrong-type-argument (list ',type ,obj)))) | ||
| 166 | 159 | ||
| 167 | (defmacro eieio--class-v (class) ;Use a macro, so it acts as a GV place. | 160 | (defmacro eieio--class-v (class) ;Use a macro, so it acts as a GV place. |
| 168 | "Internal: Return the class vector from the CLASS symbol." | 161 | "Internal: Return the class vector from the CLASS symbol." |
| @@ -183,27 +176,17 @@ Currently under control of this var: | |||
| 183 | (eq (aref class 0) 'defclass) | 176 | (eq (aref class 0) 'defclass) |
| 184 | (error nil))) | 177 | (error nil))) |
| 185 | 178 | ||
| 186 | (defsubst eieio-class-object (class) | 179 | (defun class-p (class) |
| 187 | "Check that CLASS is a class and return the corresponding object." | ||
| 188 | (let ((c (eieio--class-object class))) | ||
| 189 | (eieio--check-type eieio--class-p c) | ||
| 190 | c)) | ||
| 191 | |||
| 192 | (defsubst class-p (class) | ||
| 193 | "Return non-nil if CLASS is a valid class vector. | 180 | "Return non-nil if CLASS is a valid class vector. |
| 194 | CLASS is a symbol." ;FIXME: Is it a vector or a symbol? | 181 | CLASS is a symbol." ;FIXME: Is it a vector or a symbol? |
| 195 | ;; this new method is faster since it doesn't waste time checking lots of | 182 | (and (symbolp class) (eieio--class-p (eieio--class-v class)))) |
| 196 | ;; things. | ||
| 197 | (condition-case nil | ||
| 198 | (eq (aref (eieio--class-v class) 0) 'defclass) | ||
| 199 | (error nil))) | ||
| 200 | 183 | ||
| 201 | (defun eieio-class-name (class) | 184 | (defun eieio-class-name (class) |
| 202 | "Return a Lisp like symbol name for CLASS." | 185 | "Return a Lisp like symbol name for CLASS." |
| 203 | ;; FIXME: What's a "Lisp like symbol name"? | 186 | ;; FIXME: What's a "Lisp like symbol name"? |
| 204 | ;; FIXME: CLOS returns a symbol, but the code returns a string. | 187 | ;; FIXME: CLOS returns a symbol, but the code returns a string. |
| 205 | (if (eieio--class-p class) (setq class (eieio--class-symbol class))) | 188 | (if (eieio--class-p class) (setq class (eieio--class-symbol class))) |
| 206 | (eieio--check-type class-p class) | 189 | (cl-check-type class class) |
| 207 | ;; I think this is supposed to return a symbol, but to me CLASS is a symbol, | 190 | ;; I think this is supposed to return a symbol, but to me CLASS is a symbol, |
| 208 | ;; and I wanted a string. Arg! | 191 | ;; and I wanted a string. Arg! |
| 209 | (format "#<class %s>" (symbol-name class))) | 192 | (format "#<class %s>" (symbol-name class))) |
| @@ -221,14 +204,17 @@ CLASS is a symbol." ;FIXME: Is it a vector or a symbol? | |||
| 221 | Return nil if that option doesn't exist." | 204 | Return nil if that option doesn't exist." |
| 222 | (eieio--class-option-assoc (eieio--class-options class) option)) | 205 | (eieio--class-option-assoc (eieio--class-options class) option)) |
| 223 | 206 | ||
| 224 | (defsubst eieio-object-p (obj) | 207 | (defun eieio-object-p (obj) |
| 225 | "Return non-nil if OBJ is an EIEIO object." | 208 | "Return non-nil if OBJ is an EIEIO object." |
| 226 | (and (vectorp obj) | 209 | (and (vectorp obj) |
| 227 | (condition-case nil | 210 | (> (length obj) 0) |
| 228 | (eq (aref (eieio--object-class-object obj) 0) 'defclass) | 211 | (let ((tag (eieio--object-class-tag obj))) |
| 229 | (error nil)))) | 212 | (and (symbolp tag) |
| 213 | ;; (eq (symbol-function tag) :quick-object-witness-check) | ||
| 214 | (boundp tag) | ||
| 215 | (eieio--class-p (symbol-value tag)))))) | ||
| 230 | 216 | ||
| 231 | (defalias 'object-p 'eieio-object-p) | 217 | (define-obsolete-function-alias 'object-p 'eieio-object-p "25.1") |
| 232 | 218 | ||
| 233 | (defsubst class-abstract-p (class) | 219 | (defsubst class-abstract-p (class) |
| 234 | "Return non-nil if CLASS is abstract. | 220 | "Return non-nil if CLASS is abstract. |
| @@ -266,10 +252,9 @@ It creates an autoload function for CNAME's constructor." | |||
| 266 | ;; simply not exist yet. So instead we just don't store the list of parents | 252 | ;; simply not exist yet. So instead we just don't store the list of parents |
| 267 | ;; here in eieio-defclass-autoload at all, since it seems that they're just | 253 | ;; here in eieio-defclass-autoload at all, since it seems that they're just |
| 268 | ;; not needed before the class is actually loaded. | 254 | ;; not needed before the class is actually loaded. |
| 269 | (let* ((oldc (when (class-p cname) (eieio--class-v cname))) | 255 | (let* ((oldc (eieio--class-v cname)) |
| 270 | (newc (eieio--class-make cname)) | 256 | (newc (eieio--class-make cname))) |
| 271 | ) | 257 | (if (eieio--class-p oldc) |
| 272 | (if oldc | ||
| 273 | nil ;; Do nothing if we already have this class. | 258 | nil ;; Do nothing if we already have this class. |
| 274 | 259 | ||
| 275 | ;; turn this into a usable self-pointing symbol | 260 | ;; turn this into a usable self-pointing symbol |
| @@ -300,7 +285,21 @@ It creates an autoload function for CNAME's constructor." | |||
| 300 | (cl-every (lambda (elem) (cl-typep elem ',elem-type)) | 285 | (cl-every (lambda (elem) (cl-typep elem ',elem-type)) |
| 301 | list))))) | 286 | list))))) |
| 302 | 287 | ||
| 303 | (declare-function eieio--defmethod "eieio-generic" (method kind argclass code)) | 288 | |
| 289 | (defun eieio-make-class-predicate (class) | ||
| 290 | (lambda (obj) | ||
| 291 | ;; (:docstring (format "Test OBJ to see if it's an object of type %S." | ||
| 292 | ;; class)) | ||
| 293 | (and (eieio-object-p obj) | ||
| 294 | (same-class-p obj class)))) | ||
| 295 | |||
| 296 | (defun eieio-make-child-predicate (class) | ||
| 297 | (lambda (obj) | ||
| 298 | ;; (:docstring (format | ||
| 299 | ;; "Test OBJ to see if it's an object is a child of type %S." | ||
| 300 | ;; class)) | ||
| 301 | (and (eieio-object-p obj) | ||
| 302 | (object-of-class-p obj class)))) | ||
| 304 | 303 | ||
| 305 | (defun eieio-defclass-internal (cname superclasses slots options) | 304 | (defun eieio-defclass-internal (cname superclasses slots options) |
| 306 | "Define CNAME as a new subclass of SUPERCLASSES. | 305 | "Define CNAME as a new subclass of SUPERCLASSES. |
| @@ -314,7 +313,7 @@ See `defclass' for more information." | |||
| 314 | (setq eieio-hook nil) | 313 | (setq eieio-hook nil) |
| 315 | 314 | ||
| 316 | (let* ((pname superclasses) | 315 | (let* ((pname superclasses) |
| 317 | (oldc (when (class-p cname) (eieio--class-v cname))) | 316 | (oldc (let ((c (eieio--class-v cname))) (if (eieio--class-p c) c))) |
| 318 | (newc (if (and oldc (not (eieio--class-default-object-cache oldc))) | 317 | (newc (if (and oldc (not (eieio--class-default-object-cache oldc))) |
| 319 | ;; The oldc class is a stub setup by eieio-defclass-autoload. | 318 | ;; The oldc class is a stub setup by eieio-defclass-autoload. |
| 320 | ;; Reuse it instead of creating a new one, so that existing | 319 | ;; Reuse it instead of creating a new one, so that existing |
| @@ -342,19 +341,20 @@ See `defclass' for more information." | |||
| 342 | (if pname | 341 | (if pname |
| 343 | (progn | 342 | (progn |
| 344 | (dolist (p pname) | 343 | (dolist (p pname) |
| 345 | (if (and p (symbolp p)) | 344 | (if (not (and p (symbolp p))) |
| 346 | (if (not (class-p p)) | 345 | (error "Invalid parent class %S" p) |
| 346 | (let ((c (eieio--class-v p))) | ||
| 347 | (if (not (eieio--class-p c)) | ||
| 347 | ;; bad class | 348 | ;; bad class |
| 348 | (error "Given parent class %S is not a class" p) | 349 | (error "Given parent class %S is not a class" p) |
| 349 | ;; good parent class... | 350 | ;; good parent class... |
| 350 | ;; save new child in parent | 351 | ;; save new child in parent |
| 351 | (cl-pushnew cname (eieio--class-children (eieio--class-v p))) | 352 | (cl-pushnew cname (eieio--class-children c)) |
| 352 | ;; Get custom groups, and store them into our local copy. | 353 | ;; Get custom groups, and store them into our local copy. |
| 353 | (mapc (lambda (g) (cl-pushnew g groups :test #'equal)) | 354 | (mapc (lambda (g) (cl-pushnew g groups :test #'equal)) |
| 354 | (eieio--class-option (eieio--class-v p) :custom-groups)) | 355 | (eieio--class-option c :custom-groups)) |
| 355 | ;; save parent in child | 356 | ;; Save parent in child. |
| 356 | (push (eieio--class-v p) (eieio--class-parent newc))) | 357 | (push c (eieio--class-parent newc)))))) |
| 357 | (error "Invalid parent class %S" p))) | ||
| 358 | ;; Reverse the list of our parents so that they are prioritized in | 358 | ;; Reverse the list of our parents so that they are prioritized in |
| 359 | ;; the same order as specified in the code. | 359 | ;; the same order as specified in the code. |
| 360 | (cl-callf nreverse (eieio--class-parent newc))) | 360 | (cl-callf nreverse (eieio--class-parent newc))) |
| @@ -506,13 +506,7 @@ See `defclass' for more information." | |||
| 506 | (eieio--class-option-assoc options :documentation)) | 506 | (eieio--class-option-assoc options :documentation)) |
| 507 | 507 | ||
| 508 | ;; Save the file location where this class is defined. | 508 | ;; Save the file location where this class is defined. |
| 509 | (let ((fname (if load-in-progress | 509 | (add-to-list 'current-load-list `(eieio-defclass . ,cname)) |
| 510 | load-file-name | ||
| 511 | buffer-file-name))) | ||
| 512 | (when fname | ||
| 513 | (when (string-match "\\.elc\\'" fname) | ||
| 514 | (setq fname (substring fname 0 (1- (length fname))))) | ||
| 515 | (put cname 'class-location fname))) | ||
| 516 | 510 | ||
| 517 | ;; We have a list of custom groups. Store them into the options. | 511 | ;; We have a list of custom groups. Store them into the options. |
| 518 | (let ((g (eieio--class-option-assoc options :custom-groups))) | 512 | (let ((g (eieio--class-option-assoc options :custom-groups))) |
| @@ -539,6 +533,7 @@ See `defclass' for more information." | |||
| 539 | ;; objects readable. | 533 | ;; objects readable. |
| 540 | (tag (intern (format "eieio-class-tag--%s" cname)))) | 534 | (tag (intern (format "eieio-class-tag--%s" cname)))) |
| 541 | (set tag newc) | 535 | (set tag newc) |
| 536 | (fset tag :quick-object-witness-check) | ||
| 542 | (setf (eieio--object-class-tag cache) tag) | 537 | (setf (eieio--object-class-tag cache) tag) |
| 543 | (let ((eieio-skip-typecheck t)) | 538 | (let ((eieio-skip-typecheck t)) |
| 544 | ;; All type-checking has been done to our satisfaction | 539 | ;; All type-checking has been done to our satisfaction |
| @@ -908,12 +903,13 @@ Argument FN is the function calling this verifier." | |||
| 908 | ;; | 903 | ;; |
| 909 | (defun eieio-oref (obj slot) | 904 | (defun eieio-oref (obj slot) |
| 910 | "Return the value in OBJ at SLOT in the object vector." | 905 | "Return the value in OBJ at SLOT in the object vector." |
| 911 | (eieio--check-type (or eieio-object-p class-p) obj) | 906 | (cl-check-type slot symbol) |
| 912 | (eieio--check-type symbolp slot) | 907 | (cl-check-type obj (or eieio-object class)) |
| 913 | (if (class-p obj) (eieio-class-un-autoload obj)) | ||
| 914 | (let* ((class (cond ((symbolp obj) | 908 | (let* ((class (cond ((symbolp obj) |
| 915 | (error "eieio-oref called on a class!") | 909 | (error "eieio-oref called on a class!") |
| 916 | (eieio--class-v obj)) | 910 | (let ((c (eieio--class-v obj))) |
| 911 | (if (eieio--class-p c) (eieio-class-un-autoload obj)) | ||
| 912 | c)) | ||
| 917 | (t (eieio--object-class-object obj)))) | 913 | (t (eieio--object-class-object obj)))) |
| 918 | (c (eieio--slot-name-index class obj slot))) | 914 | (c (eieio--slot-name-index class obj slot))) |
| 919 | (if (not c) | 915 | (if (not c) |
| @@ -928,15 +924,15 @@ Argument FN is the function calling this verifier." | |||
| 928 | (slot-missing obj slot 'oref) | 924 | (slot-missing obj slot 'oref) |
| 929 | ;;(signal 'invalid-slot-name (list (eieio-object-name obj) slot)) | 925 | ;;(signal 'invalid-slot-name (list (eieio-object-name obj) slot)) |
| 930 | ) | 926 | ) |
| 931 | (eieio--check-type eieio-object-p obj) | 927 | (cl-check-type obj eieio-object) |
| 932 | (eieio-barf-if-slot-unbound (aref obj c) obj slot 'oref)))) | 928 | (eieio-barf-if-slot-unbound (aref obj c) obj slot 'oref)))) |
| 933 | 929 | ||
| 934 | 930 | ||
| 935 | (defun eieio-oref-default (obj slot) | 931 | (defun eieio-oref-default (obj slot) |
| 936 | "Do the work for the macro `oref-default' with similar parameters. | 932 | "Do the work for the macro `oref-default' with similar parameters. |
| 937 | Fills in OBJ's SLOT with its default value." | 933 | Fills in OBJ's SLOT with its default value." |
| 938 | (eieio--check-type (or eieio-object-p class-p) obj) | 934 | (cl-check-type obj (or eieio-object class)) |
| 939 | (eieio--check-type symbolp slot) | 935 | (cl-check-type slot symbol) |
| 940 | (let* ((cl (cond ((symbolp obj) (eieio--class-v obj)) | 936 | (let* ((cl (cond ((symbolp obj) (eieio--class-v obj)) |
| 941 | (t (eieio--object-class-object obj)))) | 937 | (t (eieio--object-class-object obj)))) |
| 942 | (c (eieio--slot-name-index cl obj slot))) | 938 | (c (eieio--slot-name-index cl obj slot))) |
| @@ -974,8 +970,8 @@ Fills in OBJ's SLOT with its default value." | |||
| 974 | (defun eieio-oset (obj slot value) | 970 | (defun eieio-oset (obj slot value) |
| 975 | "Do the work for the macro `oset'. | 971 | "Do the work for the macro `oset'. |
| 976 | Fills in OBJ's SLOT with VALUE." | 972 | Fills in OBJ's SLOT with VALUE." |
| 977 | (eieio--check-type eieio-object-p obj) | 973 | (cl-check-type obj eieio-object) |
| 978 | (eieio--check-type symbolp slot) | 974 | (cl-check-type slot symbol) |
| 979 | (let* ((class (eieio--object-class-object obj)) | 975 | (let* ((class (eieio--object-class-object obj)) |
| 980 | (c (eieio--slot-name-index class obj slot))) | 976 | (c (eieio--slot-name-index class obj slot))) |
| 981 | (if (not c) | 977 | (if (not c) |
| @@ -999,8 +995,8 @@ Fills in OBJ's SLOT with VALUE." | |||
| 999 | "Do the work for the macro `oset-default'. | 995 | "Do the work for the macro `oset-default'. |
| 1000 | Fills in the default value in CLASS' in SLOT with VALUE." | 996 | Fills in the default value in CLASS' in SLOT with VALUE." |
| 1001 | (setq class (eieio--class-object class)) | 997 | (setq class (eieio--class-object class)) |
| 1002 | (eieio--check-type eieio--class-p class) | 998 | (cl-check-type class eieio--class) |
| 1003 | (eieio--check-type symbolp slot) | 999 | (cl-check-type slot symbol) |
| 1004 | (let* ((c (eieio--slot-name-index class nil slot))) | 1000 | (let* ((c (eieio--slot-name-index class nil slot))) |
| 1005 | (if (not c) | 1001 | (if (not c) |
| 1006 | ;; It might be missing because it is a :class allocated slot. | 1002 | ;; It might be missing because it is a :class allocated slot. |
| @@ -1222,10 +1218,11 @@ method invocation orders of the involved classes." | |||
| 1222 | ;; A class must be defined before it can be used as a parameter | 1218 | ;; A class must be defined before it can be used as a parameter |
| 1223 | ;; specializer in a defmethod form. | 1219 | ;; specializer in a defmethod form. |
| 1224 | ;; So we can ignore types that are not known to denote classes. | 1220 | ;; So we can ignore types that are not known to denote classes. |
| 1225 | (and (class-p type) | 1221 | (and (eieio--class-p (eieio--class-object type)) |
| 1226 | ;; Prefer (aref ,name 0) over (eieio--class-tag ,name) so that | 1222 | ;; Use the exact same code as for cl-struct, so that methods |
| 1227 | ;; the tagcode is identical to the tagcode used for cl-struct. | 1223 | ;; that dispatch on both kinds of objects get to share this |
| 1228 | `(50 . (and (vectorp ,name) (aref ,name 0))))) | 1224 | ;; part of the dispatch code. |
| 1225 | `(50 . ,(cl--generic-struct-tag name)))) | ||
| 1229 | 1226 | ||
| 1230 | (add-function :before-until cl-generic-tag-types-function | 1227 | (add-function :before-until cl-generic-tag-types-function |
| 1231 | #'eieio--generic-tag-types) | 1228 | #'eieio--generic-tag-types) |
diff --git a/lisp/emacs-lisp/eieio-datadebug.el b/lisp/emacs-lisp/eieio-datadebug.el index 119f7cce038..82349192e5e 100644 --- a/lisp/emacs-lisp/eieio-datadebug.el +++ b/lisp/emacs-lisp/eieio-datadebug.el | |||
| @@ -117,7 +117,7 @@ PREBUTTONTEXT is some text between PREFIX and the object button." | |||
| 117 | (setq publa (cdr publa))))))) | 117 | (setq publa (cdr publa))))))) |
| 118 | 118 | ||
| 119 | ;;; Augment the Data debug thing display list. | 119 | ;;; Augment the Data debug thing display list. |
| 120 | (data-debug-add-specialized-thing (lambda (thing) (object-p thing)) | 120 | (data-debug-add-specialized-thing (lambda (thing) (eieio-object-p thing)) |
| 121 | #'data-debug-insert-object-button) | 121 | #'data-debug-insert-object-button) |
| 122 | 122 | ||
| 123 | ;;; DEBUG METHODS | 123 | ;;; DEBUG METHODS |
diff --git a/lisp/emacs-lisp/eieio-opt.el b/lisp/emacs-lisp/eieio-opt.el index 8d40edf5624..304ee364dc8 100644 --- a/lisp/emacs-lisp/eieio-opt.el +++ b/lisp/emacs-lisp/eieio-opt.el | |||
| @@ -45,7 +45,7 @@ variable `eieio-default-superclass'." | |||
| 45 | nil t))) | 45 | nil t))) |
| 46 | nil)) | 46 | nil)) |
| 47 | (if (not root-class) (setq root-class 'eieio-default-superclass)) | 47 | (if (not root-class) (setq root-class 'eieio-default-superclass)) |
| 48 | (eieio--check-type class-p root-class) | 48 | (cl-check-type root-class class) |
| 49 | (display-buffer (get-buffer-create "*EIEIO OBJECT BROWSE*") t) | 49 | (display-buffer (get-buffer-create "*EIEIO OBJECT BROWSE*") t) |
| 50 | (with-current-buffer (get-buffer "*EIEIO OBJECT BROWSE*") | 50 | (with-current-buffer (get-buffer "*EIEIO OBJECT BROWSE*") |
| 51 | (erase-buffer) | 51 | (erase-buffer) |
| @@ -58,7 +58,7 @@ variable `eieio-default-superclass'." | |||
| 58 | Argument THIS-ROOT is the local root of the tree. | 58 | Argument THIS-ROOT is the local root of the tree. |
| 59 | Argument PREFIX is the character prefix to use. | 59 | Argument PREFIX is the character prefix to use. |
| 60 | Argument CH-PREFIX is another character prefix to display." | 60 | Argument CH-PREFIX is another character prefix to display." |
| 61 | (eieio--check-type class-p this-root) | 61 | (cl-check-type this-root class) |
| 62 | (let ((myname (symbol-name this-root)) | 62 | (let ((myname (symbol-name this-root)) |
| 63 | (chl (eieio--class-children (eieio--class-v this-root))) | 63 | (chl (eieio--class-children (eieio--class-v this-root))) |
| 64 | (fprefix (concat ch-prefix " +--")) | 64 | (fprefix (concat ch-prefix " +--")) |
| @@ -85,12 +85,12 @@ If CLASS is actually an object, then also display current values of that object. | |||
| 85 | "n abstract" | 85 | "n abstract" |
| 86 | "") | 86 | "") |
| 87 | " class") | 87 | " class") |
| 88 | (let ((location (get class 'class-location))) | 88 | (let ((location (find-lisp-object-file-name class 'eieio-defclass))) |
| 89 | (when location | 89 | (when location |
| 90 | (insert " in `") | 90 | (insert " in `") |
| 91 | (help-insert-xref-button | 91 | (help-insert-xref-button |
| 92 | (file-name-nondirectory location) | 92 | (help-fns-short-filename location) |
| 93 | 'eieio-class-def class location) | 93 | 'eieio-class-def class location 'eieio-defclass) |
| 94 | (insert "'"))) | 94 | (insert "'"))) |
| 95 | (insert ".\n") | 95 | (insert ".\n") |
| 96 | ;; Parents | 96 | ;; Parents |
| @@ -204,15 +204,6 @@ Outputs to the current buffer." | |||
| 204 | prot (cdr prot) | 204 | prot (cdr prot) |
| 205 | i (1+ i))))) | 205 | i (1+ i))))) |
| 206 | 206 | ||
| 207 | (defun eieio-build-class-list (class) | ||
| 208 | "Return a list of all classes that inherit from CLASS." | ||
| 209 | (if (class-p class) | ||
| 210 | (cl-mapcan | ||
| 211 | (lambda (c) | ||
| 212 | (append (list c) (eieio-build-class-list c))) | ||
| 213 | (eieio--class-children (eieio--class-v class))) | ||
| 214 | (list class))) | ||
| 215 | |||
| 216 | (defun eieio-build-class-alist (&optional class instantiable-only buildlist) | 207 | (defun eieio-build-class-alist (&optional class instantiable-only buildlist) |
| 217 | "Return an alist of all currently active classes for completion purposes. | 208 | "Return an alist of all currently active classes for completion purposes. |
| 218 | Optional argument CLASS is the class to start with. | 209 | Optional argument CLASS is the class to start with. |
| @@ -256,24 +247,22 @@ are not abstract." | |||
| 256 | 247 | ||
| 257 | ;;; METHOD COMPLETION / DOC | 248 | ;;; METHOD COMPLETION / DOC |
| 258 | 249 | ||
| 259 | (define-button-type 'eieio-method-def | ||
| 260 | :supertype 'help-xref | ||
| 261 | 'help-function (lambda (class method file) | ||
| 262 | (eieio-help-find-method-definition class method file)) | ||
| 263 | 'help-echo (purecopy "mouse-2, RET: find method's definition")) | ||
| 264 | |||
| 265 | (define-button-type 'eieio-class-def | 250 | (define-button-type 'eieio-class-def |
| 266 | :supertype 'help-xref | 251 | :supertype 'help-function-def |
| 267 | 'help-function (lambda (class file) | ||
| 268 | (eieio-help-find-class-definition class file)) | ||
| 269 | 'help-echo (purecopy "mouse-2, RET: find class definition")) | 252 | 'help-echo (purecopy "mouse-2, RET: find class definition")) |
| 270 | 253 | ||
| 254 | (defconst eieio--defclass-regexp "(defclass[ \t\r\n]+%s[ \t\r\n]+") | ||
| 255 | (with-eval-after-load 'find-func | ||
| 256 | (defvar find-function-regexp-alist) | ||
| 257 | (add-to-list 'find-function-regexp-alist | ||
| 258 | `(eieio-defclass . eieio--defclass-regexp))) | ||
| 259 | |||
| 271 | ;;;###autoload | 260 | ;;;###autoload |
| 272 | (defun eieio-help-constructor (ctr) | 261 | (defun eieio-help-constructor (ctr) |
| 273 | "Describe CTR if it is a class constructor." | 262 | "Describe CTR if it is a class constructor." |
| 274 | (when (class-p ctr) | 263 | (when (class-p ctr) |
| 275 | (erase-buffer) | 264 | (erase-buffer) |
| 276 | (let ((location (get ctr 'class-location)) | 265 | (let ((location (find-lisp-object-file-name ctr 'eieio-defclass)) |
| 277 | (def (symbol-function ctr))) | 266 | (def (symbol-function ctr))) |
| 278 | (goto-char (point-min)) | 267 | (goto-char (point-min)) |
| 279 | (prin1 ctr) | 268 | (prin1 ctr) |
| @@ -288,8 +277,8 @@ are not abstract." | |||
| 288 | (when location | 277 | (when location |
| 289 | (insert " in `") | 278 | (insert " in `") |
| 290 | (help-insert-xref-button | 279 | (help-insert-xref-button |
| 291 | (file-name-nondirectory location) | 280 | (help-fns-short-filename location) |
| 292 | 'eieio-class-def ctr location) | 281 | 'eieio-class-def ctr location 'eieio-defclass) |
| 293 | (insert "'")) | 282 | (insert "'")) |
| 294 | (insert ".\nCreates an object of class " (symbol-name ctr) ".") | 283 | (insert ".\nCreates an object of class " (symbol-name ctr) ".") |
| 295 | (goto-char (point-max)) | 284 | (goto-char (point-max)) |
| @@ -304,7 +293,7 @@ are not abstract." | |||
| 304 | "Return non-nil if a method with SPECIALIZERS applies to CLASS." | 293 | "Return non-nil if a method with SPECIALIZERS applies to CLASS." |
| 305 | (let ((applies nil)) | 294 | (let ((applies nil)) |
| 306 | (dolist (specializer specializers) | 295 | (dolist (specializer specializers) |
| 307 | (if (eq 'subclass (car-safe specializer)) | 296 | (if (memq (car-safe specializer) '(subclass eieio--static)) |
| 308 | (setq specializer (nth 1 specializer))) | 297 | (setq specializer (nth 1 specializer))) |
| 309 | ;; Don't include the methods that are "too generic", such as those | 298 | ;; Don't include the methods that are "too generic", such as those |
| 310 | ;; applying to `eieio-default-superclass'. | 299 | ;; applying to `eieio-default-superclass'. |
| @@ -443,60 +432,6 @@ The value returned is a list of elements of the form | |||
| 443 | (terpri) | 432 | (terpri) |
| 444 | )) | 433 | )) |
| 445 | 434 | ||
| 446 | ;;; HELP AUGMENTATION | ||
| 447 | ;; | ||
| 448 | (defun eieio-help-find-method-definition (class method file) | ||
| 449 | (let ((filename (find-library-name file)) | ||
| 450 | location buf) | ||
| 451 | (when (symbolp class) | ||
| 452 | (setq class (symbol-name class))) | ||
| 453 | (when (symbolp method) | ||
| 454 | (setq method (symbol-name method))) | ||
| 455 | (when (null filename) | ||
| 456 | (error "Cannot find library %s" file)) | ||
| 457 | (setq buf (find-file-noselect filename)) | ||
| 458 | (with-current-buffer buf | ||
| 459 | (goto-char (point-min)) | ||
| 460 | (when | ||
| 461 | (re-search-forward | ||
| 462 | ;; Regexp for searching methods. | ||
| 463 | (concat "(defmethod[ \t\r\n]+" method | ||
| 464 | "\\([ \t\r\n]+:[a-zA-Z]+\\)?" | ||
| 465 | "[ \t\r\n]+(\\s-*(\\(\\sw\\|\\s_\\)+\\s-+" | ||
| 466 | class | ||
| 467 | "\\s-*)") | ||
| 468 | nil t) | ||
| 469 | (setq location (match-beginning 0)))) | ||
| 470 | (if (null location) | ||
| 471 | (message "Unable to find location in file") | ||
| 472 | (pop-to-buffer buf) | ||
| 473 | (goto-char location) | ||
| 474 | (recenter) | ||
| 475 | (beginning-of-line)))) | ||
| 476 | |||
| 477 | (defun eieio-help-find-class-definition (class file) | ||
| 478 | (when (symbolp class) | ||
| 479 | (setq class (symbol-name class))) | ||
| 480 | (let ((filename (find-library-name file)) | ||
| 481 | location buf) | ||
| 482 | (when (null filename) | ||
| 483 | (error "Cannot find library %s" file)) | ||
| 484 | (setq buf (find-file-noselect filename)) | ||
| 485 | (with-current-buffer buf | ||
| 486 | (goto-char (point-min)) | ||
| 487 | (when | ||
| 488 | (re-search-forward | ||
| 489 | ;; Regexp for searching a class. | ||
| 490 | (concat "(defclass[ \t\r\n]+" class "[ \t\r\n]+") | ||
| 491 | nil t) | ||
| 492 | (setq location (match-beginning 0)))) | ||
| 493 | (if (null location) | ||
| 494 | (message "Unable to find location in file") | ||
| 495 | (pop-to-buffer buf) | ||
| 496 | (goto-char location) | ||
| 497 | (recenter) | ||
| 498 | (beginning-of-line)))) | ||
| 499 | |||
| 500 | ;;; SPEEDBAR SUPPORT | 435 | ;;; SPEEDBAR SUPPORT |
| 501 | ;; | 436 | ;; |
| 502 | 437 | ||
| @@ -546,7 +481,7 @@ current expansion depth." | |||
| 546 | 481 | ||
| 547 | (defun eieio-class-button (class depth) | 482 | (defun eieio-class-button (class depth) |
| 548 | "Draw a speedbar button at the current point for CLASS at DEPTH." | 483 | "Draw a speedbar button at the current point for CLASS at DEPTH." |
| 549 | (eieio--check-type class-p class) | 484 | (cl-check-type class class) |
| 550 | (let ((subclasses (eieio--class-children (eieio--class-v class)))) | 485 | (let ((subclasses (eieio--class-children (eieio--class-v class)))) |
| 551 | (if subclasses | 486 | (if subclasses |
| 552 | (speedbar-make-tag-line 'angle ?+ | 487 | (speedbar-make-tag-line 'angle ?+ |
diff --git a/lisp/emacs-lisp/eieio.el b/lisp/emacs-lisp/eieio.el index 91469b4b96c..526090954a9 100644 --- a/lisp/emacs-lisp/eieio.el +++ b/lisp/emacs-lisp/eieio.el | |||
| @@ -110,7 +110,7 @@ Options in CLOS not supported in EIEIO: | |||
| 110 | Due to the way class options are set up, you can add any tags you wish, | 110 | Due to the way class options are set up, you can add any tags you wish, |
| 111 | and reference them using the function `class-option'." | 111 | and reference them using the function `class-option'." |
| 112 | (declare (doc-string 4)) | 112 | (declare (doc-string 4)) |
| 113 | (eieio--check-type listp superclasses) | 113 | (cl-check-type superclasses list) |
| 114 | 114 | ||
| 115 | (cond ((and (stringp (car options-and-doc)) | 115 | (cond ((and (stringp (car options-and-doc)) |
| 116 | (/= 1 (% (length options-and-doc) 2))) | 116 | (/= 1 (% (length options-and-doc) 2))) |
| @@ -223,18 +223,9 @@ This method is obsolete." | |||
| 223 | ;; referencing classes. ei, a class whose slot can contain only | 223 | ;; referencing classes. ei, a class whose slot can contain only |
| 224 | ;; pointers to itself. | 224 | ;; pointers to itself. |
| 225 | 225 | ||
| 226 | ;; Create the test function. | 226 | ;; Create the test functions. |
| 227 | (defun ,testsym1 (obj) | 227 | (defalias ',testsym1 (eieio-make-class-predicate ',name)) |
| 228 | ,(format "Test OBJ to see if it an object of type %S." name) | 228 | (defalias ',testsym2 (eieio-make-child-predicate ',name)) |
| 229 | (and (eieio-object-p obj) | ||
| 230 | (same-class-p obj ',name))) | ||
| 231 | |||
| 232 | (defun ,testsym2 (obj) | ||
| 233 | ,(format | ||
| 234 | "Test OBJ to see if it an object is a child of type %S." | ||
| 235 | name) | ||
| 236 | (and (eieio-object-p obj) | ||
| 237 | (object-of-class-p obj ',name))) | ||
| 238 | 229 | ||
| 239 | ,@(when eieio-backward-compatibility | 230 | ,@(when eieio-backward-compatibility |
| 240 | (let ((f (intern (format "%s-child-p" name)))) | 231 | (let ((f (intern (format "%s-child-p" name)))) |
| @@ -374,7 +365,7 @@ variable name of the same name as the slot." | |||
| 374 | (defun eieio-object-name (obj &optional extra) | 365 | (defun eieio-object-name (obj &optional extra) |
| 375 | "Return a Lisp like symbol string for object OBJ. | 366 | "Return a Lisp like symbol string for object OBJ. |
| 376 | If EXTRA, include that in the string returned to represent the symbol." | 367 | If EXTRA, include that in the string returned to represent the symbol." |
| 377 | (eieio--check-type eieio-object-p obj) | 368 | (cl-check-type obj eieio-object) |
| 378 | (format "#<%s %s%s>" (eieio--object-class-name obj) | 369 | (format "#<%s %s%s>" (eieio--object-class-name obj) |
| 379 | (eieio-object-name-string obj) (or extra ""))) | 370 | (eieio-object-name-string obj) (or extra ""))) |
| 380 | (define-obsolete-function-alias 'object-name #'eieio-object-name "24.4") | 371 | (define-obsolete-function-alias 'object-name #'eieio-object-name "24.4") |
| @@ -394,7 +385,7 @@ If EXTRA, include that in the string returned to represent the symbol." | |||
| 394 | (cl-defmethod eieio-object-set-name-string (obj name) | 385 | (cl-defmethod eieio-object-set-name-string (obj name) |
| 395 | "Set the string which is OBJ's NAME." | 386 | "Set the string which is OBJ's NAME." |
| 396 | (declare (obsolete eieio-named "25.1")) | 387 | (declare (obsolete eieio-named "25.1")) |
| 397 | (eieio--check-type stringp name) | 388 | (cl-check-type name string) |
| 398 | (setf (gethash obj eieio--object-names) name)) | 389 | (setf (gethash obj eieio--object-names) name)) |
| 399 | (define-obsolete-function-alias | 390 | (define-obsolete-function-alias |
| 400 | 'object-set-name-string 'eieio-object-set-name-string "24.4") | 391 | 'object-set-name-string 'eieio-object-set-name-string "24.4") |
| @@ -402,7 +393,7 @@ If EXTRA, include that in the string returned to represent the symbol." | |||
| 402 | (defun eieio-object-class (obj) | 393 | (defun eieio-object-class (obj) |
| 403 | "Return the class struct defining OBJ." | 394 | "Return the class struct defining OBJ." |
| 404 | ;; FIXME: We say we return a "struct" but we return a symbol instead! | 395 | ;; FIXME: We say we return a "struct" but we return a symbol instead! |
| 405 | (eieio--check-type eieio-object-p obj) | 396 | (cl-check-type obj eieio-object) |
| 406 | (eieio--object-class-name obj)) | 397 | (eieio--object-class-name obj)) |
| 407 | (define-obsolete-function-alias 'object-class #'eieio-object-class "24.4") | 398 | (define-obsolete-function-alias 'object-class #'eieio-object-class "24.4") |
| 408 | ;; CLOS name, maybe? | 399 | ;; CLOS name, maybe? |
| @@ -410,7 +401,7 @@ If EXTRA, include that in the string returned to represent the symbol." | |||
| 410 | 401 | ||
| 411 | (defun eieio-object-class-name (obj) | 402 | (defun eieio-object-class-name (obj) |
| 412 | "Return a Lisp like symbol name for OBJ's class." | 403 | "Return a Lisp like symbol name for OBJ's class." |
| 413 | (eieio--check-type eieio-object-p obj) | 404 | (cl-check-type obj eieio-object) |
| 414 | (eieio-class-name (eieio--object-class-name obj))) | 405 | (eieio-class-name (eieio--object-class-name obj))) |
| 415 | (define-obsolete-function-alias | 406 | (define-obsolete-function-alias |
| 416 | 'object-class-name 'eieio-object-class-name "24.4") | 407 | 'object-class-name 'eieio-object-class-name "24.4") |
| @@ -419,15 +410,14 @@ If EXTRA, include that in the string returned to represent the symbol." | |||
| 419 | "Return parent classes to CLASS. (overload of variable). | 410 | "Return parent classes to CLASS. (overload of variable). |
| 420 | 411 | ||
| 421 | The CLOS function `class-direct-superclasses' is aliased to this function." | 412 | The CLOS function `class-direct-superclasses' is aliased to this function." |
| 422 | (let ((c (eieio-class-object class))) | 413 | (eieio--class-parent (eieio--class-object class))) |
| 423 | (eieio--class-parent c))) | ||
| 424 | 414 | ||
| 425 | (define-obsolete-function-alias 'class-parents #'eieio-class-parents "24.4") | 415 | (define-obsolete-function-alias 'class-parents #'eieio-class-parents "24.4") |
| 426 | 416 | ||
| 427 | (defun eieio-class-children (class) | 417 | (defun eieio-class-children (class) |
| 428 | "Return child classes to CLASS. | 418 | "Return child classes to CLASS. |
| 429 | The CLOS function `class-direct-subclasses' is aliased to this function." | 419 | The CLOS function `class-direct-subclasses' is aliased to this function." |
| 430 | (eieio--check-type class-p class) | 420 | (cl-check-type class class) |
| 431 | (eieio--class-children (eieio--class-v class))) | 421 | (eieio--class-children (eieio--class-v class))) |
| 432 | (define-obsolete-function-alias | 422 | (define-obsolete-function-alias |
| 433 | 'class-children #'eieio-class-children "24.4") | 423 | 'class-children #'eieio-class-children "24.4") |
| @@ -446,13 +436,13 @@ The CLOS function `class-direct-subclasses' is aliased to this function." | |||
| 446 | (defun same-class-p (obj class) | 436 | (defun same-class-p (obj class) |
| 447 | "Return t if OBJ is of class-type CLASS." | 437 | "Return t if OBJ is of class-type CLASS." |
| 448 | (setq class (eieio--class-object class)) | 438 | (setq class (eieio--class-object class)) |
| 449 | (eieio--check-type eieio--class-p class) | 439 | (cl-check-type class eieio--class) |
| 450 | (eieio--check-type eieio-object-p obj) | 440 | (cl-check-type obj eieio-object) |
| 451 | (eq (eieio--object-class-object obj) class)) | 441 | (eq (eieio--object-class-object obj) class)) |
| 452 | 442 | ||
| 453 | (defun object-of-class-p (obj class) | 443 | (defun object-of-class-p (obj class) |
| 454 | "Return non-nil if OBJ is an instance of CLASS or CLASS' subclasses." | 444 | "Return non-nil if OBJ is an instance of CLASS or CLASS' subclasses." |
| 455 | (eieio--check-type eieio-object-p obj) | 445 | (cl-check-type obj eieio-object) |
| 456 | ;; class will be checked one layer down | 446 | ;; class will be checked one layer down |
| 457 | (child-of-class-p (eieio--object-class-object obj) class)) | 447 | (child-of-class-p (eieio--object-class-object obj) class)) |
| 458 | ;; Backwards compatibility | 448 | ;; Backwards compatibility |
| @@ -461,13 +451,13 @@ The CLOS function `class-direct-subclasses' is aliased to this function." | |||
| 461 | (defun child-of-class-p (child class) | 451 | (defun child-of-class-p (child class) |
| 462 | "Return non-nil if CHILD class is a subclass of CLASS." | 452 | "Return non-nil if CHILD class is a subclass of CLASS." |
| 463 | (setq child (eieio--class-object child)) | 453 | (setq child (eieio--class-object child)) |
| 464 | (eieio--check-type eieio--class-p child) | 454 | (cl-check-type child eieio--class) |
| 465 | ;; `eieio-default-superclass' is never mentioned in eieio--class-parent, | 455 | ;; `eieio-default-superclass' is never mentioned in eieio--class-parent, |
| 466 | ;; so we have to special case it here. | 456 | ;; so we have to special case it here. |
| 467 | (or (eq class 'eieio-default-superclass) | 457 | (or (eq class 'eieio-default-superclass) |
| 468 | (let ((p nil)) | 458 | (let ((p nil)) |
| 469 | (setq class (eieio--class-object class)) | 459 | (setq class (eieio--class-object class)) |
| 470 | (eieio--check-type eieio--class-p class) | 460 | (cl-check-type class eieio--class) |
| 471 | (while (and child (not (eq child class))) | 461 | (while (and child (not (eq child class))) |
| 472 | (setq p (append p (eieio--class-parent child)) | 462 | (setq p (append p (eieio--class-parent child)) |
| 473 | child (pop p))) | 463 | child (pop p))) |
| @@ -475,11 +465,11 @@ The CLOS function `class-direct-subclasses' is aliased to this function." | |||
| 475 | 465 | ||
| 476 | (defun object-slots (obj) | 466 | (defun object-slots (obj) |
| 477 | "Return list of slots available in OBJ." | 467 | "Return list of slots available in OBJ." |
| 478 | (eieio--check-type eieio-object-p obj) | 468 | (cl-check-type obj eieio-object) |
| 479 | (eieio--class-public-a (eieio--object-class-object obj))) | 469 | (eieio--class-public-a (eieio--object-class-object obj))) |
| 480 | 470 | ||
| 481 | (defun eieio--class-slot-initarg (class slot) "Fetch from CLASS, SLOT's :initarg." | 471 | (defun eieio--class-slot-initarg (class slot) "Fetch from CLASS, SLOT's :initarg." |
| 482 | (eieio--check-type eieio--class-p class) | 472 | (cl-check-type class eieio--class) |
| 483 | (let ((ia (eieio--class-initarg-tuples class)) | 473 | (let ((ia (eieio--class-initarg-tuples class)) |
| 484 | (f nil)) | 474 | (f nil)) |
| 485 | (while (and ia (not f)) | 475 | (while (and ia (not f)) |
| @@ -517,7 +507,7 @@ OBJECT can be an instance or a class." | |||
| 517 | ;; Return nil if the magic symbol is in there. | 507 | ;; Return nil if the magic symbol is in there. |
| 518 | (not (eq (cond | 508 | (not (eq (cond |
| 519 | ((eieio-object-p object) (eieio-oref object slot)) | 509 | ((eieio-object-p object) (eieio-oref object slot)) |
| 520 | ((class-p object) (eieio-oref-default object slot)) | 510 | ((symbolp object) (eieio-oref-default object slot)) |
| 521 | (t (signal 'wrong-type-argument (list 'eieio-object-p object)))) | 511 | (t (signal 'wrong-type-argument (list 'eieio-object-p object)))) |
| 522 | eieio-unbound)))) | 512 | eieio-unbound)))) |
| 523 | 513 | ||
| @@ -529,7 +519,8 @@ OBJECT can be an instance or a class." | |||
| 529 | "Return non-nil if OBJECT-OR-CLASS has SLOT." | 519 | "Return non-nil if OBJECT-OR-CLASS has SLOT." |
| 530 | (let ((cv (cond ((eieio-object-p object-or-class) | 520 | (let ((cv (cond ((eieio-object-p object-or-class) |
| 531 | (eieio--object-class-object object-or-class)) | 521 | (eieio--object-class-object object-or-class)) |
| 532 | (t (eieio-class-object object-or-class))))) | 522 | ((eieio--class-p object-or-class) object-or-class) |
| 523 | (t (find-class object-or-class 'error))))) | ||
| 533 | (or (memq slot (eieio--class-public-a cv)) | 524 | (or (memq slot (eieio--class-public-a cv)) |
| 534 | (memq slot (eieio--class-class-allocation-a cv))) | 525 | (memq slot (eieio--class-class-allocation-a cv))) |
| 535 | )) | 526 | )) |
| @@ -538,10 +529,10 @@ OBJECT can be an instance or a class." | |||
| 538 | "Return the class that SYMBOL represents. | 529 | "Return the class that SYMBOL represents. |
| 539 | If there is no class, nil is returned if ERRORP is nil. | 530 | If there is no class, nil is returned if ERRORP is nil. |
| 540 | If ERRORP is non-nil, `wrong-argument-type' is signaled." | 531 | If ERRORP is non-nil, `wrong-argument-type' is signaled." |
| 541 | (if (not (class-p symbol)) | 532 | (let ((class (eieio--class-v symbol))) |
| 542 | (if errorp (signal 'wrong-type-argument (list 'class-p symbol)) | 533 | (cond |
| 543 | nil) | 534 | ((eieio--class-p class) class) |
| 544 | (eieio--class-v symbol))) | 535 | (errorp (signal 'wrong-type-argument (list 'class-p symbol)))))) |
| 545 | 536 | ||
| 546 | ;;; Slightly more complex utility functions for objects | 537 | ;;; Slightly more complex utility functions for objects |
| 547 | ;; | 538 | ;; |
| @@ -551,7 +542,7 @@ LIST is a list of objects whose slots are searched. | |||
| 551 | Objects in LIST do not need to have a slot named SLOT, nor does | 542 | Objects in LIST do not need to have a slot named SLOT, nor does |
| 552 | SLOT need to be bound. If these errors occur, those objects will | 543 | SLOT need to be bound. If these errors occur, those objects will |
| 553 | be ignored." | 544 | be ignored." |
| 554 | (eieio--check-type listp list) | 545 | (cl-check-type list list) |
| 555 | (while (and list (not (condition-case nil | 546 | (while (and list (not (condition-case nil |
| 556 | ;; This prevents errors for missing slots. | 547 | ;; This prevents errors for missing slots. |
| 557 | (equal key (eieio-oref (car list) slot)) | 548 | (equal key (eieio-oref (car list) slot)) |
| @@ -563,7 +554,7 @@ be ignored." | |||
| 563 | "Return an association list with the contents of SLOT as the key element. | 554 | "Return an association list with the contents of SLOT as the key element. |
| 564 | LIST must be a list of objects with SLOT in it. | 555 | LIST must be a list of objects with SLOT in it. |
| 565 | This is useful when you need to do completing read on an object group." | 556 | This is useful when you need to do completing read on an object group." |
| 566 | (eieio--check-type listp list) | 557 | (cl-check-type list list) |
| 567 | (let ((assoclist nil)) | 558 | (let ((assoclist nil)) |
| 568 | (while list | 559 | (while list |
| 569 | (setq assoclist (cons (cons (eieio-oref (car list) slot) | 560 | (setq assoclist (cons (cons (eieio-oref (car list) slot) |
| @@ -577,7 +568,7 @@ This is useful when you need to do completing read on an object group." | |||
| 577 | LIST must be a list of objects, but those objects do not need to have | 568 | LIST must be a list of objects, but those objects do not need to have |
| 578 | SLOT in it. If it does not, then that element is left out of the association | 569 | SLOT in it. If it does not, then that element is left out of the association |
| 579 | list." | 570 | list." |
| 580 | (eieio--check-type listp list) | 571 | (cl-check-type list list) |
| 581 | (let ((assoclist nil)) | 572 | (let ((assoclist nil)) |
| 582 | (while list | 573 | (while list |
| 583 | (if (slot-exists-p (car list) slot) | 574 | (if (slot-exists-p (car list) slot) |
| @@ -869,12 +860,8 @@ this object." | |||
| 869 | (object-write thing)) | 860 | (object-write thing)) |
| 870 | ((consp thing) | 861 | ((consp thing) |
| 871 | (eieio-list-prin1 thing)) | 862 | (eieio-list-prin1 thing)) |
| 872 | ((class-p thing) | 863 | ((eieio--class-p thing) |
| 873 | (princ (eieio-class-name thing))) | 864 | (princ (eieio-class-name thing))) |
| 874 | ((or (keywordp thing) (booleanp thing)) | ||
| 875 | (prin1 thing)) | ||
| 876 | ((symbolp thing) | ||
| 877 | (princ (concat "'" (symbol-name thing)))) | ||
| 878 | (t (prin1 thing)))) | 865 | (t (prin1 thing)))) |
| 879 | 866 | ||
| 880 | (defun eieio-list-prin1 (list) | 867 | (defun eieio-list-prin1 (list) |
| @@ -942,7 +929,7 @@ Optional argument GROUP is the sub-group of slots to display. | |||
| 942 | 929 | ||
| 943 | ;;;*** | 930 | ;;;*** |
| 944 | 931 | ||
| 945 | ;;;### (autoloads nil "eieio-opt" "eieio-opt.el" "b849f8bf1312d5ef57e53d02173e4b5a") | 932 | ;;;### (autoloads nil "eieio-opt" "eieio-opt.el" "ff1097f185bc2c253276a7d19fe2f54a") |
| 946 | ;;; Generated autoloads from eieio-opt.el | 933 | ;;; Generated autoloads from eieio-opt.el |
| 947 | 934 | ||
| 948 | (autoload 'eieio-browse "eieio-opt" "\ | 935 | (autoload 'eieio-browse "eieio-opt" "\ |
diff --git a/lisp/erc/ChangeLog b/lisp/erc/ChangeLog index 28ac7d38b96..44971cc16fc 100644 --- a/lisp/erc/ChangeLog +++ b/lisp/erc/ChangeLog | |||
| @@ -1,3 +1,8 @@ | |||
| 1 | 2015-01-28 Dima Kogan <dima@secretsauce.net> | ||
| 2 | |||
| 3 | * erc-backend.el (define-erc-response-handler): Give hook-name | ||
| 4 | default value of nil and add-to-list (bug#19363). | ||
| 5 | |||
| 1 | 2015-01-22 Paul Eggert <eggert@cs.ucla.edu> | 6 | 2015-01-22 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 7 | ||
| 3 | Don't downcase system diagnostics' first letters | 8 | Don't downcase system diagnostics' first letters |
diff --git a/lisp/erc/erc-backend.el b/lisp/erc/erc-backend.el index b8c67860e20..8ce199fbcbb 100644 --- a/lisp/erc/erc-backend.el +++ b/lisp/erc/erc-backend.el | |||
| @@ -1162,8 +1162,11 @@ add things to `%s' instead." | |||
| 1162 | (cl-loop for alias in aliases | 1162 | (cl-loop for alias in aliases |
| 1163 | collect (intern (format "erc-server-%s-functions" alias))))) | 1163 | collect (intern (format "erc-server-%s-functions" alias))))) |
| 1164 | `(prog2 | 1164 | `(prog2 |
| 1165 | ;; Normal hook variable. | 1165 | ;; Normal hook variable. The variable may already have a |
| 1166 | (defvar ,hook-name ',fn-name ,(format hook-doc name)) | 1166 | ;; value at this point, so I default to nil, and (add-hook) |
| 1167 | ;; unconditionally | ||
| 1168 | (defvar ,hook-name nil ,(format hook-doc name)) | ||
| 1169 | (add-to-list ',hook-name ',fn-name) | ||
| 1167 | ;; Handler function | 1170 | ;; Handler function |
| 1168 | (defun ,fn-name (proc parsed) | 1171 | (defun ,fn-name (proc parsed) |
| 1169 | ,fn-doc | 1172 | ,fn-doc |
diff --git a/lisp/filenotify.el b/lisp/filenotify.el index 35181b63f3a..c94f631dde8 100644 --- a/lisp/filenotify.el +++ b/lisp/filenotify.el | |||
| @@ -41,13 +41,21 @@ could use another implementation.") | |||
| 41 | "Hash table for registered file notification descriptors. | 41 | "Hash table for registered file notification descriptors. |
| 42 | A key in this hash table is the descriptor as returned from | 42 | A key in this hash table is the descriptor as returned from |
| 43 | `gfilenotify', `inotify', `w32notify' or a file name handler. | 43 | `gfilenotify', `inotify', `w32notify' or a file name handler. |
| 44 | The value in the hash table is the cons cell (DIR FILE CALLBACK).") | 44 | The value in the hash table is a list |
| 45 | |||
| 46 | \(DIR (FILE . CALLBACK) (FILE . CALLBACK) ...) | ||
| 47 | |||
| 48 | Several values for a given DIR happen only for `inotify', when | ||
| 49 | different files from the same directory are watched.") | ||
| 45 | 50 | ||
| 46 | ;; This function is used by `gfilenotify', `inotify' and `w32notify' events. | 51 | ;; This function is used by `gfilenotify', `inotify' and `w32notify' events. |
| 47 | ;;;###autoload | 52 | ;;;###autoload |
| 48 | (defun file-notify-handle-event (event) | 53 | (defun file-notify-handle-event (event) |
| 49 | "Handle file system monitoring event. | 54 | "Handle file system monitoring event. |
| 50 | If EVENT is a filewatch event, call its callback. | 55 | If EVENT is a filewatch event, call its callback. It has the format |
| 56 | |||
| 57 | \(file-notify (DESCRIPTOR ACTIONS FILE COOKIE) CALLBACK) | ||
| 58 | |||
| 51 | Otherwise, signal a `file-notify-error'." | 59 | Otherwise, signal a `file-notify-error'." |
| 52 | (interactive "e") | 60 | (interactive "e") |
| 53 | (if (and (eq (car event) 'file-notify) | 61 | (if (and (eq (car event) 'file-notify) |
| @@ -81,12 +89,23 @@ This is available in case a file has been moved." | |||
| 81 | This is available in case a file has been moved." | 89 | This is available in case a file has been moved." |
| 82 | (nth 3 event)) | 90 | (nth 3 event)) |
| 83 | 91 | ||
| 92 | ;; `inotify' returns the same descriptor when the file (directory) | ||
| 93 | ;; uses the same inode. We want to distinguish, and apply a virtual | ||
| 94 | ;; descriptor which make the difference. | ||
| 95 | (defun file-notify--descriptor (descriptor file) | ||
| 96 | "Return the descriptor to be used in `file-notify-*-watch'. | ||
| 97 | For `gfilenotify' and `w32notify' it is the same descriptor as | ||
| 98 | used in the low-level file notification package." | ||
| 99 | (if (and (natnump descriptor) (eq file-notify--library 'inotify)) | ||
| 100 | (cons descriptor file) | ||
| 101 | descriptor)) | ||
| 102 | |||
| 84 | ;; The callback function used to map between specific flags of the | 103 | ;; The callback function used to map between specific flags of the |
| 85 | ;; respective file notifications, and the ones we return. | 104 | ;; respective file notifications, and the ones we return. |
| 86 | (defun file-notify-callback (event) | 105 | (defun file-notify-callback (event) |
| 87 | "Handle an EVENT returned from file notification. | 106 | "Handle an EVENT returned from file notification. |
| 88 | EVENT is the same one as in `file-notify-handle-event' except the | 107 | EVENT is the cdr of the event in `file-notify-handle-event' |
| 89 | car of that event, which is the symbol `file-notify'." | 108 | \(DESCRIPTOR ACTIONS FILE COOKIE)." |
| 90 | (let* ((desc (car event)) | 109 | (let* ((desc (car event)) |
| 91 | (registered (gethash desc file-notify-descriptors)) | 110 | (registered (gethash desc file-notify-descriptors)) |
| 92 | (pending-event (assoc desc file-notify--pending-events)) | 111 | (pending-event (assoc desc file-notify--pending-events)) |
| @@ -97,99 +116,113 @@ car of that event, which is the symbol `file-notify'." | |||
| 97 | ;; Make actions a list. | 116 | ;; Make actions a list. |
| 98 | (unless (consp actions) (setq actions (cons actions nil))) | 117 | (unless (consp actions) (setq actions (cons actions nil))) |
| 99 | 118 | ||
| 100 | ;; Check, that event is meant for us. | 119 | ;; Loop over registered entries. In fact, more than one entry |
| 101 | (unless (setq callback (nth 2 registered)) | 120 | ;; happens only for `inotify'. |
| 102 | (setq actions nil)) | 121 | (dolist (entry (cdr registered)) |
| 103 | 122 | ||
| 104 | ;; Loop over actions. In fact, more than one action happens only | 123 | ;; Check, that event is meant for us. |
| 105 | ;; for `inotify'. | 124 | (unless (setq callback (cdr entry)) |
| 106 | (dolist (action actions) | 125 | (setq actions nil)) |
| 107 | 126 | ||
| 108 | ;; Send pending event, if it doesn't match. | 127 | ;; Loop over actions. In fact, more than one action happens only |
| 109 | (when (and pending-event | 128 | ;; for `inotify'. |
| 110 | ;; The cookie doesn't match. | 129 | (dolist (action actions) |
| 111 | (not (eq (file-notify--event-cookie pending-event) | 130 | |
| 112 | (file-notify--event-cookie event))) | 131 | ;; Send pending event, if it doesn't match. |
| 113 | (or | 132 | (when (and pending-event |
| 114 | ;; inotify. | 133 | ;; The cookie doesn't match. |
| 115 | (and (eq (nth 1 pending-event) 'moved-from) | 134 | (not (eq (file-notify--event-cookie pending-event) |
| 116 | (not (eq action 'moved-to))) | 135 | (file-notify--event-cookie event))) |
| 117 | ;; w32notify. | 136 | (or |
| 118 | (and (eq (nth 1 pending-event) 'renamed-from) | 137 | ;; inotify. |
| 119 | (not (eq action 'renamed-to))))) | 138 | (and (eq (nth 1 pending-event) 'moved-from) |
| 120 | (funcall callback | 139 | (not (eq action 'moved-to))) |
| 121 | (list desc 'deleted | 140 | ;; w32notify. |
| 122 | (file-notify--event-file-name pending-event))) | 141 | (and (eq (nth 1 pending-event) 'renamed-from) |
| 123 | (setq file-notify--pending-events | 142 | (not (eq action 'renamed-to))))) |
| 124 | (delete pending-event file-notify--pending-events))) | 143 | (funcall callback |
| 125 | 144 | (list desc 'deleted | |
| 126 | ;; Map action. We ignore all events which cannot be mapped. | 145 | (file-notify--event-file-name pending-event))) |
| 127 | (setq action | 146 | (setq file-notify--pending-events |
| 128 | (cond | 147 | (delete pending-event file-notify--pending-events))) |
| 129 | ;; gfilenotify. | 148 | |
| 130 | ((memq action '(attribute-changed changed created deleted)) action) | 149 | ;; Map action. We ignore all events which cannot be mapped. |
| 131 | ((eq action 'moved) | 150 | (setq action |
| 132 | (setq file1 (file-notify--event-file1-name event)) | 151 | (cond |
| 133 | 'renamed) | 152 | ;; gfilenotify. |
| 134 | 153 | ((memq action '(attribute-changed changed created deleted)) | |
| 135 | ;; inotify. | 154 | action) |
| 136 | ((eq action 'attrib) 'attribute-changed) | 155 | ((eq action 'moved) |
| 137 | ((eq action 'create) 'created) | 156 | (setq file1 (file-notify--event-file1-name event)) |
| 138 | ((eq action 'modify) 'changed) | 157 | 'renamed) |
| 139 | ((memq action '(delete 'delete-self move-self)) 'deleted) | 158 | |
| 140 | ;; Make the event pending. | 159 | ;; inotify. |
| 141 | ((eq action 'moved-from) | 160 | ((eq action 'attrib) 'attribute-changed) |
| 142 | (add-to-list 'file-notify--pending-events | 161 | ((eq action 'create) 'created) |
| 143 | (list desc action file | 162 | ((eq action 'modify) 'changed) |
| 144 | (file-notify--event-cookie event))) | 163 | ((memq action '(delete 'delete-self move-self)) 'deleted) |
| 145 | nil) | 164 | ;; Make the event pending. |
| 146 | ;; Look for pending event. | 165 | ((eq action 'moved-from) |
| 147 | ((eq action 'moved-to) | 166 | (add-to-list 'file-notify--pending-events |
| 148 | (if (null pending-event) | 167 | (list desc action file |
| 149 | 'created | 168 | (file-notify--event-cookie event))) |
| 150 | (setq file1 file | 169 | nil) |
| 151 | file (file-notify--event-file-name pending-event) | 170 | ;; Look for pending event. |
| 152 | file-notify--pending-events | 171 | ((eq action 'moved-to) |
| 153 | (delete pending-event file-notify--pending-events)) | 172 | (if (null pending-event) |
| 154 | 'renamed)) | 173 | 'created |
| 155 | 174 | (setq file1 file | |
| 156 | ;; w32notify. | 175 | file (file-notify--event-file-name pending-event) |
| 157 | ((eq action 'added) 'created) | 176 | file-notify--pending-events |
| 158 | ((eq action 'modified) 'changed) | 177 | (delete pending-event file-notify--pending-events)) |
| 159 | ((eq action 'removed) 'deleted) | 178 | 'renamed)) |
| 160 | ;; Make the event pending. | 179 | |
| 161 | ((eq 'renamed-from action) | 180 | ;; w32notify. |
| 162 | (add-to-list 'file-notify--pending-events | 181 | ((eq action 'added) 'created) |
| 163 | (list desc action file | 182 | ((eq action 'modified) 'changed) |
| 164 | (file-notify--event-cookie event))) | 183 | ((eq action 'removed) 'deleted) |
| 165 | nil) | 184 | ;; Make the event pending. |
| 166 | ;; Look for pending event. | 185 | ((eq action 'renamed-from) |
| 167 | ((eq 'renamed-to action) | 186 | (add-to-list 'file-notify--pending-events |
| 168 | (if (null pending-event) | 187 | (list desc action file |
| 169 | 'created | 188 | (file-notify--event-cookie event))) |
| 170 | (setq file1 file | 189 | nil) |
| 171 | file (file-notify--event-file-name pending-event) | 190 | ;; Look for pending event. |
| 172 | file-notify--pending-events | 191 | ((eq action 'renamed-to) |
| 173 | (delete pending-event file-notify--pending-events)) | 192 | (if (null pending-event) |
| 174 | 'renamed)))) | 193 | 'created |
| 175 | 194 | (setq file1 file | |
| 176 | ;; Apply callback. | 195 | file (file-notify--event-file-name pending-event) |
| 177 | (when (and action | 196 | file-notify--pending-events |
| 178 | (or | 197 | (delete pending-event file-notify--pending-events)) |
| 179 | ;; If there is no relative file name for that watch, | 198 | 'renamed)))) |
| 180 | ;; we watch the whole directory. | 199 | |
| 181 | (null (nth 1 registered)) | 200 | ;; Apply callback. |
| 182 | ;; File matches. | 201 | (when (and action |
| 183 | (string-equal | 202 | (or |
| 184 | (nth 1 registered) (file-name-nondirectory file)) | 203 | ;; If there is no relative file name for that watch, |
| 185 | ;; File1 matches. | 204 | ;; we watch the whole directory. |
| 186 | (and (stringp file1) | 205 | (null (nth 0 entry)) |
| 187 | (string-equal | 206 | ;; File matches. |
| 188 | (nth 1 registered) (file-name-nondirectory file1))))) | 207 | (string-equal |
| 189 | (if file1 | 208 | (nth 0 entry) (file-name-nondirectory file)) |
| 190 | (funcall callback (list desc action file file1)) | 209 | ;; File1 matches. |
| 191 | (funcall callback (list desc action file))))))) | 210 | (and (stringp file1) |
| 192 | 211 | (string-equal | |
| 212 | (nth 0 entry) (file-name-nondirectory file1))))) | ||
| 213 | (if file1 | ||
| 214 | (funcall | ||
| 215 | callback | ||
| 216 | `(,(file-notify--descriptor desc (nth 0 entry)) | ||
| 217 | ,action ,file ,file1)) | ||
| 218 | (funcall | ||
| 219 | callback | ||
| 220 | `(,(file-notify--descriptor desc (nth 0 entry)) | ||
| 221 | ,action ,file)))))))) | ||
| 222 | |||
| 223 | ;; `gfilenotify' and `w32notify' return a unique descriptor for every | ||
| 224 | ;; `file-notify-add-watch', while `inotify' returns a unique | ||
| 225 | ;; descriptor per inode only. | ||
| 193 | (defun file-notify-add-watch (file flags callback) | 226 | (defun file-notify-add-watch (file flags callback) |
| 194 | "Add a watch for filesystem events pertaining to FILE. | 227 | "Add a watch for filesystem events pertaining to FILE. |
| 195 | This arranges for filesystem events pertaining to FILE to be reported | 228 | This arranges for filesystem events pertaining to FILE to be reported |
| @@ -206,7 +239,7 @@ include the following symbols: | |||
| 206 | `attribute-change' -- watch for file attributes changes, like | 239 | `attribute-change' -- watch for file attributes changes, like |
| 207 | permissions or modification time | 240 | permissions or modification time |
| 208 | 241 | ||
| 209 | If FILE is a directory, 'change' watches for file creation or | 242 | If FILE is a directory, `change' watches for file creation or |
| 210 | deletion in that directory. This does not work recursively. | 243 | deletion in that directory. This does not work recursively. |
| 211 | 244 | ||
| 212 | When any event happens, Emacs will call the CALLBACK function passing | 245 | When any event happens, Emacs will call the CALLBACK function passing |
| @@ -240,82 +273,96 @@ FILE is the name of the file whose event is being reported." | |||
| 240 | (if (file-directory-p file) | 273 | (if (file-directory-p file) |
| 241 | file | 274 | file |
| 242 | (file-name-directory file)))) | 275 | (file-name-directory file)))) |
| 243 | desc func l-flags) | 276 | desc func l-flags registered) |
| 244 | 277 | ||
| 245 | ;; Check, whether this has been registered already. | 278 | (if handler |
| 246 | ; (maphash | 279 | ;; A file name handler could exist even if there is no local |
| 247 | ; (lambda (key value) | 280 | ;; file notification support. |
| 248 | ; (when (equal (cons file callback) value) (setq desc key))) | 281 | (setq desc (funcall |
| 249 | ; file-notify-descriptors) | 282 | handler 'file-notify-add-watch dir flags callback)) |
| 250 | 283 | ||
| 251 | (unless desc | 284 | ;; Check, whether Emacs has been compiled with file |
| 252 | (if handler | 285 | ;; notification support. |
| 253 | ;; A file name handler could exist even if there is no local | 286 | (unless file-notify--library |
| 254 | ;; file notification support. | 287 | (signal 'file-notify-error |
| 255 | (setq desc (funcall | 288 | '("No file notification package available"))) |
| 256 | handler 'file-notify-add-watch dir flags callback)) | 289 | |
| 257 | 290 | ;; Determine low-level function to be called. | |
| 258 | ;; Check, whether Emacs has been compiled with file | 291 | (setq func |
| 259 | ;; notification support. | 292 | (cond |
| 260 | (unless file-notify--library | 293 | ((eq file-notify--library 'gfilenotify) 'gfile-add-watch) |
| 261 | (signal 'file-notify-error | 294 | ((eq file-notify--library 'inotify) 'inotify-add-watch) |
| 262 | '("No file notification package available"))) | 295 | ((eq file-notify--library 'w32notify) 'w32notify-add-watch))) |
| 263 | 296 | ||
| 264 | ;; Determine low-level function to be called. | 297 | ;; Determine respective flags. |
| 265 | (setq func | 298 | (if (eq file-notify--library 'gfilenotify) |
| 266 | (cond | 299 | (setq l-flags '(watch-mounts send-moved)) |
| 267 | ((eq file-notify--library 'gfilenotify) 'gfile-add-watch) | 300 | (when (memq 'change flags) |
| 268 | ((eq file-notify--library 'inotify) 'inotify-add-watch) | 301 | (setq |
| 269 | ((eq file-notify--library 'w32notify) 'w32notify-add-watch))) | 302 | l-flags |
| 270 | 303 | (cond | |
| 271 | ;; Determine respective flags. | 304 | ((eq file-notify--library 'inotify) '(create modify move delete)) |
| 272 | (if (eq file-notify--library 'gfilenotify) | 305 | ((eq file-notify--library 'w32notify) |
| 273 | (setq l-flags '(watch-mounts send-moved)) | 306 | '(file-name directory-name size last-write-time))))) |
| 274 | (when (memq 'change flags) | 307 | (when (memq 'attribute-change flags) |
| 275 | (setq | 308 | (add-to-list |
| 276 | l-flags | 309 | 'l-flags |
| 277 | (cond | 310 | (cond |
| 278 | ((eq file-notify--library 'inotify) '(create modify move delete)) | 311 | ((eq file-notify--library 'inotify) 'attrib) |
| 279 | ((eq file-notify--library 'w32notify) | 312 | ((eq file-notify--library 'w32notify) 'attributes))))) |
| 280 | '(file-name directory-name size last-write-time))))) | 313 | |
| 281 | (when (memq 'attribute-change flags) | 314 | ;; Call low-level function. |
| 282 | (add-to-list | 315 | (setq desc (funcall func dir l-flags 'file-notify-callback))) |
| 283 | 'l-flags | 316 | |
| 284 | (cond | 317 | ;; Modify `file-notify-descriptors'. |
| 285 | ((eq file-notify--library 'inotify) 'attrib) | 318 | (setq registered (gethash desc file-notify-descriptors)) |
| 286 | ((eq file-notify--library 'w32notify) 'attributes))))) | 319 | (puthash |
| 287 | 320 | desc | |
| 288 | ;; Call low-level function. | 321 | `(,dir |
| 289 | (setq desc (funcall func dir l-flags 'file-notify-callback)))) | 322 | (,(unless (file-directory-p file) (file-name-nondirectory file)) |
| 323 | . ,callback) | ||
| 324 | . ,(cdr registered)) | ||
| 325 | file-notify-descriptors) | ||
| 290 | 326 | ||
| 291 | ;; Return descriptor. | 327 | ;; Return descriptor. |
| 292 | (puthash desc | 328 | (file-notify--descriptor |
| 293 | (list (directory-file-name | 329 | desc (unless (file-directory-p file) (file-name-nondirectory file))))) |
| 294 | (if (file-directory-p dir) dir (file-name-directory dir))) | ||
| 295 | (unless (file-directory-p file) | ||
| 296 | (file-name-nondirectory file)) | ||
| 297 | callback) | ||
| 298 | file-notify-descriptors) | ||
| 299 | desc)) | ||
| 300 | 330 | ||
| 301 | (defun file-notify-rm-watch (descriptor) | 331 | (defun file-notify-rm-watch (descriptor) |
| 302 | "Remove an existing watch specified by its DESCRIPTOR. | 332 | "Remove an existing watch specified by its DESCRIPTOR. |
| 303 | DESCRIPTOR should be an object returned by `file-notify-add-watch'." | 333 | DESCRIPTOR should be an object returned by `file-notify-add-watch'." |
| 304 | (let ((file (car (gethash descriptor file-notify-descriptors))) | 334 | (let* ((desc (if (consp descriptor) (car descriptor) descriptor)) |
| 305 | handler) | 335 | (file (if (consp descriptor) (cdr descriptor))) |
| 306 | 336 | (dir (car (gethash desc file-notify-descriptors))) | |
| 307 | (when (stringp file) | 337 | handler registered) |
| 308 | (setq handler (find-file-name-handler file 'file-notify-rm-watch)) | 338 | |
| 309 | (if handler | 339 | (when (stringp dir) |
| 310 | (funcall handler 'file-notify-rm-watch descriptor) | 340 | (setq handler (find-file-name-handler dir 'file-notify-rm-watch)) |
| 311 | (funcall | 341 | |
| 312 | (cond | 342 | ;; Modify `file-notify-descriptors'. |
| 313 | ((eq file-notify--library 'gfilenotify) 'gfile-rm-watch) | 343 | (if (not file) |
| 314 | ((eq file-notify--library 'inotify) 'inotify-rm-watch) | 344 | (remhash desc file-notify-descriptors) |
| 315 | ((eq file-notify--library 'w32notify) 'w32notify-rm-watch)) | 345 | |
| 316 | descriptor))) | 346 | (setq registered (gethash desc file-notify-descriptors)) |
| 317 | 347 | (setcdr registered | |
| 318 | (remhash descriptor file-notify-descriptors))) | 348 | (delete (assoc file (cdr registered)) (cdr registered))) |
| 349 | (if (null (cdr registered)) | ||
| 350 | (remhash desc file-notify-descriptors) | ||
| 351 | (puthash desc registered file-notify-descriptors))) | ||
| 352 | |||
| 353 | ;; Call low-level function. | ||
| 354 | (when (null (cdr registered)) | ||
| 355 | (if handler | ||
| 356 | ;; A file name handler could exist even if there is no local | ||
| 357 | ;; file notification support. | ||
| 358 | (funcall handler 'file-notify-rm-watch desc) | ||
| 359 | |||
| 360 | (funcall | ||
| 361 | (cond | ||
| 362 | ((eq file-notify--library 'gfilenotify) 'gfile-rm-watch) | ||
| 363 | ((eq file-notify--library 'inotify) 'inotify-rm-watch) | ||
| 364 | ((eq file-notify--library 'w32notify) 'w32notify-rm-watch)) | ||
| 365 | desc)))))) | ||
| 319 | 366 | ||
| 320 | ;; The end: | 367 | ;; The end: |
| 321 | (provide 'filenotify) | 368 | (provide 'filenotify) |
diff --git a/lisp/files.el b/lisp/files.el index ed1943dfc28..5e80cb76599 100644 --- a/lisp/files.el +++ b/lisp/files.el | |||
| @@ -6094,7 +6094,7 @@ and `list-directory-verbose-switches'." | |||
| 6094 | 6094 | ||
| 6095 | PATTERN is assumed to represent a file-name wildcard suitable for the | 6095 | PATTERN is assumed to represent a file-name wildcard suitable for the |
| 6096 | underlying filesystem. For Unix and GNU/Linux, each character from the | 6096 | underlying filesystem. For Unix and GNU/Linux, each character from the |
| 6097 | set [ \\t\\n;<>&|()'\"#$] is quoted with a backslash; for DOS/Windows, all | 6097 | set [ \\t\\n;<>&|()`'\"#$] is quoted with a backslash; for DOS/Windows, all |
| 6098 | the parts of the pattern which don't include wildcard characters are | 6098 | the parts of the pattern which don't include wildcard characters are |
| 6099 | quoted with double quotes. | 6099 | quoted with double quotes. |
| 6100 | 6100 | ||
| @@ -6108,12 +6108,12 @@ need to be passed verbatim to shell commands." | |||
| 6108 | ;; argument has quotes, we can safely assume it is already | 6108 | ;; argument has quotes, we can safely assume it is already |
| 6109 | ;; quoted by the caller. | 6109 | ;; quoted by the caller. |
| 6110 | (if (or (string-match "[\"]" pattern) | 6110 | (if (or (string-match "[\"]" pattern) |
| 6111 | ;; We quote [&()#$'] in case their shell is a port of a | 6111 | ;; We quote [&()#$`'] in case their shell is a port of a |
| 6112 | ;; Unixy shell. We quote [,=+] because stock DOS and | 6112 | ;; Unixy shell. We quote [,=+] because stock DOS and |
| 6113 | ;; Windows shells require that in some cases, such as | 6113 | ;; Windows shells require that in some cases, such as |
| 6114 | ;; passing arguments to batch files that use positional | 6114 | ;; passing arguments to batch files that use positional |
| 6115 | ;; arguments like %1. | 6115 | ;; arguments like %1. |
| 6116 | (not (string-match "[ \t;&()#$',=+]" pattern))) | 6116 | (not (string-match "[ \t;&()#$`',=+]" pattern))) |
| 6117 | pattern | 6117 | pattern |
| 6118 | (let ((result "\"") | 6118 | (let ((result "\"") |
| 6119 | (beg 0) | 6119 | (beg 0) |
| @@ -6128,7 +6128,7 @@ need to be passed verbatim to shell commands." | |||
| 6128 | (concat result (substring pattern beg) "\"")))) | 6128 | (concat result (substring pattern beg) "\"")))) |
| 6129 | (t | 6129 | (t |
| 6130 | (let ((beg 0)) | 6130 | (let ((beg 0)) |
| 6131 | (while (string-match "[ \t\n;<>&|()'\"#$]" pattern beg) | 6131 | (while (string-match "[ \t\n;<>&|()`'\"#$]" pattern beg) |
| 6132 | (setq pattern | 6132 | (setq pattern |
| 6133 | (concat (substring pattern 0 (match-beginning 0)) | 6133 | (concat (substring pattern 0 (match-beginning 0)) |
| 6134 | "\\" | 6134 | "\\" |
| @@ -6590,35 +6590,40 @@ Runs the members of `kill-emacs-query-functions' in turn and stops | |||
| 6590 | if any returns nil. If `confirm-kill-emacs' is non-nil, calls it." | 6590 | if any returns nil. If `confirm-kill-emacs' is non-nil, calls it." |
| 6591 | (interactive "P") | 6591 | (interactive "P") |
| 6592 | (save-some-buffers arg t) | 6592 | (save-some-buffers arg t) |
| 6593 | (and (or (not (memq t (mapcar (function | 6593 | (let ((confirm confirm-kill-emacs)) |
| 6594 | (lambda (buf) (and (buffer-file-name buf) | 6594 | (and |
| 6595 | (buffer-modified-p buf)))) | 6595 | (or (not (memq t (mapcar (function |
| 6596 | (buffer-list)))) | 6596 | (lambda (buf) (and (buffer-file-name buf) |
| 6597 | (yes-or-no-p "Modified buffers exist; exit anyway? ")) | 6597 | (buffer-modified-p buf)))) |
| 6598 | (or (not (fboundp 'process-list)) | 6598 | (buffer-list)))) |
| 6599 | ;; process-list is not defined on MSDOS. | 6599 | (progn (setq confirm nil) |
| 6600 | (let ((processes (process-list)) | 6600 | (yes-or-no-p "Modified buffers exist; exit anyway? "))) |
| 6601 | active) | 6601 | (or (not (fboundp 'process-list)) |
| 6602 | (while processes | 6602 | ;; process-list is not defined on MSDOS. |
| 6603 | (and (memq (process-status (car processes)) '(run stop open listen)) | 6603 | (let ((processes (process-list)) |
| 6604 | (process-query-on-exit-flag (car processes)) | 6604 | active) |
| 6605 | (setq active t)) | 6605 | (while processes |
| 6606 | (setq processes (cdr processes))) | 6606 | (and (memq (process-status (car processes)) '(run stop open listen)) |
| 6607 | (or (not active) | 6607 | (process-query-on-exit-flag (car processes)) |
| 6608 | (with-current-buffer-window | 6608 | (setq active t)) |
| 6609 | (get-buffer-create "*Process List*") nil | 6609 | (setq processes (cdr processes))) |
| 6610 | #'(lambda (window _value) | 6610 | (or (not active) |
| 6611 | (with-selected-window window | 6611 | (with-current-buffer-window |
| 6612 | (unwind-protect | 6612 | (get-buffer-create "*Process List*") nil |
| 6613 | (yes-or-no-p "Active processes exist; kill them and exit anyway? ") | 6613 | #'(lambda (window _value) |
| 6614 | (when (window-live-p window) | 6614 | (with-selected-window window |
| 6615 | (quit-restore-window window 'kill))))) | 6615 | (unwind-protect |
| 6616 | (list-processes t))))) | 6616 | (progn |
| 6617 | ;; Query the user for other things, perhaps. | 6617 | (setq confirm nil) |
| 6618 | (run-hook-with-args-until-failure 'kill-emacs-query-functions) | 6618 | (yes-or-no-p "Active processes exist; kill them and exit anyway? ")) |
| 6619 | (or (null confirm-kill-emacs) | 6619 | (when (window-live-p window) |
| 6620 | (funcall confirm-kill-emacs "Really exit Emacs? ")) | 6620 | (quit-restore-window window 'kill))))) |
| 6621 | (kill-emacs))) | 6621 | (list-processes t))))) |
| 6622 | ;; Query the user for other things, perhaps. | ||
| 6623 | (run-hook-with-args-until-failure 'kill-emacs-query-functions) | ||
| 6624 | (or (null confirm) | ||
| 6625 | (funcall confirm "Really exit Emacs? ")) | ||
| 6626 | (kill-emacs)))) | ||
| 6622 | 6627 | ||
| 6623 | (defun save-buffers-kill-terminal (&optional arg) | 6628 | (defun save-buffers-kill-terminal (&optional arg) |
| 6624 | "Offer to save each buffer, then kill the current connection. | 6629 | "Offer to save each buffer, then kill the current connection. |
diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog index 7bf4a6e01d6..76683310b3e 100644 --- a/lisp/gnus/ChangeLog +++ b/lisp/gnus/ChangeLog | |||
| @@ -1,3 +1,30 @@ | |||
| 1 | 2015-01-30 Glenn Morris <rgm@gnu.org> | ||
| 2 | |||
| 3 | * gnus-registry.el (gnus-registry-max-pruned-entries) | ||
| 4 | (gnus-registry-prune-factor, gnus-registry-default-sort-function): | ||
| 5 | Fix :version. | ||
| 6 | (gnus-registry-default-sort-function): Improve :type. | ||
| 7 | |||
| 8 | 2015-01-29 Lars Ingebrigtsen <larsi@gnus.org> | ||
| 9 | |||
| 10 | * nnimap.el (nnimap-request-group): Allow running this function on | ||
| 11 | groups that don't exist in Gnus yet. | ||
| 12 | (nnimap-request-group): Revert previous patch since that made it | ||
| 13 | impossible to enter nnimap groups. | ||
| 14 | |||
| 15 | * message.el (message-smtpmail-send-it): Remove the mail header | ||
| 16 | separator before sending. | ||
| 17 | |||
| 18 | 2015-01-28 Elias Oltmanns <eo@nebensachen.de> | ||
| 19 | |||
| 20 | * nnimap.el (nnimap-find-expired-articles): Fix handling of | ||
| 21 | (expiry-wait . never). | ||
| 22 | |||
| 23 | 2015-01-28 Lars Ingebrigtsen <larsi@gnus.org> | ||
| 24 | |||
| 25 | * nnimap.el (nnimap-request-group): Clear the buffer before returning | ||
| 26 | the data. | ||
| 27 | |||
| 1 | 2015-01-27 Lars Ingebrigtsen <larsi@gnus.org> | 28 | 2015-01-27 Lars Ingebrigtsen <larsi@gnus.org> |
| 2 | 29 | ||
| 3 | * nnir.el (nnir-imap-expr-to-imap): Check for literal+ capability in | 30 | * nnir.el (nnir-imap-expr-to-imap): Check for literal+ capability in |
diff --git a/lisp/gnus/gnus-registry.el b/lisp/gnus/gnus-registry.el index 9cfca1290c5..2017ea2f826 100644 --- a/lisp/gnus/gnus-registry.el +++ b/lisp/gnus/gnus-registry.el | |||
| @@ -176,7 +176,8 @@ nnmairix groups are specifically excluded because they are ephemeral." | |||
| 176 | (make-obsolete-variable 'gnus-registry-max-track-groups nil "23.4") | 176 | (make-obsolete-variable 'gnus-registry-max-track-groups nil "23.4") |
| 177 | (make-obsolete-variable 'gnus-registry-entry-caching nil "23.4") | 177 | (make-obsolete-variable 'gnus-registry-entry-caching nil "23.4") |
| 178 | (make-obsolete-variable 'gnus-registry-trim-articles-without-groups nil "23.4") | 178 | (make-obsolete-variable 'gnus-registry-trim-articles-without-groups nil "23.4") |
| 179 | (make-obsolete-variable 'gnus-registry-max-pruned-entries nil "24.4") | 179 | ;; FIXME it was simply deleted. |
| 180 | (make-obsolete-variable 'gnus-registry-max-pruned-entries nil "25.1") | ||
| 180 | 181 | ||
| 181 | (defcustom gnus-registry-track-extra '(subject sender recipient) | 182 | (defcustom gnus-registry-track-extra '(subject sender recipient) |
| 182 | "Whether the registry should track extra data about a message. | 183 | "Whether the registry should track extra data about a message. |
| @@ -253,21 +254,18 @@ exactly how much less. For example, given a maximum size of | |||
| 253 | cut the registry back to \(- 50000 \(* 50000 0.1\)\) -> 45000 | 254 | cut the registry back to \(- 50000 \(* 50000 0.1\)\) -> 45000 |
| 254 | entries. The pruning process is constrained by the presence of | 255 | entries. The pruning process is constrained by the presence of |
| 255 | \"precious\" entries." | 256 | \"precious\" entries." |
| 256 | :version "24.4" | 257 | :version "25.1" |
| 257 | :group 'gnus-registry | 258 | :group 'gnus-registry |
| 258 | :type 'float) | 259 | :type 'float) |
| 259 | 260 | ||
| 260 | (defcustom gnus-registry-default-sort-function | 261 | (defcustom gnus-registry-default-sort-function |
| 261 | #'gnus-registry-sort-by-creation-time | 262 | #'gnus-registry-sort-by-creation-time |
| 262 | "Sort function to use when pruning the registry. | 263 | "Sort function to use when pruning the registry. |
| 263 | 264 | Entries that sort to the front of the list are pruned first. | |
| 264 | Entries which sort to the front of the list will be pruned | ||
| 265 | first. | ||
| 266 | |||
| 267 | This can slow pruning down. Set to nil to perform no sorting." | 265 | This can slow pruning down. Set to nil to perform no sorting." |
| 268 | :version "24.4" | 266 | :version "25.1" |
| 269 | :group 'gnus-registry | 267 | :group 'gnus-registry |
| 270 | :type 'symbol) | 268 | :type '(choice (const :tag "No sorting" nil) function)) |
| 271 | 269 | ||
| 272 | (defun gnus-registry-sort-by-creation-time (l r) | 270 | (defun gnus-registry-sort-by-creation-time (l r) |
| 273 | "Sort older entries to front of list." | 271 | "Sort older entries to front of list." |
diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el index de7e9bab8ec..a06de2a6414 100644 --- a/lisp/gnus/message.el +++ b/lisp/gnus/message.el | |||
| @@ -4906,6 +4906,11 @@ evaluates `message-send-mail-hook' just before sending a message. | |||
| 4906 | It is useful if your ISP requires the POP-before-SMTP | 4906 | It is useful if your ISP requires the POP-before-SMTP |
| 4907 | authentication. See the Gnus manual for details." | 4907 | authentication. See the Gnus manual for details." |
| 4908 | (run-hooks 'message-send-mail-hook) | 4908 | (run-hooks 'message-send-mail-hook) |
| 4909 | ;; Change header-delimiter to be what smtpmail expects. | ||
| 4910 | (goto-char (point-min)) | ||
| 4911 | (when (re-search-forward | ||
| 4912 | (concat "^" (regexp-quote mail-header-separator) "\n")) | ||
| 4913 | (replace-match "\n")) | ||
| 4909 | (smtpmail-send-it)) | 4914 | (smtpmail-send-it)) |
| 4910 | 4915 | ||
| 4911 | (defun message-send-mail-with-mailclient () | 4916 | (defun message-send-mail-with-mailclient () |
diff --git a/lisp/gnus/mm-decode.el b/lisp/gnus/mm-decode.el index f03b9c9b484..311ea7cffff 100644 --- a/lisp/gnus/mm-decode.el +++ b/lisp/gnus/mm-decode.el | |||
| @@ -889,7 +889,7 @@ external if displayed external." | |||
| 889 | (when (and (boundp 'gnus-summary-buffer) | 889 | (when (and (boundp 'gnus-summary-buffer) |
| 890 | (bufferp gnus-summary-buffer) | 890 | (bufferp gnus-summary-buffer) |
| 891 | (buffer-name gnus-summary-buffer)) | 891 | (buffer-name gnus-summary-buffer)) |
| 892 | ;; So that we pop back to the right place, sortof. | 892 | ;; So that we pop back to the right place, sort of. |
| 893 | (switch-to-buffer gnus-summary-buffer) | 893 | (switch-to-buffer gnus-summary-buffer) |
| 894 | (switch-to-buffer mm)) | 894 | (switch-to-buffer mm)) |
| 895 | (delete-other-windows) | 895 | (delete-other-windows) |
diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el index 8e81abcf9c0..e619c0f13c2 100644 --- a/lisp/gnus/nnimap.el +++ b/lisp/gnus/nnimap.el | |||
| @@ -812,6 +812,7 @@ textual parts.") | |||
| 812 | (nnimap-finish-retrieve-group-infos server (list info) sequences | 812 | (nnimap-finish-retrieve-group-infos server (list info) sequences |
| 813 | t) | 813 | t) |
| 814 | (setq active (nth 2 (assoc group nnimap-current-infos))))) | 814 | (setq active (nth 2 (assoc group nnimap-current-infos))))) |
| 815 | (erase-buffer) | ||
| 815 | (insert (format "211 %d %d %d %S\n" | 816 | (insert (format "211 %d %d %d %S\n" |
| 816 | (- (cdr active) (car active)) | 817 | (- (cdr active) (car active)) |
| 817 | (car active) | 818 | (car active) |
| @@ -1020,20 +1021,20 @@ textual parts.") | |||
| 1020 | 1021 | ||
| 1021 | (defun nnimap-find-expired-articles (group) | 1022 | (defun nnimap-find-expired-articles (group) |
| 1022 | (let ((cutoff (nnmail-expired-article-p group nil nil))) | 1023 | (let ((cutoff (nnmail-expired-article-p group nil nil))) |
| 1023 | (with-current-buffer (nnimap-buffer) | 1024 | (when cutoff |
| 1024 | (let ((result | 1025 | (with-current-buffer (nnimap-buffer) |
| 1025 | (nnimap-command | 1026 | (let ((result |
| 1026 | "UID SEARCH SENTBEFORE %s" | 1027 | (nnimap-command |
| 1027 | (format-time-string | 1028 | "UID SEARCH SENTBEFORE %s" |
| 1028 | (format "%%d-%s-%%Y" | 1029 | (format-time-string |
| 1029 | (upcase | 1030 | (format "%%d-%s-%%Y" |
| 1030 | (car (rassoc (nth 4 (decode-time cutoff)) | 1031 | (upcase |
| 1031 | parse-time-months)))) | 1032 | (car (rassoc (nth 4 (decode-time cutoff)) |
| 1032 | cutoff)))) | 1033 | parse-time-months)))) |
| 1033 | (and (car result) | 1034 | cutoff)))) |
| 1034 | (delete 0 (mapcar #'string-to-number | 1035 | (and (car result) |
| 1035 | (cdr (assoc "SEARCH" (cdr result)))))))))) | 1036 | (delete 0 (mapcar #'string-to-number |
| 1036 | 1037 | (cdr (assoc "SEARCH" (cdr result))))))))))) | |
| 1037 | 1038 | ||
| 1038 | (defun nnimap-find-article-by-message-id (group server message-id | 1039 | (defun nnimap-find-article-by-message-id (group server message-id |
| 1039 | &optional limit) | 1040 | &optional limit) |
diff --git a/lisp/loadup.el b/lisp/loadup.el index 96641c8a268..003b0db4abd 100644 --- a/lisp/loadup.el +++ b/lisp/loadup.el | |||
| @@ -145,7 +145,8 @@ | |||
| 145 | (file-error (load "ldefs-boot.el"))) | 145 | (file-error (load "ldefs-boot.el"))) |
| 146 | 146 | ||
| 147 | (load "emacs-lisp/nadvice") | 147 | (load "emacs-lisp/nadvice") |
| 148 | (load "minibuffer") | 148 | (load "emacs-lisp/cl-preloaded") |
| 149 | (load "minibuffer") ;After loaddefs, for define-minor-mode. | ||
| 149 | (load "abbrev") ;lisp-mode.el and simple.el use define-abbrev-table. | 150 | (load "abbrev") ;lisp-mode.el and simple.el use define-abbrev-table. |
| 150 | (load "simple") | 151 | (load "simple") |
| 151 | 152 | ||
diff --git a/lisp/net/net-utils.el b/lisp/net/net-utils.el index 28aa43117da..ebcbc714ffb 100644 --- a/lisp/net/net-utils.el +++ b/lisp/net/net-utils.el | |||
| @@ -328,7 +328,15 @@ This variable is only used if the variable | |||
| 328 | 328 | ||
| 329 | (defun net-utils-run-program (name header program args) | 329 | (defun net-utils-run-program (name header program args) |
| 330 | "Run a network information program." | 330 | "Run a network information program." |
| 331 | (let ((buf (get-buffer-create (concat "*" name "*")))) | 331 | (let ((buf (get-buffer-create (concat "*" name "*"))) |
| 332 | (coding-system-for-read | ||
| 333 | ;; MS-Windows versions of network utilities output text | ||
| 334 | ;; encoded in the console (a.k.a. "OEM") codepage, which is | ||
| 335 | ;; different from the default system (a.k.a. "ANSI") | ||
| 336 | ;; codepage. | ||
| 337 | (if (eq system-type 'windows-nt) | ||
| 338 | (intern (format "cp%d" (w32-get-console-output-codepage))) | ||
| 339 | coding-system-for-read))) | ||
| 332 | (set-buffer buf) | 340 | (set-buffer buf) |
| 333 | (erase-buffer) | 341 | (erase-buffer) |
| 334 | (insert header "\n") | 342 | (insert header "\n") |
| @@ -352,7 +360,15 @@ This variable is only used if the variable | |||
| 352 | (when proc | 360 | (when proc |
| 353 | (set-process-filter proc nil) | 361 | (set-process-filter proc nil) |
| 354 | (delete-process proc))) | 362 | (delete-process proc))) |
| 355 | (let ((inhibit-read-only t)) | 363 | (let ((inhibit-read-only t) |
| 364 | (coding-system-for-read | ||
| 365 | ;; MS-Windows versions of network utilities output text | ||
| 366 | ;; encoded in the console (a.k.a. "OEM") codepage, which is | ||
| 367 | ;; different from the default system (a.k.a. "ANSI") | ||
| 368 | ;; codepage. | ||
| 369 | (if (eq system-type 'windows-nt) | ||
| 370 | (intern (format "cp%d" (w32-get-console-output-codepage))) | ||
| 371 | coding-system-for-read))) | ||
| 356 | (erase-buffer)) | 372 | (erase-buffer)) |
| 357 | (net-utils-mode) | 373 | (net-utils-mode) |
| 358 | (setq-local net-utils--revert-cmd | 374 | (setq-local net-utils--revert-cmd |
diff --git a/lisp/net/shr.el b/lisp/net/shr.el index a0c9eba4144..59c277b01c2 100644 --- a/lisp/net/shr.el +++ b/lisp/net/shr.el | |||
| @@ -1628,6 +1628,8 @@ The preference is a float determined from `shr-prefer-media-type'." | |||
| 1628 | (let ((trs nil) | 1628 | (let ((trs nil) |
| 1629 | (shr-inhibit-decoration (not fill)) | 1629 | (shr-inhibit-decoration (not fill)) |
| 1630 | (rowspans (make-vector (length widths) 0)) | 1630 | (rowspans (make-vector (length widths) 0)) |
| 1631 | (colspan-remaining 0) | ||
| 1632 | colspan-width colspan-count | ||
| 1631 | width colspan) | 1633 | width colspan) |
| 1632 | (dolist (row (dom-non-text-children dom)) | 1634 | (dolist (row (dom-non-text-children dom)) |
| 1633 | (when (eq (dom-tag row) 'tr) | 1635 | (when (eq (dom-tag row) 'tr) |
| @@ -1659,24 +1661,39 @@ The preference is a float determined from `shr-prefer-media-type'." | |||
| 1659 | (if column | 1661 | (if column |
| 1660 | (aref widths width-column) | 1662 | (aref widths width-column) |
| 1661 | 10)) | 1663 | 10)) |
| 1662 | (when (and fill | 1664 | (when (setq colspan (dom-attr column 'colspan)) |
| 1663 | (setq colspan (dom-attr column 'colspan))) | ||
| 1664 | (setq colspan (min (string-to-number colspan) | 1665 | (setq colspan (min (string-to-number colspan) |
| 1665 | ;; The colspan may be wrong, so | 1666 | ;; The colspan may be wrong, so |
| 1666 | ;; truncate it to the length of the | 1667 | ;; truncate it to the length of the |
| 1667 | ;; remaining columns. | 1668 | ;; remaining columns. |
| 1668 | (- (length widths) i))) | 1669 | (- (length widths) i))) |
| 1669 | (dotimes (j (1- colspan)) | 1670 | (dotimes (j (1- colspan)) |
| 1670 | (if (> (+ i 1 j) (1- (length widths))) | 1671 | (setq width |
| 1671 | (setq width (aref widths (1- (length widths)))) | 1672 | (if (> (+ i 1 j) (1- (length widths))) |
| 1672 | (setq width (+ width | 1673 | ;; If we have a colspan spec that's longer |
| 1673 | shr-table-separator-length | 1674 | ;; than the table is wide, just use the last |
| 1674 | (aref widths (+ i 1 j)))))) | 1675 | ;; width as the width. |
| 1675 | (setq width-column (+ width-column (1- colspan)))) | 1676 | (aref widths (1- (length widths))) |
| 1677 | ;; Sum up the widths of the columns we're | ||
| 1678 | ;; spanning. | ||
| 1679 | (+ width | ||
| 1680 | shr-table-separator-length | ||
| 1681 | (aref widths (+ i 1 j)))))) | ||
| 1682 | (setq width-column (+ width-column (1- colspan)) | ||
| 1683 | colspan-count colspan | ||
| 1684 | colspan-remaining colspan)) | ||
| 1676 | (when (or column | 1685 | (when (or column |
| 1677 | (not fill)) | 1686 | (not fill)) |
| 1678 | (push (shr-render-td column width fill) | 1687 | (let ((data (shr-render-td column width fill))) |
| 1679 | tds)) | 1688 | (if (and (not fill) |
| 1689 | (> colspan-remaining 0)) | ||
| 1690 | (progn | ||
| 1691 | (when (= colspan-count colspan-remaining) | ||
| 1692 | (setq colspan-width data)) | ||
| 1693 | (let ((this-width (/ colspan-width colspan-count))) | ||
| 1694 | (push this-width tds) | ||
| 1695 | (setq colspan-remaining (1- colspan-remaining)))) | ||
| 1696 | (push data tds)))) | ||
| 1680 | (setq i (1+ i) | 1697 | (setq i (1+ i) |
| 1681 | width-column (1+ width-column)))) | 1698 | width-column (1+ width-column)))) |
| 1682 | (push (nreverse tds) trs)))) | 1699 | (push (nreverse tds) trs)))) |
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index d44c8ea2f6d..ba0d13eab8b 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el | |||
| @@ -64,7 +64,6 @@ | |||
| 64 | (defvar bkup-backup-directory-info) | 64 | (defvar bkup-backup-directory-info) |
| 65 | (defvar directory-sep-char) | 65 | (defvar directory-sep-char) |
| 66 | (defvar eshell-path-env) | 66 | (defvar eshell-path-env) |
| 67 | (defvar file-notify-descriptors) | ||
| 68 | (defvar ls-lisp-use-insert-directory-program) | 67 | (defvar ls-lisp-use-insert-directory-program) |
| 69 | (defvar outline-regexp) | 68 | (defvar outline-regexp) |
| 70 | 69 | ||
| @@ -3415,7 +3414,7 @@ of." | |||
| 3415 | (defun tramp-handle-file-notify-rm-watch (proc) | 3414 | (defun tramp-handle-file-notify-rm-watch (proc) |
| 3416 | "Like `file-notify-rm-watch' for Tramp files." | 3415 | "Like `file-notify-rm-watch' for Tramp files." |
| 3417 | ;; The descriptor must be a process object. | 3416 | ;; The descriptor must be a process object. |
| 3418 | (unless (and (processp proc) (gethash proc file-notify-descriptors)) | 3417 | (unless (processp proc) |
| 3419 | (tramp-error proc 'file-notify-error "Not a valid descriptor %S" proc)) | 3418 | (tramp-error proc 'file-notify-error "Not a valid descriptor %S" proc)) |
| 3420 | (tramp-message proc 6 "Kill %S" proc) | 3419 | (tramp-message proc 6 "Kill %S" proc) |
| 3421 | (kill-process proc)) | 3420 | (kill-process proc)) |
diff --git a/lisp/outline.el b/lisp/outline.el index 11d71fb1226..ae31b8088f0 100644 --- a/lisp/outline.el +++ b/lisp/outline.el | |||
| @@ -35,9 +35,6 @@ | |||
| 35 | 35 | ||
| 36 | ;;; Code: | 36 | ;;; Code: |
| 37 | 37 | ||
| 38 | (defvar font-lock-warning-face) | ||
| 39 | |||
| 40 | |||
| 41 | (defgroup outlines nil | 38 | (defgroup outlines nil |
| 42 | "Support for hierarchical outlining." | 39 | "Support for hierarchical outlining." |
| 43 | :prefix "outline-" | 40 | :prefix "outline-" |
| @@ -65,73 +62,66 @@ in the file it applies to.") | |||
| 65 | (define-key map "@" 'outline-mark-subtree) | 62 | (define-key map "@" 'outline-mark-subtree) |
| 66 | (define-key map "\C-n" 'outline-next-visible-heading) | 63 | (define-key map "\C-n" 'outline-next-visible-heading) |
| 67 | (define-key map "\C-p" 'outline-previous-visible-heading) | 64 | (define-key map "\C-p" 'outline-previous-visible-heading) |
| 68 | (define-key map "\C-i" 'show-children) | 65 | (define-key map "\C-i" 'outline-show-children) |
| 69 | (define-key map "\C-s" 'show-subtree) | 66 | (define-key map "\C-s" 'outline-show-subtree) |
| 70 | (define-key map "\C-d" 'hide-subtree) | 67 | (define-key map "\C-d" 'outline-hide-subtree) |
| 71 | (define-key map "\C-u" 'outline-up-heading) | 68 | (define-key map "\C-u" 'outline-up-heading) |
| 72 | (define-key map "\C-f" 'outline-forward-same-level) | 69 | (define-key map "\C-f" 'outline-forward-same-level) |
| 73 | (define-key map "\C-b" 'outline-backward-same-level) | 70 | (define-key map "\C-b" 'outline-backward-same-level) |
| 74 | (define-key map "\C-t" 'hide-body) | 71 | (define-key map "\C-t" 'outline-hide-body) |
| 75 | (define-key map "\C-a" 'show-all) | 72 | (define-key map "\C-a" 'outline-show-all) |
| 76 | (define-key map "\C-c" 'hide-entry) | 73 | (define-key map "\C-c" 'outline-hide-entry) |
| 77 | (define-key map "\C-e" 'show-entry) | 74 | (define-key map "\C-e" 'outline-show-entry) |
| 78 | (define-key map "\C-l" 'hide-leaves) | 75 | (define-key map "\C-l" 'outline-hide-leaves) |
| 79 | (define-key map "\C-k" 'show-branches) | 76 | (define-key map "\C-k" 'outline-show-branches) |
| 80 | (define-key map "\C-q" 'hide-sublevels) | 77 | (define-key map "\C-q" 'outline-hide-sublevels) |
| 81 | (define-key map "\C-o" 'hide-other) | 78 | (define-key map "\C-o" 'outline-hide-other) |
| 82 | (define-key map "\C-^" 'outline-move-subtree-up) | 79 | (define-key map "\C-^" 'outline-move-subtree-up) |
| 83 | (define-key map "\C-v" 'outline-move-subtree-down) | 80 | (define-key map "\C-v" 'outline-move-subtree-down) |
| 84 | (define-key map [(control ?<)] 'outline-promote) | 81 | (define-key map [(control ?<)] 'outline-promote) |
| 85 | (define-key map [(control ?>)] 'outline-demote) | 82 | (define-key map [(control ?>)] 'outline-demote) |
| 86 | (define-key map "\C-m" 'outline-insert-heading) | 83 | (define-key map "\C-m" 'outline-insert-heading) |
| 87 | ;; Where to bind outline-cycle ? | ||
| 88 | map)) | 84 | map)) |
| 89 | 85 | ||
| 90 | (defvar outline-mode-menu-bar-map | 86 | (defvar outline-mode-menu-bar-map |
| 91 | (let ((map (make-sparse-keymap))) | 87 | (let ((map (make-sparse-keymap))) |
| 92 | |||
| 93 | (define-key map [hide] (cons "Hide" (make-sparse-keymap "Hide"))) | 88 | (define-key map [hide] (cons "Hide" (make-sparse-keymap "Hide"))) |
| 94 | 89 | (define-key map [hide outline-hide-other] | |
| 95 | (define-key map [hide hide-other] | 90 | '(menu-item "Hide Other" outline-hide-other |
| 96 | '(menu-item "Hide Other" hide-other | ||
| 97 | :help "Hide everything except current body and parent and top-level headings")) | 91 | :help "Hide everything except current body and parent and top-level headings")) |
| 98 | (define-key map [hide hide-sublevels] | 92 | (define-key map [hide outline-hide-sublevels] |
| 99 | '(menu-item "Hide Sublevels" hide-sublevels | 93 | '(menu-item "Hide Sublevels" outline-hide-sublevels |
| 100 | :help "Hide everything but the top LEVELS levels of headers, in whole buffer")) | 94 | :help "Hide everything but the top LEVELS levels of headers, in whole buffer")) |
| 101 | (define-key map [hide hide-subtree] | 95 | (define-key map [hide outline-hide-subtree] |
| 102 | '(menu-item "Hide Subtree" hide-subtree | 96 | '(menu-item "Hide Subtree" outline-hide-subtree |
| 103 | :help "Hide everything after this heading at deeper levels")) | 97 | :help "Hide everything after this heading at deeper levels")) |
| 104 | (define-key map [hide hide-entry] | 98 | (define-key map [hide outline-hide-entry] |
| 105 | '(menu-item "Hide Entry" hide-entry | 99 | '(menu-item "Hide Entry" outline-hide-entry |
| 106 | :help "Hide the body directly following this heading")) | 100 | :help "Hide the body directly following this heading")) |
| 107 | (define-key map [hide hide-body] | 101 | (define-key map [hide outline-hide-body] |
| 108 | '(menu-item "Hide Body" hide-body | 102 | '(menu-item "Hide Body" outline-hide-body |
| 109 | :help "Hide all body lines in buffer, leaving all headings visible")) | 103 | :help "Hide all body lines in buffer, leaving all headings visible")) |
| 110 | (define-key map [hide hide-leaves] | 104 | (define-key map [hide outline-hide-leaves] |
| 111 | '(menu-item "Hide Leaves" hide-leaves | 105 | '(menu-item "Hide Leaves" outline-hide-leaves |
| 112 | :help "Hide the body after this heading and at deeper levels")) | 106 | :help "Hide the body after this heading and at deeper levels")) |
| 113 | |||
| 114 | (define-key map [show] (cons "Show" (make-sparse-keymap "Show"))) | 107 | (define-key map [show] (cons "Show" (make-sparse-keymap "Show"))) |
| 115 | 108 | (define-key map [show outline-show-subtree] | |
| 116 | (define-key map [show show-subtree] | 109 | '(menu-item "Show Subtree" outline-show-subtree |
| 117 | '(menu-item "Show Subtree" show-subtree | ||
| 118 | :help "Show everything after this heading at deeper levels")) | 110 | :help "Show everything after this heading at deeper levels")) |
| 119 | (define-key map [show show-children] | 111 | (define-key map [show outline-show-children] |
| 120 | '(menu-item "Show Children" show-children | 112 | '(menu-item "Show Children" outline-show-children |
| 121 | :help "Show all direct subheadings of this heading")) | 113 | :help "Show all direct subheadings of this heading")) |
| 122 | (define-key map [show show-branches] | 114 | (define-key map [show outline-show-branches] |
| 123 | '(menu-item "Show Branches" show-branches | 115 | '(menu-item "Show Branches" outline-show-branches |
| 124 | :help "Show all subheadings of this heading, but not their bodies")) | 116 | :help "Show all subheadings of this heading, but not their bodies")) |
| 125 | (define-key map [show show-entry] | 117 | (define-key map [show outline-show-entry] |
| 126 | '(menu-item "Show Entry" show-entry | 118 | '(menu-item "Show Entry" outline-show-entry |
| 127 | :help "Show the body directly following this heading")) | 119 | :help "Show the body directly following this heading")) |
| 128 | (define-key map [show show-all] | 120 | (define-key map [show outline-show-all] |
| 129 | '(menu-item "Show All" show-all | 121 | '(menu-item "Show All" outline-show-all |
| 130 | :help "Show all of the text in the buffer")) | 122 | :help "Show all of the text in the buffer")) |
| 131 | |||
| 132 | (define-key map [headings] | 123 | (define-key map [headings] |
| 133 | (cons "Headings" (make-sparse-keymap "Headings"))) | 124 | (cons "Headings" (make-sparse-keymap "Headings"))) |
| 134 | |||
| 135 | (define-key map [headings demote-subtree] | 125 | (define-key map [headings demote-subtree] |
| 136 | '(menu-item "Demote Subtree" outline-demote | 126 | '(menu-item "Demote Subtree" outline-demote |
| 137 | :help "Demote headings lower down the tree")) | 127 | :help "Demote headings lower down the tree")) |
| @@ -152,23 +142,18 @@ in the file it applies to.") | |||
| 152 | '(menu-item "New Heading" outline-insert-heading | 142 | '(menu-item "New Heading" outline-insert-heading |
| 153 | :help "Insert a new heading at same depth at point")) | 143 | :help "Insert a new heading at same depth at point")) |
| 154 | (define-key map [headings outline-backward-same-level] | 144 | (define-key map [headings outline-backward-same-level] |
| 155 | |||
| 156 | '(menu-item "Previous Same Level" outline-backward-same-level | 145 | '(menu-item "Previous Same Level" outline-backward-same-level |
| 157 | :help "Move backward to the arg'th subheading at same level as this one.")) | 146 | :help "Move backward to the arg'th subheading at same level as this one.")) |
| 158 | (define-key map [headings outline-forward-same-level] | 147 | (define-key map [headings outline-forward-same-level] |
| 159 | |||
| 160 | '(menu-item "Next Same Level" outline-forward-same-level | 148 | '(menu-item "Next Same Level" outline-forward-same-level |
| 161 | :help "Move forward to the arg'th subheading at same level as this one")) | 149 | :help "Move forward to the arg'th subheading at same level as this one")) |
| 162 | (define-key map [headings outline-previous-visible-heading] | 150 | (define-key map [headings outline-previous-visible-heading] |
| 163 | |||
| 164 | '(menu-item "Previous" outline-previous-visible-heading | 151 | '(menu-item "Previous" outline-previous-visible-heading |
| 165 | :help "Move to the previous heading line")) | 152 | :help "Move to the previous heading line")) |
| 166 | (define-key map [headings outline-next-visible-heading] | 153 | (define-key map [headings outline-next-visible-heading] |
| 167 | |||
| 168 | '(menu-item "Next" outline-next-visible-heading | 154 | '(menu-item "Next" outline-next-visible-heading |
| 169 | :help "Move to the next visible heading line")) | 155 | :help "Move to the next visible heading line")) |
| 170 | (define-key map [headings outline-up-heading] | 156 | (define-key map [headings outline-up-heading] |
| 171 | |||
| 172 | '(menu-item "Up" outline-up-heading | 157 | '(menu-item "Up" outline-up-heading |
| 173 | :help "Move to the visible heading line of which the present line is a subheading")) | 158 | :help "Move to the visible heading line of which the present line is a subheading")) |
| 174 | map)) | 159 | map)) |
| @@ -190,7 +175,6 @@ in the file it applies to.") | |||
| 190 | outline-mode-menu-bar-map)))))) | 175 | outline-mode-menu-bar-map)))))) |
| 191 | map)) | 176 | map)) |
| 192 | 177 | ||
| 193 | |||
| 194 | (defvar outline-mode-map | 178 | (defvar outline-mode-map |
| 195 | (let ((map (make-sparse-keymap))) | 179 | (let ((map (make-sparse-keymap))) |
| 196 | (define-key map "\C-c" outline-mode-prefix-map) | 180 | (define-key map "\C-c" outline-mode-prefix-map) |
| @@ -198,7 +182,7 @@ in the file it applies to.") | |||
| 198 | map)) | 182 | map)) |
| 199 | 183 | ||
| 200 | (defvar outline-font-lock-keywords | 184 | (defvar outline-font-lock-keywords |
| 201 | '(;; | 185 | '( |
| 202 | ;; Highlight headings according to the level. | 186 | ;; Highlight headings according to the level. |
| 203 | (eval . (list (concat "^\\(?:" outline-regexp "\\).+") | 187 | (eval . (list (concat "^\\(?:" outline-regexp "\\).+") |
| 204 | 0 '(outline-font-lock-face) nil t))) | 188 | 0 '(outline-font-lock-face) nil t))) |
| @@ -248,33 +232,14 @@ in the file it applies to.") | |||
| 248 | [outline-1 outline-2 outline-3 outline-4 | 232 | [outline-1 outline-2 outline-3 outline-4 |
| 249 | outline-5 outline-6 outline-7 outline-8]) | 233 | outline-5 outline-6 outline-7 outline-8]) |
| 250 | 234 | ||
| 251 | ;; (defvar outline-font-lock-levels nil) | ||
| 252 | ;; (make-variable-buffer-local 'outline-font-lock-levels) | ||
| 253 | |||
| 254 | (defun outline-font-lock-face () | 235 | (defun outline-font-lock-face () |
| 255 | ;; (save-excursion | 236 | "Return one of `outline-font-lock-faces' for current level." |
| 256 | ;; (outline-back-to-heading t) | ||
| 257 | ;; (let* ((count 0) | ||
| 258 | ;; (start-level (funcall outline-level)) | ||
| 259 | ;; (level start-level) | ||
| 260 | ;; face-level) | ||
| 261 | ;; (while (not (setq face-level | ||
| 262 | ;; (if (or (bobp) (eq level 1)) 0 | ||
| 263 | ;; (cdr (assq level outline-font-lock-levels))))) | ||
| 264 | ;; (outline-up-heading 1 t) | ||
| 265 | ;; (setq count (1+ count)) | ||
| 266 | ;; (setq level (funcall outline-level))) | ||
| 267 | ;; ;; Remember for later. | ||
| 268 | ;; (unless (zerop count) | ||
| 269 | ;; (setq face-level (+ face-level count)) | ||
| 270 | ;; (push (cons start-level face-level) outline-font-lock-levels)) | ||
| 271 | ;; (condition-case nil | ||
| 272 | ;; (aref outline-font-lock-faces face-level) | ||
| 273 | ;; (error font-lock-warning-face)))) | ||
| 274 | (save-excursion | 237 | (save-excursion |
| 275 | (goto-char (match-beginning 0)) | 238 | (goto-char (match-beginning 0)) |
| 276 | (looking-at outline-regexp) | 239 | (looking-at outline-regexp) |
| 277 | (aref outline-font-lock-faces (% (1- (funcall outline-level)) (length outline-font-lock-faces))))) | 240 | (aref outline-font-lock-faces |
| 241 | (% (1- (funcall outline-level)) | ||
| 242 | (length outline-font-lock-faces))))) | ||
| 278 | 243 | ||
| 279 | (defvar outline-view-change-hook nil | 244 | (defvar outline-view-change-hook nil |
| 280 | "Normal hook to be run after outline visibility changes.") | 245 | "Normal hook to be run after outline visibility changes.") |
| @@ -296,29 +261,11 @@ invisible, or visible again. Invisible lines are attached to the end | |||
| 296 | of the heading, so they move with it, if the line is killed and yanked | 261 | of the heading, so they move with it, if the line is killed and yanked |
| 297 | back. A heading with text hidden under it is marked with an ellipsis (...). | 262 | back. A heading with text hidden under it is marked with an ellipsis (...). |
| 298 | 263 | ||
| 299 | Commands:\\<outline-mode-map> | 264 | \\{outline-mode-map} |
| 300 | \\[outline-next-visible-heading] outline-next-visible-heading move by visible headings | 265 | The commands `outline-hide-subtree', `outline-show-subtree', |
| 301 | \\[outline-previous-visible-heading] outline-previous-visible-heading | 266 | `outline-show-children', `outline-hide-entry', |
| 302 | \\[outline-forward-same-level] outline-forward-same-level similar but skip subheadings | 267 | `outline-show-entry', `outline-hide-leaves', and `outline-show-branches' |
| 303 | \\[outline-backward-same-level] outline-backward-same-level | 268 | are used when point is on a heading line. |
| 304 | \\[outline-up-heading] outline-up-heading move from subheading to heading | ||
| 305 | |||
| 306 | \\[hide-body] make all text invisible (not headings). | ||
| 307 | \\[show-all] make everything in buffer visible. | ||
| 308 | \\[hide-sublevels] make only the first N levels of headers visible. | ||
| 309 | |||
| 310 | The remaining commands are used when point is on a heading line. | ||
| 311 | They apply to some of the body or subheadings of that heading. | ||
| 312 | \\[hide-subtree] hide-subtree make body and subheadings invisible. | ||
| 313 | \\[show-subtree] show-subtree make body and subheadings visible. | ||
| 314 | \\[show-children] show-children make direct subheadings visible. | ||
| 315 | No effect on body, or subheadings 2 or more levels down. | ||
| 316 | With arg N, affects subheadings N levels down. | ||
| 317 | \\[hide-entry] make immediately following body invisible. | ||
| 318 | \\[show-entry] make it visible. | ||
| 319 | \\[hide-leaves] make body under heading and under its subheadings invisible. | ||
| 320 | The subheadings remain visible. | ||
| 321 | \\[show-branches] make all subheadings at all levels visible. | ||
| 322 | 269 | ||
| 323 | The variable `outline-regexp' can be changed to control what is a heading. | 270 | The variable `outline-regexp' can be changed to control what is a heading. |
| 324 | A line is a heading if `outline-regexp' matches something at the | 271 | A line is a heading if `outline-regexp' matches something at the |
| @@ -340,7 +287,7 @@ Turning on outline mode calls the value of `text-mode-hook' and then of | |||
| 340 | '(outline-font-lock-keywords t nil nil backward-paragraph)) | 287 | '(outline-font-lock-keywords t nil nil backward-paragraph)) |
| 341 | (setq imenu-generic-expression | 288 | (setq imenu-generic-expression |
| 342 | (list (list nil (concat "^\\(?:" outline-regexp "\\).*$") 0))) | 289 | (list (list nil (concat "^\\(?:" outline-regexp "\\).*$") 0))) |
| 343 | (add-hook 'change-major-mode-hook 'show-all nil t)) | 290 | (add-hook 'change-major-mode-hook 'outline-show-all nil t)) |
| 344 | 291 | ||
| 345 | (defcustom outline-minor-mode-prefix "\C-c@" | 292 | (defcustom outline-minor-mode-prefix "\C-c@" |
| 346 | "Prefix key to use for Outline commands in Outline minor mode. | 293 | "Prefix key to use for Outline commands in Outline minor mode. |
| @@ -373,7 +320,7 @@ See the command `outline-mode' for more information on this mode." | |||
| 373 | ;; Cause use of ellipses for invisible text. | 320 | ;; Cause use of ellipses for invisible text. |
| 374 | (remove-from-invisibility-spec '(outline . t)) | 321 | (remove-from-invisibility-spec '(outline . t)) |
| 375 | ;; When turning off outline mode, get rid of any outline hiding. | 322 | ;; When turning off outline mode, get rid of any outline hiding. |
| 376 | (show-all))) | 323 | (outline-show-all))) |
| 377 | 324 | ||
| 378 | (defvar outline-level 'outline-level | 325 | (defvar outline-level 'outline-level |
| 379 | "Function of no args to compute a header's nesting level in an outline. | 326 | "Function of no args to compute a header's nesting level in an outline. |
| @@ -441,7 +388,8 @@ at the end of the buffer." | |||
| 441 | nil 'move)) | 388 | nil 'move)) |
| 442 | 389 | ||
| 443 | (defsubst outline-invisible-p (&optional pos) | 390 | (defsubst outline-invisible-p (&optional pos) |
| 444 | "Non-nil if the character after point is invisible." | 391 | "Non-nil if the character after POS is invisible. |
| 392 | If POS is nil, use `point' instead." | ||
| 445 | (get-char-property (or pos (point)) 'invisible)) | 393 | (get-char-property (or pos (point)) 'invisible)) |
| 446 | 394 | ||
| 447 | (defun outline-back-to-heading (&optional invisible-ok) | 395 | (defun outline-back-to-heading (&optional invisible-ok) |
| @@ -454,7 +402,7 @@ Only visible heading lines are considered, unless INVISIBLE-OK is non-nil." | |||
| 454 | (while (not found) | 402 | (while (not found) |
| 455 | (or (re-search-backward (concat "^\\(?:" outline-regexp "\\)") | 403 | (or (re-search-backward (concat "^\\(?:" outline-regexp "\\)") |
| 456 | nil t) | 404 | nil t) |
| 457 | (error "before first heading")) | 405 | (error "Before first heading")) |
| 458 | (setq found (and (or invisible-ok (not (outline-invisible-p))) | 406 | (setq found (and (or invisible-ok (not (outline-invisible-p))) |
| 459 | (point))))) | 407 | (point))))) |
| 460 | (goto-char found) | 408 | (goto-char found) |
| @@ -489,6 +437,9 @@ If INVISIBLE-OK is non-nil, an invisible heading line is ok too." | |||
| 489 | (run-hooks 'outline-insert-heading-hook))) | 437 | (run-hooks 'outline-insert-heading-hook))) |
| 490 | 438 | ||
| 491 | (defun outline-invent-heading (head up) | 439 | (defun outline-invent-heading (head up) |
| 440 | "Create a heading by using heading HEAD as a template. | ||
| 441 | When UP is non-nil, the created heading will be one level above. | ||
| 442 | Otherwise, it will be one level below." | ||
| 492 | (save-match-data | 443 | (save-match-data |
| 493 | ;; Let's try to invent one by repeating or deleting the last char. | 444 | ;; Let's try to invent one by repeating or deleting the last char. |
| 494 | (let ((new-head (if up (substring head 0 -1) | 445 | (let ((new-head (if up (substring head 0 -1) |
| @@ -504,7 +455,7 @@ If INVISIBLE-OK is non-nil, an invisible heading line is ok too." | |||
| 504 | 455 | ||
| 505 | (defun outline-promote (&optional which) | 456 | (defun outline-promote (&optional which) |
| 506 | "Promote headings higher up the tree. | 457 | "Promote headings higher up the tree. |
| 507 | If transient-mark-mode is on, and mark is active, promote headings in | 458 | If `transient-mark-mode' is on, and mark is active, promote headings in |
| 508 | the region (from a Lisp program, pass `region' for WHICH). Otherwise: | 459 | the region (from a Lisp program, pass `region' for WHICH). Otherwise: |
| 509 | without prefix argument, promote current heading and all headings in the | 460 | without prefix argument, promote current heading and all headings in the |
| 510 | subtree (from a Lisp program, pass `subtree' for WHICH); with prefix | 461 | subtree (from a Lisp program, pass `subtree' for WHICH); with prefix |
| @@ -543,7 +494,7 @@ nil for WHICH, or do not pass any argument)." | |||
| 543 | 494 | ||
| 544 | (defun outline-demote (&optional which) | 495 | (defun outline-demote (&optional which) |
| 545 | "Demote headings lower down the tree. | 496 | "Demote headings lower down the tree. |
| 546 | If transient-mark-mode is on, and mark is active, demote headings in | 497 | If `transient-mark-mode' is on, and mark is active, demote headings in |
| 547 | the region (from a Lisp program, pass `region' for WHICH). Otherwise: | 498 | the region (from a Lisp program, pass `region' for WHICH). Otherwise: |
| 548 | without prefix argument, demote current heading and all headings in the | 499 | without prefix argument, demote current heading and all headings in the |
| 549 | subtree (from a Lisp program, pass `subtree' for WHICH); with prefix | 500 | subtree (from a Lisp program, pass `subtree' for WHICH); with prefix |
| @@ -585,7 +536,7 @@ nil for WHICH, or do not pass any argument)." | |||
| 585 | (replace-match down-head nil t))))) | 536 | (replace-match down-head nil t))))) |
| 586 | 537 | ||
| 587 | (defun outline-head-from-level (level head &optional alist) | 538 | (defun outline-head-from-level (level head &optional alist) |
| 588 | "Get new heading with level LEVEL from ALIST. | 539 | "Get new heading with level LEVEL, closest to HEAD, from ALIST. |
| 589 | If there are no such entries, return nil. | 540 | If there are no such entries, return nil. |
| 590 | ALIST defaults to `outline-heading-alist'. | 541 | ALIST defaults to `outline-heading-alist'. |
| 591 | Similar to (car (rassoc LEVEL ALIST)). | 542 | Similar to (car (rassoc LEVEL ALIST)). |
| @@ -677,16 +628,17 @@ the match data is set appropriately." | |||
| 677 | (move-marker ins-point (point)) | 628 | (move-marker ins-point (point)) |
| 678 | (insert (delete-and-extract-region beg end)) | 629 | (insert (delete-and-extract-region beg end)) |
| 679 | (goto-char ins-point) | 630 | (goto-char ins-point) |
| 680 | (if folded (hide-subtree)) | 631 | (if folded (outline-hide-subtree)) |
| 681 | (move-marker ins-point nil))) | 632 | (move-marker ins-point nil))) |
| 682 | 633 | ||
| 683 | (defun outline-end-of-heading () | 634 | (defun outline-end-of-heading () |
| 635 | "Move to one char before the next `outline-heading-end-regexp'." | ||
| 684 | (if (re-search-forward outline-heading-end-regexp nil 'move) | 636 | (if (re-search-forward outline-heading-end-regexp nil 'move) |
| 685 | (forward-char -1))) | 637 | (forward-char -1))) |
| 686 | 638 | ||
| 687 | (defun outline-next-visible-heading (arg) | 639 | (defun outline-next-visible-heading (arg) |
| 688 | "Move to the next visible heading line. | 640 | "Move to the next visible heading line. |
| 689 | With argument, repeats or can move backward if negative. | 641 | With ARG, repeats or can move backward if negative. |
| 690 | A heading line is one that starts with a `*' (or that | 642 | A heading line is one that starts with a `*' (or that |
| 691 | `outline-regexp' matches)." | 643 | `outline-regexp' matches)." |
| 692 | (interactive "p") | 644 | (interactive "p") |
| @@ -714,7 +666,7 @@ A heading line is one that starts with a `*' (or that | |||
| 714 | 666 | ||
| 715 | (defun outline-previous-visible-heading (arg) | 667 | (defun outline-previous-visible-heading (arg) |
| 716 | "Move to the previous heading line. | 668 | "Move to the previous heading line. |
| 717 | With argument, repeats or can move forward if negative. | 669 | With ARG, repeats or can move forward if negative. |
| 718 | A heading line is one that starts with a `*' (or that | 670 | A heading line is one that starts with a `*' (or that |
| 719 | `outline-regexp' matches)." | 671 | `outline-regexp' matches)." |
| 720 | (interactive "p") | 672 | (interactive "p") |
| @@ -739,7 +691,7 @@ This puts point at the start of the current subtree, and mark at the end." | |||
| 739 | (defvar outline-isearch-open-invisible-function nil | 691 | (defvar outline-isearch-open-invisible-function nil |
| 740 | "Function called if `isearch' finishes in an invisible overlay. | 692 | "Function called if `isearch' finishes in an invisible overlay. |
| 741 | The function is called with the overlay as its only argument. | 693 | The function is called with the overlay as its only argument. |
| 742 | If nil, `show-entry' is called to reveal the invisible text.") | 694 | If nil, `outline-show-entry' is called to reveal the invisible text.") |
| 743 | 695 | ||
| 744 | (put 'outline 'reveal-toggle-invisible 'outline-reveal-toggle-invisible) | 696 | (put 'outline 'reveal-toggle-invisible 'outline-reveal-toggle-invisible) |
| 745 | (defun outline-flag-region (from to flag) | 697 | (defun outline-flag-region (from to flag) |
| @@ -763,51 +715,51 @@ If FLAG is nil then text is shown, while if FLAG is t the text is hidden." | |||
| 763 | (save-excursion | 715 | (save-excursion |
| 764 | (goto-char (overlay-start o)) | 716 | (goto-char (overlay-start o)) |
| 765 | (if hidep | 717 | (if hidep |
| 766 | ;; When hiding the area again, we could just clean it up and let | 718 | ;; When hiding the area again, we could just clean it up and let |
| 767 | ;; reveal do the rest, by simply doing: | 719 | ;; reveal do the rest, by simply doing: |
| 768 | ;; (remove-overlays (overlay-start o) (overlay-end o) | 720 | ;; (remove-overlays (overlay-start o) (overlay-end o) |
| 769 | ;; 'invisible 'outline) | 721 | ;; 'invisible 'outline) |
| 770 | ;; | 722 | ;; |
| 771 | ;; That works fine as long as everything is in sync, but if the | 723 | ;; That works fine as long as everything is in sync, but if the |
| 772 | ;; structure of the document is changed while revealing parts of it, | 724 | ;; structure of the document is changed while revealing parts of it, |
| 773 | ;; the resulting behavior can be ugly. I.e. we need to make | 725 | ;; the resulting behavior can be ugly. I.e. we need to make |
| 774 | ;; sure that we hide exactly a subtree. | 726 | ;; sure that we hide exactly a subtree. |
| 775 | (progn | 727 | (progn |
| 776 | (let ((end (overlay-end o))) | 728 | (let ((end (overlay-end o))) |
| 777 | (delete-overlay o) | 729 | (delete-overlay o) |
| 778 | (while (progn | 730 | (while (progn |
| 779 | (hide-subtree) | 731 | (outline-hide-subtree) |
| 780 | (outline-next-visible-heading 1) | 732 | (outline-next-visible-heading 1) |
| 781 | (and (not (eobp)) (< (point) end)))))) | 733 | (and (not (eobp)) (< (point) end)))))) |
| 782 | 734 | ||
| 783 | ;; When revealing, we just need to reveal sublevels. If point is | 735 | ;; When revealing, we just need to reveal sublevels. If point is |
| 784 | ;; inside one of the sublevels, reveal will call us again. | 736 | ;; inside one of the sublevels, reveal will call us again. |
| 785 | ;; But we need to preserve the original overlay. | 737 | ;; But we need to preserve the original overlay. |
| 786 | (let ((o1 (copy-overlay o))) | 738 | (let ((o1 (copy-overlay o))) |
| 787 | (overlay-put o 'invisible nil) ;Show (most of) the text. | 739 | (overlay-put o 'invisible nil) ;Show (most of) the text. |
| 788 | (while (progn | 740 | (while (progn |
| 789 | (show-entry) | 741 | (outline-show-entry) |
| 790 | (show-children) | 742 | (outline-show-children) |
| 791 | ;; Normally just the above is needed. | 743 | ;; Normally just the above is needed. |
| 792 | ;; But in odd cases, the above might fail to show anything. | 744 | ;; But in odd cases, the above might fail to show anything. |
| 793 | ;; To avoid an infinite loop, we have to make sure that | 745 | ;; To avoid an infinite loop, we have to make sure that |
| 794 | ;; *something* gets shown. | 746 | ;; *something* gets shown. |
| 795 | (and (equal (overlay-start o) (overlay-start o1)) | 747 | (and (equal (overlay-start o) (overlay-start o1)) |
| 796 | (< (point) (overlay-end o)) | 748 | (< (point) (overlay-end o)) |
| 797 | (= 0 (forward-line 1))))) | 749 | (= 0 (forward-line 1))))) |
| 798 | ;; If still nothing was shown, just kill the damn thing. | 750 | ;; If still nothing was shown, just kill the damn thing. |
| 799 | (when (equal (overlay-start o) (overlay-start o1)) | 751 | (when (equal (overlay-start o) (overlay-start o1)) |
| 800 | ;; I've seen it happen at the end of buffer. | 752 | ;; I've seen it happen at the end of buffer. |
| 801 | (delete-overlay o1)))))) | 753 | (delete-overlay o1)))))) |
| 802 | 754 | ||
| 803 | ;; Function to be set as an outline-isearch-open-invisible' property | 755 | ;; Function to be set as an outline-isearch-open-invisible' property |
| 804 | ;; to the overlay that makes the outline invisible (see | 756 | ;; to the overlay that makes the outline invisible (see |
| 805 | ;; `outline-flag-region'). | 757 | ;; `outline-flag-region'). |
| 806 | (defun outline-isearch-open-invisible (_overlay) | 758 | (defun outline-isearch-open-invisible (_overlay) |
| 807 | ;; We rely on the fact that isearch places point on the matched text. | 759 | ;; We rely on the fact that isearch places point on the matched text. |
| 808 | (show-entry)) | 760 | (outline-show-entry)) |
| 809 | 761 | ||
| 810 | (defun hide-entry () | 762 | (defun outline-hide-entry () |
| 811 | "Hide the body directly following this heading." | 763 | "Hide the body directly following this heading." |
| 812 | (interactive) | 764 | (interactive) |
| 813 | (save-excursion | 765 | (save-excursion |
| @@ -815,22 +767,31 @@ If FLAG is nil then text is shown, while if FLAG is t the text is hidden." | |||
| 815 | (outline-end-of-heading) | 767 | (outline-end-of-heading) |
| 816 | (outline-flag-region (point) (progn (outline-next-preface) (point)) t))) | 768 | (outline-flag-region (point) (progn (outline-next-preface) (point)) t))) |
| 817 | 769 | ||
| 818 | (defun show-entry () | 770 | (define-obsolete-function-alias |
| 771 | 'hide-entry 'outline-hide-entry "25.1") | ||
| 772 | |||
| 773 | (defun outline-show-entry () | ||
| 819 | "Show the body directly following this heading. | 774 | "Show the body directly following this heading. |
| 820 | Show the heading too, if it is currently invisible." | 775 | Show the heading too, if it is currently invisible." |
| 821 | (interactive) | 776 | (interactive) |
| 822 | (save-excursion | 777 | (save-excursion |
| 823 | (outline-back-to-heading t) | 778 | (outline-back-to-heading t) |
| 824 | (outline-flag-region (1- (point)) | 779 | (outline-flag-region (1- (point)) |
| 825 | (progn (outline-next-preface) (point)) nil))) | 780 | (progn (outline-next-preface) (point)) nil))) |
| 781 | |||
| 782 | (define-obsolete-function-alias | ||
| 783 | 'show-entry 'outline-show-entry "25.1") | ||
| 826 | 784 | ||
| 827 | (defun hide-body () | 785 | (defun outline-hide-body () |
| 828 | "Hide all body lines in buffer, leaving all headings visible." | 786 | "Hide all body lines in buffer, leaving all headings visible." |
| 829 | (interactive) | 787 | (interactive) |
| 830 | (hide-region-body (point-min) (point-max))) | 788 | (outline-hide-region-body (point-min) (point-max))) |
| 831 | 789 | ||
| 832 | (defun hide-region-body (start end) | 790 | (define-obsolete-function-alias |
| 833 | "Hide all body lines in the region, but not headings." | 791 | 'hide-body 'outline-hide-body "25.1") |
| 792 | |||
| 793 | (defun outline-hide-region-body (start end) | ||
| 794 | "Hide all body lines between START and END, but not headings." | ||
| 834 | ;; Nullify the hook to avoid repeated calls to `outline-flag-region' | 795 | ;; Nullify the hook to avoid repeated calls to `outline-flag-region' |
| 835 | ;; wasting lots of time running `lazy-lock-fontify-after-outline' | 796 | ;; wasting lots of time running `lazy-lock-fontify-after-outline' |
| 836 | ;; and run the hook finally. | 797 | ;; and run the hook finally. |
| @@ -850,30 +811,47 @@ Show the heading too, if it is currently invisible." | |||
| 850 | (outline-end-of-heading)))))) | 811 | (outline-end-of-heading)))))) |
| 851 | (run-hooks 'outline-view-change-hook)) | 812 | (run-hooks 'outline-view-change-hook)) |
| 852 | 813 | ||
| 853 | (defun show-all () | 814 | (define-obsolete-function-alias |
| 815 | 'hide-region-body 'outline-hide-region-body "25.1") | ||
| 816 | |||
| 817 | (defun outline-show-all () | ||
| 854 | "Show all of the text in the buffer." | 818 | "Show all of the text in the buffer." |
| 855 | (interactive) | 819 | (interactive) |
| 856 | (outline-flag-region (point-min) (point-max) nil)) | 820 | (outline-flag-region (point-min) (point-max) nil)) |
| 857 | 821 | ||
| 858 | (defun hide-subtree () | 822 | (define-obsolete-function-alias |
| 823 | 'show-all 'outline-show-all "25.1") | ||
| 824 | |||
| 825 | (defun outline-hide-subtree () | ||
| 859 | "Hide everything after this heading at deeper levels." | 826 | "Hide everything after this heading at deeper levels." |
| 860 | (interactive) | 827 | (interactive) |
| 861 | (outline-flag-subtree t)) | 828 | (outline-flag-subtree t)) |
| 862 | 829 | ||
| 863 | (defun hide-leaves () | 830 | (define-obsolete-function-alias |
| 831 | 'hide-subtree 'outline-hide-subtree "25.1") | ||
| 832 | |||
| 833 | (defun outline-hide-leaves () | ||
| 864 | "Hide the body after this heading and at deeper levels." | 834 | "Hide the body after this heading and at deeper levels." |
| 865 | (interactive) | 835 | (interactive) |
| 866 | (save-excursion | 836 | (save-excursion |
| 867 | (outline-back-to-heading) | 837 | (outline-back-to-heading) |
| 868 | ;; Turned off to fix bug reported by Otto Maddox on 22 Nov 2005. | 838 | ;; Turned off to fix bug reported by Otto Maddox on 22 Nov 2005. |
| 869 | ;; (outline-end-of-heading) | 839 | ;; (outline-end-of-heading) |
| 870 | (hide-region-body (point) (progn (outline-end-of-subtree) (point))))) | 840 | (outline-hide-region-body |
| 841 | (point) | ||
| 842 | (progn (outline-end-of-subtree) (point))))) | ||
| 843 | |||
| 844 | (define-obsolete-function-alias | ||
| 845 | 'hide-leaves 'outline-hide-leaves "25.1") | ||
| 871 | 846 | ||
| 872 | (defun show-subtree () | 847 | (defun outline-show-subtree () |
| 873 | "Show everything after this heading at deeper levels." | 848 | "Show everything after this heading at deeper levels." |
| 874 | (interactive) | 849 | (interactive) |
| 875 | (outline-flag-subtree nil)) | 850 | (outline-flag-subtree nil)) |
| 876 | 851 | ||
| 852 | (define-obsolete-function-alias | ||
| 853 | 'show-subtree 'outline-show-subtree "25.1") | ||
| 854 | |||
| 877 | (defun outline-show-heading () | 855 | (defun outline-show-heading () |
| 878 | "Show the current heading and move to its end." | 856 | "Show the current heading and move to its end." |
| 879 | (outline-flag-region (- (point) | 857 | (outline-flag-region (- (point) |
| @@ -884,7 +862,7 @@ Show the heading too, if it is currently invisible." | |||
| 884 | (progn (outline-end-of-heading) (point)) | 862 | (progn (outline-end-of-heading) (point)) |
| 885 | nil)) | 863 | nil)) |
| 886 | 864 | ||
| 887 | (defun hide-sublevels (levels) | 865 | (defun outline-hide-sublevels (levels) |
| 888 | "Hide everything but the top LEVELS levels of headers, in whole buffer." | 866 | "Hide everything but the top LEVELS levels of headers, in whole buffer." |
| 889 | (interactive (list | 867 | (interactive (list |
| 890 | (cond | 868 | (cond |
| @@ -922,14 +900,17 @@ Show the heading too, if it is currently invisible." | |||
| 922 | (outline-flag-region (1- (point)) (point) nil)))) | 900 | (outline-flag-region (1- (point)) (point) nil)))) |
| 923 | (run-hooks 'outline-view-change-hook)) | 901 | (run-hooks 'outline-view-change-hook)) |
| 924 | 902 | ||
| 925 | (defun hide-other () | 903 | (define-obsolete-function-alias |
| 904 | 'hide-sublevels 'outline-hide-sublevels "25.1") | ||
| 905 | |||
| 906 | (defun outline-hide-other () | ||
| 926 | "Hide everything except current body and parent and top-level headings." | 907 | "Hide everything except current body and parent and top-level headings." |
| 927 | (interactive) | 908 | (interactive) |
| 928 | (hide-sublevels 1) | 909 | (outline-hide-sublevels 1) |
| 929 | (let (outline-view-change-hook) | 910 | (let (outline-view-change-hook) |
| 930 | (save-excursion | 911 | (save-excursion |
| 931 | (outline-back-to-heading t) | 912 | (outline-back-to-heading t) |
| 932 | (show-entry) | 913 | (outline-show-entry) |
| 933 | (while (condition-case nil (progn (outline-up-heading 1 t) (not (bobp))) | 914 | (while (condition-case nil (progn (outline-up-heading 1 t) (not (bobp))) |
| 934 | (error nil)) | 915 | (error nil)) |
| 935 | (outline-flag-region (1- (point)) | 916 | (outline-flag-region (1- (point)) |
| @@ -937,17 +918,21 @@ Show the heading too, if it is currently invisible." | |||
| 937 | nil)))) | 918 | nil)))) |
| 938 | (run-hooks 'outline-view-change-hook)) | 919 | (run-hooks 'outline-view-change-hook)) |
| 939 | 920 | ||
| 921 | (define-obsolete-function-alias | ||
| 922 | 'hide-other 'outline-hide-other "25.1") | ||
| 923 | |||
| 940 | (defun outline-toggle-children () | 924 | (defun outline-toggle-children () |
| 941 | "Show or hide the current subtree depending on its current state." | 925 | "Show or hide the current subtree depending on its current state." |
| 942 | (interactive) | 926 | (interactive) |
| 943 | (save-excursion | 927 | (save-excursion |
| 944 | (outline-back-to-heading) | 928 | (outline-back-to-heading) |
| 945 | (if (not (outline-invisible-p (line-end-position))) | 929 | (if (not (outline-invisible-p (line-end-position))) |
| 946 | (hide-subtree) | 930 | (outline-hide-subtree) |
| 947 | (show-children) | 931 | (outline-show-children) |
| 948 | (show-entry)))) | 932 | (outline-show-entry)))) |
| 949 | 933 | ||
| 950 | (defun outline-flag-subtree (flag) | 934 | (defun outline-flag-subtree (flag) |
| 935 | "Assign FLAG to the current subtree." | ||
| 951 | (save-excursion | 936 | (save-excursion |
| 952 | (outline-back-to-heading) | 937 | (outline-back-to-heading) |
| 953 | (outline-end-of-heading) | 938 | (outline-end-of-heading) |
| @@ -956,6 +941,7 @@ Show the heading too, if it is currently invisible." | |||
| 956 | flag))) | 941 | flag))) |
| 957 | 942 | ||
| 958 | (defun outline-end-of-subtree () | 943 | (defun outline-end-of-subtree () |
| 944 | "Move to the end of the current subtree." | ||
| 959 | (outline-back-to-heading) | 945 | (outline-back-to-heading) |
| 960 | (let ((first t) | 946 | (let ((first t) |
| 961 | (level (funcall outline-level))) | 947 | (level (funcall outline-level))) |
| @@ -972,12 +958,15 @@ Show the heading too, if it is currently invisible." | |||
| 972 | ;; leave blank line before heading | 958 | ;; leave blank line before heading |
| 973 | (forward-char -1)))))) | 959 | (forward-char -1)))))) |
| 974 | 960 | ||
| 975 | (defun show-branches () | 961 | (defun outline-show-branches () |
| 976 | "Show all subheadings of this heading, but not their bodies." | 962 | "Show all subheadings of this heading, but not their bodies." |
| 977 | (interactive) | 963 | (interactive) |
| 978 | (show-children 1000)) | 964 | (outline-show-children 1000)) |
| 965 | |||
| 966 | (define-obsolete-function-alias | ||
| 967 | 'show-branches 'outline-show-branches "25.1") | ||
| 979 | 968 | ||
| 980 | (defun show-children (&optional level) | 969 | (defun outline-show-children (&optional level) |
| 981 | "Show all direct subheadings of this heading. | 970 | "Show all direct subheadings of this heading. |
| 982 | Prefix arg LEVEL is how many levels below the current level should be shown. | 971 | Prefix arg LEVEL is how many levels below the current level should be shown. |
| 983 | Default is enough to cause the following heading to appear." | 972 | Default is enough to cause the following heading to appear." |
| @@ -1004,6 +993,9 @@ Default is enough to cause the following heading to appear." | |||
| 1004 | (if (eobp) (point-max) (1+ (point))))))) | 993 | (if (eobp) (point-max) (1+ (point))))))) |
| 1005 | (run-hooks 'outline-view-change-hook)) | 994 | (run-hooks 'outline-view-change-hook)) |
| 1006 | 995 | ||
| 996 | (define-obsolete-function-alias | ||
| 997 | 'show-children 'outline-show-children "25.1") | ||
| 998 | |||
| 1007 | 999 | ||
| 1008 | 1000 | ||
| 1009 | (defun outline-up-heading (arg &optional invisible-ok) | 1001 | (defun outline-up-heading (arg &optional invisible-ok) |
| @@ -1086,7 +1078,7 @@ If there is no such heading, return nil." | |||
| 1086 | (point))))) | 1078 | (point))))) |
| 1087 | 1079 | ||
| 1088 | (defun outline-headers-as-kill (beg end) | 1080 | (defun outline-headers-as-kill (beg end) |
| 1089 | "Save the visible outline headers in region at the start of the kill ring. | 1081 | "Save the visible outline headers between BEG and END to the kill ring. |
| 1090 | 1082 | ||
| 1091 | Text shown between the headers isn't copied. Two newlines are | 1083 | Text shown between the headers isn't copied. Two newlines are |
| 1092 | inserted between saved headers. Yanking the result may be a | 1084 | inserted between saved headers. Yanking the result may be a |
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 13ff439bef2..d340550a017 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el | |||
| @@ -463,9 +463,14 @@ The type returned can be `comment', `string' or `paren'." | |||
| 463 | ((nth 8 ppss) (if (nth 4 ppss) 'comment 'string)) | 463 | ((nth 8 ppss) (if (nth 4 ppss) 'comment 'string)) |
| 464 | ((nth 1 ppss) 'paren)))) | 464 | ((nth 1 ppss) 'paren)))) |
| 465 | 465 | ||
| 466 | (defsubst python-syntax-comment-or-string-p () | 466 | (defsubst python-syntax-comment-or-string-p (&optional ppss) |
| 467 | "Return non-nil if point is inside 'comment or 'string." | 467 | "Return non-nil if PPSS is inside 'comment or 'string." |
| 468 | (nth 8 (syntax-ppss))) | 468 | (nth 8 (or ppss (syntax-ppss)))) |
| 469 | |||
| 470 | (defsubst python-syntax-closing-paren-p () | ||
| 471 | "Return non-nil if char after point is a closing paren." | ||
| 472 | (= (syntax-class (syntax-after (point))) | ||
| 473 | (syntax-class (string-to-syntax ")")))) | ||
| 469 | 474 | ||
| 470 | (define-obsolete-function-alias | 475 | (define-obsolete-function-alias |
| 471 | 'python-info-ppss-context #'python-syntax-context "24.3") | 476 | 'python-info-ppss-context #'python-syntax-context "24.3") |
| @@ -704,11 +709,28 @@ It makes underscores and dots word constituent chars.") | |||
| 704 | 'python-guess-indent 'python-indent-guess-indent-offset "24.3") | 709 | 'python-guess-indent 'python-indent-guess-indent-offset "24.3") |
| 705 | 710 | ||
| 706 | (defvar python-indent-current-level 0 | 711 | (defvar python-indent-current-level 0 |
| 707 | "Current indentation level `python-indent-line-function' is using.") | 712 | "Deprecated var available for compatibility.") |
| 708 | 713 | ||
| 709 | (defvar python-indent-levels '(0) | 714 | (defvar python-indent-levels '(0) |
| 710 | "Levels of indentation available for `python-indent-line-function'. | 715 | "Deprecated var available for compatibility.") |
| 711 | Can also be `noindent' if automatic indentation can't be used.") | 716 | |
| 717 | (make-obsolete-variable | ||
| 718 | 'python-indent-current-level | ||
| 719 | "The indentation API changed to avoid global state. | ||
| 720 | The function `python-indent-calculate-levels' does not use it | ||
| 721 | anymore. If you were defadvising it and or depended on this | ||
| 722 | variable for indentation customizations, refactor your code to | ||
| 723 | work on `python-indent-calculate-indentation' instead." | ||
| 724 | "24.5") | ||
| 725 | |||
| 726 | (make-obsolete-variable | ||
| 727 | 'python-indent-levels | ||
| 728 | "The indentation API changed to avoid global state. | ||
| 729 | The function `python-indent-calculate-levels' does not use it | ||
| 730 | anymore. If you were defadvising it and or depended on this | ||
| 731 | variable for indentation customizations, refactor your code to | ||
| 732 | work on `python-indent-calculate-indentation' instead." | ||
| 733 | "24.5") | ||
| 712 | 734 | ||
| 713 | (defun python-indent-guess-indent-offset () | 735 | (defun python-indent-guess-indent-offset () |
| 714 | "Guess and set `python-indent-offset' for the current buffer." | 736 | "Guess and set `python-indent-offset' for the current buffer." |
| @@ -748,362 +770,358 @@ Can also be `noindent' if automatic indentation can't be used.") | |||
| 748 | python-indent-offset))))))) | 770 | python-indent-offset))))))) |
| 749 | 771 | ||
| 750 | (defun python-indent-context () | 772 | (defun python-indent-context () |
| 751 | "Get information on indentation context. | 773 | "Get information about the current indentation context. |
| 752 | Context information is returned with a cons with the form: | 774 | Context is returned in a cons with the form (STATUS . START). |
| 753 | (STATUS . START) | 775 | |
| 754 | 776 | STATUS can be one of the following: | |
| 755 | Where status can be any of the following symbols: | 777 | |
| 756 | 778 | keyword | |
| 757 | * after-comment: When current line might continue a comment block | 779 | ------- |
| 758 | * inside-paren: If point in between (), {} or [] | 780 | |
| 759 | * inside-string: If point is inside a string | 781 | :after-comment |
| 760 | * after-backslash: Previous line ends in a backslash | 782 | - Point is after a comment line. |
| 761 | * after-beginning-of-block: Point is after beginning of block | 783 | - START is the position of the \"#\" character. |
| 762 | * after-line: Point is after normal line | 784 | :inside-string |
| 763 | * dedenter-statement: Point is on a dedenter statement. | 785 | - Point is inside string. |
| 764 | * no-indent: Point is at beginning of buffer or other special case | 786 | - START is the position of the first quote that starts it. |
| 765 | START is the buffer position where the sexp starts." | 787 | :no-indent |
| 788 | - No possible indentation case matches. | ||
| 789 | - START is always zero. | ||
| 790 | |||
| 791 | :inside-paren | ||
| 792 | - Fallback case when point is inside paren. | ||
| 793 | - START is the first non space char position *after* the open paren. | ||
| 794 | :inside-paren-at-closing-nested-paren | ||
| 795 | - Point is on a line that contains a nested paren closer. | ||
| 796 | - START is the position of the open paren it closes. | ||
| 797 | :inside-paren-at-closing-paren | ||
| 798 | - Point is on a line that contains a paren closer. | ||
| 799 | - START is the position of the open paren. | ||
| 800 | :inside-paren-newline-start | ||
| 801 | - Point is inside a paren with items starting in their own line. | ||
| 802 | - START is the position of the open paren. | ||
| 803 | :inside-paren-newline-start-from-block | ||
| 804 | - Point is inside a paren with items starting in their own line | ||
| 805 | from a block start. | ||
| 806 | - START is the position of the open paren. | ||
| 807 | |||
| 808 | :after-backslash | ||
| 809 | - Fallback case when point is after backslash. | ||
| 810 | - START is the char after the position of the backslash. | ||
| 811 | :after-backslash-assignment-continuation | ||
| 812 | - Point is after a backslashed assignment. | ||
| 813 | - START is the char after the position of the backslash. | ||
| 814 | :after-backslash-block-continuation | ||
| 815 | - Point is after a backslashed block continuation. | ||
| 816 | - START is the char after the position of the backslash. | ||
| 817 | :after-backslash-dotted-continuation | ||
| 818 | - Point is after a backslashed dotted continuation. Previous | ||
| 819 | line must contain a dot to align with. | ||
| 820 | - START is the char after the position of the backslash. | ||
| 821 | :after-backslash-first-line | ||
| 822 | - First line following a backslashed continuation. | ||
| 823 | - START is the char after the position of the backslash. | ||
| 824 | |||
| 825 | :after-block-end | ||
| 826 | - Point is after a line containing a block ender. | ||
| 827 | - START is the position where the ender starts. | ||
| 828 | :after-block-start | ||
| 829 | - Point is after a line starting a block. | ||
| 830 | - START is the position where the block starts. | ||
| 831 | :after-line | ||
| 832 | - Point is after a simple line. | ||
| 833 | - START is the position where the previous line starts. | ||
| 834 | :at-dedenter-block-start | ||
| 835 | - Point is on a line starting a dedenter block. | ||
| 836 | - START is the position where the dedenter block starts." | ||
| 766 | (save-restriction | 837 | (save-restriction |
| 767 | (widen) | 838 | (widen) |
| 768 | (let ((ppss (save-excursion (beginning-of-line) (syntax-ppss))) | 839 | (let ((ppss (save-excursion |
| 769 | (start)) | 840 | (beginning-of-line) |
| 770 | (cons | 841 | (syntax-ppss)))) |
| 771 | (cond | 842 | (cond |
| 772 | ;; Beginning of buffer | 843 | ;; Beginning of buffer. |
| 773 | ((save-excursion | 844 | ((= (line-number-at-pos) 1) |
| 774 | (goto-char (line-beginning-position)) | 845 | (cons :no-indent 0)) |
| 775 | (bobp)) | 846 | ;; Comment continuation (maybe). |
| 776 | 'no-indent) | 847 | ((save-excursion |
| 777 | ;; Comment continuation | 848 | (when (and |
| 778 | ((save-excursion | 849 | (or |
| 779 | (when (and | 850 | (python-info-current-line-comment-p) |
| 780 | (or | 851 | (python-info-current-line-empty-p)) |
| 781 | (python-info-current-line-comment-p) | 852 | (forward-comment -1) |
| 782 | (python-info-current-line-empty-p)) | 853 | (python-info-current-line-comment-p)) |
| 783 | (progn | 854 | (cons :after-comment (point))))) |
| 784 | (forward-comment -1) | 855 | ;; Inside a string. |
| 785 | (python-info-current-line-comment-p))) | 856 | ((let ((start (python-syntax-context 'string ppss))) |
| 786 | (setq start (point)) | 857 | (when start |
| 787 | 'after-comment))) | 858 | (cons :inside-string start)))) |
| 788 | ;; Inside string | 859 | ;; Inside a paren. |
| 789 | ((setq start (python-syntax-context 'string ppss)) | 860 | ((let* ((start (python-syntax-context 'paren ppss)) |
| 790 | 'inside-string) | 861 | (starts-in-newline |
| 791 | ;; Inside a paren | 862 | (when start |
| 792 | ((setq start (python-syntax-context 'paren ppss)) | 863 | (save-excursion |
| 793 | 'inside-paren) | 864 | (goto-char start) |
| 794 | ;; After backslash | 865 | (forward-char) |
| 795 | ((setq start (when (not (or (python-syntax-context 'string ppss) | 866 | (not |
| 796 | (python-syntax-context 'comment ppss))) | 867 | (= (line-number-at-pos) |
| 797 | (let ((line-beg-pos (line-number-at-pos))) | 868 | (progn |
| 798 | (python-info-line-ends-backslash-p | 869 | (python-util-forward-comment) |
| 799 | (1- line-beg-pos))))) | 870 | (line-number-at-pos)))))))) |
| 800 | 'after-backslash) | 871 | (when start |
| 801 | ;; After beginning of block | 872 | (cond |
| 802 | ((setq start (save-excursion | 873 | ;; Current line only holds the closing paren. |
| 803 | (when (progn | 874 | ((save-excursion |
| 804 | (back-to-indentation) | 875 | (skip-syntax-forward " ") |
| 805 | (python-util-forward-comment -1) | 876 | (when (and (python-syntax-closing-paren-p) |
| 806 | (equal (char-before) ?:)) | 877 | (progn |
| 807 | ;; Move to the first block start that's not in within | 878 | (forward-char 1) |
| 808 | ;; a string, comment or paren and that's not a | 879 | (not (python-syntax-context 'paren)))) |
| 809 | ;; continuation line. | 880 | (cons :inside-paren-at-closing-paren start)))) |
| 810 | (while (and (re-search-backward | 881 | ;; Current line only holds a closing paren for nested. |
| 811 | (python-rx block-start) nil t) | 882 | ((save-excursion |
| 812 | (or | 883 | (back-to-indentation) |
| 813 | (python-syntax-context-type) | 884 | (python-syntax-closing-paren-p)) |
| 814 | (python-info-continuation-line-p)))) | 885 | (cons :inside-paren-at-closing-nested-paren start)) |
| 815 | (when (looking-at (python-rx block-start)) | 886 | ;; This line starts from a opening block in its own line. |
| 816 | (point-marker))))) | 887 | ((save-excursion |
| 817 | 'after-beginning-of-block) | 888 | (goto-char start) |
| 818 | ((when (setq start (python-info-dedenter-statement-p)) | 889 | (when (and |
| 819 | 'dedenter-statement)) | 890 | starts-in-newline |
| 820 | ;; After normal line | 891 | (save-excursion |
| 821 | ((setq start (save-excursion | 892 | (back-to-indentation) |
| 893 | (looking-at (python-rx block-start)))) | ||
| 894 | (cons | ||
| 895 | :inside-paren-newline-start-from-block start)))) | ||
| 896 | (starts-in-newline | ||
| 897 | (cons :inside-paren-newline-start start)) | ||
| 898 | ;; General case. | ||
| 899 | (t (cons :inside-paren | ||
| 900 | (save-excursion | ||
| 901 | (goto-char (1+ start)) | ||
| 902 | (skip-syntax-forward "(" 1) | ||
| 903 | (skip-syntax-forward " ") | ||
| 904 | (point)))))))) | ||
| 905 | ;; After backslash. | ||
| 906 | ((let ((start (when (not (python-syntax-comment-or-string-p ppss)) | ||
| 907 | (python-info-line-ends-backslash-p | ||
| 908 | (1- (line-number-at-pos)))))) | ||
| 909 | (when start | ||
| 910 | (cond | ||
| 911 | ;; Continuation of dotted expression. | ||
| 912 | ((save-excursion | ||
| 913 | (back-to-indentation) | ||
| 914 | (when (eq (char-after) ?\.) | ||
| 915 | ;; Move point back until it's not inside a paren. | ||
| 916 | (while (prog2 | ||
| 917 | (forward-line -1) | ||
| 918 | (and (not (bobp)) | ||
| 919 | (python-syntax-context 'paren)))) | ||
| 920 | (goto-char (line-end-position)) | ||
| 921 | (while (and (search-backward | ||
| 922 | "." (line-beginning-position) t) | ||
| 923 | (python-syntax-context-type))) | ||
| 924 | ;; Ensure previous statement has dot to align with. | ||
| 925 | (when (and (eq (char-after) ?\.) | ||
| 926 | (not (python-syntax-context-type))) | ||
| 927 | (cons :after-backslash-dotted-continuation (point)))))) | ||
| 928 | ;; Continuation of block definition. | ||
| 929 | ((let ((block-continuation-start | ||
| 930 | (python-info-block-continuation-line-p))) | ||
| 931 | (when block-continuation-start | ||
| 932 | (save-excursion | ||
| 933 | (goto-char block-continuation-start) | ||
| 934 | (re-search-forward | ||
| 935 | (python-rx block-start (* space)) | ||
| 936 | (line-end-position) t) | ||
| 937 | (cons :after-backslash-block-continuation (point)))))) | ||
| 938 | ;; Continuation of assignment. | ||
| 939 | ((let ((assignment-continuation-start | ||
| 940 | (python-info-assignment-continuation-line-p))) | ||
| 941 | (when assignment-continuation-start | ||
| 942 | (save-excursion | ||
| 943 | (goto-char assignment-continuation-start) | ||
| 944 | (cons :after-backslash-assignment-continuation (point)))))) | ||
| 945 | ;; First line after backslash continuation start. | ||
| 946 | ((save-excursion | ||
| 947 | (goto-char start) | ||
| 948 | (when (or (= (line-number-at-pos) 1) | ||
| 949 | (not (python-info-beginning-of-backslash | ||
| 950 | (1- (line-number-at-pos))))) | ||
| 951 | (cons :after-backslash-first-line start)))) | ||
| 952 | ;; General case. | ||
| 953 | (t (cons :after-backslash start)))))) | ||
| 954 | ;; After beginning of block. | ||
| 955 | ((let ((start (save-excursion | ||
| 956 | (back-to-indentation) | ||
| 957 | (python-util-forward-comment -1) | ||
| 958 | (when (equal (char-before) ?:) | ||
| 959 | (python-nav-beginning-of-block))))) | ||
| 960 | (when start | ||
| 961 | (cons :after-block-start start)))) | ||
| 962 | ;; At dedenter statement. | ||
| 963 | ((let ((start (python-info-dedenter-statement-p))) | ||
| 964 | (when start | ||
| 965 | (cons :at-dedenter-block-start start)))) | ||
| 966 | ;; After normal line. | ||
| 967 | ((let ((start (save-excursion | ||
| 822 | (back-to-indentation) | 968 | (back-to-indentation) |
| 823 | (skip-chars-backward (rx (or whitespace ?\n))) | 969 | (skip-chars-backward " \t\n") |
| 824 | (python-nav-beginning-of-statement) | 970 | (python-nav-beginning-of-statement) |
| 825 | (point-marker))) | 971 | (point)))) |
| 826 | 'after-line) | 972 | (when start |
| 827 | ;; Do not indent | 973 | (if (save-excursion |
| 828 | (t 'no-indent)) | 974 | (python-util-forward-comment -1) |
| 829 | start)))) | 975 | (python-nav-beginning-of-statement) |
| 830 | 976 | (looking-at (python-rx block-ender))) | |
| 831 | (defun python-indent-calculate-indentation () | 977 | (cons :after-block-end start) |
| 832 | "Calculate correct indentation offset for the current line. | 978 | (cons :after-line start))))) |
| 833 | Returns `noindent' if the indentation does not depend on Python syntax, | 979 | ;; Default case: do not indent. |
| 834 | such as in strings." | 980 | (t (cons :no-indent 0)))))) |
| 835 | (let* ((indentation-context (python-indent-context)) | 981 | |
| 836 | (context-status (car indentation-context)) | 982 | (defun python-indent--calculate-indentation () |
| 837 | (context-start (cdr indentation-context))) | 983 | "Internal implementation of `python-indent-calculate-indentation'. |
| 838 | (save-restriction | 984 | May return an integer for the maximum possible indentation at |
| 839 | (widen) | 985 | current context or a list of integers. The latter case is only |
| 840 | (save-excursion | 986 | happening for :at-dedenter-block-start context since the |
| 841 | (pcase context-status | 987 | possibilities can be narrowed to especific indentation points." |
| 842 | (`no-indent 0) | 988 | (save-restriction |
| 843 | (`after-comment | 989 | (widen) |
| 844 | (goto-char context-start) | 990 | (save-excursion |
| 845 | (current-indentation)) | 991 | (pcase (python-indent-context) |
| 846 | ;; When point is after beginning of block just add one level | 992 | (`(:no-indent . ,_) 0) |
| 847 | ;; of indentation relative to the context-start | 993 | (`(,(or :after-line |
| 848 | (`after-beginning-of-block | 994 | :after-comment |
| 849 | (goto-char context-start) | 995 | :inside-string |
| 850 | (+ (current-indentation) python-indent-offset)) | 996 | :after-backslash |
| 851 | ;; When after a simple line just use previous line | 997 | :inside-paren-at-closing-paren |
| 852 | ;; indentation. | 998 | :inside-paren-at-closing-nested-paren) . ,start) |
| 853 | (`after-line | 999 | ;; Copy previous indentation. |
| 854 | (let* ((pair (save-excursion | 1000 | (goto-char start) |
| 855 | (goto-char context-start) | 1001 | (current-indentation)) |
| 856 | (cons | 1002 | (`(,(or :after-block-start |
| 857 | (current-indentation) | 1003 | :after-backslash-first-line |
| 858 | (python-info-beginning-of-block-p)))) | 1004 | :inside-paren-newline-start) . ,start) |
| 859 | (context-indentation (car pair)) | 1005 | ;; Add one indentation level. |
| 860 | ;; TODO: Separate block enders into its own case. | 1006 | (goto-char start) |
| 861 | (adjustment | 1007 | (+ (current-indentation) python-indent-offset)) |
| 862 | (if (save-excursion | 1008 | (`(,(or :inside-paren |
| 863 | (python-util-forward-comment -1) | 1009 | :after-backslash-block-continuation |
| 864 | (python-nav-beginning-of-statement) | 1010 | :after-backslash-assignment-continuation |
| 865 | (looking-at (python-rx block-ender))) | 1011 | :after-backslash-dotted-continuation) . ,start) |
| 866 | python-indent-offset | 1012 | ;; Use the column given by the context. |
| 867 | 0))) | 1013 | (goto-char start) |
| 868 | (- context-indentation adjustment))) | 1014 | (current-column)) |
| 869 | ;; When point is on a dedenter statement, search for the | 1015 | (`(:after-block-end . ,start) |
| 870 | ;; opening block that corresponds to it and use its | 1016 | ;; Subtract one indentation level. |
| 871 | ;; indentation. If no opening block is found just remove | 1017 | (goto-char start) |
| 872 | ;; indentation as this is an invalid python file. | 1018 | (- (current-indentation) python-indent-offset)) |
| 873 | (`dedenter-statement | 1019 | (`(:at-dedenter-block-start . ,_) |
| 874 | (let ((block-start-point | 1020 | ;; List all possible indentation levels from opening blocks. |
| 875 | (python-info-dedenter-opening-block-position))) | 1021 | (let ((opening-block-start-points |
| 876 | (save-excursion | 1022 | (python-info-dedenter-opening-block-positions))) |
| 877 | (if (not block-start-point) | 1023 | (if (not opening-block-start-points) |
| 878 | 0 | 1024 | 0 ; if not found default to first column |
| 879 | (goto-char block-start-point) | 1025 | (mapcar (lambda (pos) |
| 880 | (current-indentation))))) | 1026 | (save-excursion |
| 881 | ;; When inside of a string, do nothing. just use the current | 1027 | (goto-char pos) |
| 882 | ;; indentation. XXX: perhaps it would be a good idea to | 1028 | (current-indentation))) |
| 883 | ;; invoke standard text indentation here | 1029 | opening-block-start-points)))) |
| 884 | (`inside-string 'noindent) | 1030 | (`(,(or :inside-paren-newline-start-from-block) . ,start) |
| 885 | ;; After backslash we have several possibilities. | 1031 | ;; Add two indentation levels to make the suite stand out. |
| 886 | (`after-backslash | 1032 | (goto-char start) |
| 887 | (cond | 1033 | (+ (current-indentation) (* python-indent-offset 2))))))) |
| 888 | ;; Check if current line is a dot continuation. For this | 1034 | |
| 889 | ;; the current line must start with a dot and previous | 1035 | (defun python-indent--calculate-levels (indentation) |
| 890 | ;; line must contain a dot too. | 1036 | "Calculate levels list given INDENTATION. |
| 891 | ((save-excursion | 1037 | Argument INDENTATION can either be an integer or a list of |
| 892 | (back-to-indentation) | 1038 | integers. Levels are returned in ascending order, and in the |
| 893 | (when (looking-at "\\.") | 1039 | case INDENTATION is a list, this order is enforced." |
| 894 | ;; If after moving one line back point is inside a paren it | 1040 | (if (listp indentation) |
| 895 | ;; needs to move back until it's not anymore | 1041 | (sort (copy-sequence indentation) #'<) |
| 896 | (while (prog2 | 1042 | (let* ((remainder (% indentation python-indent-offset)) |
| 897 | (forward-line -1) | 1043 | (steps (/ (- indentation remainder) python-indent-offset)) |
| 898 | (and (not (bobp)) | 1044 | (levels (mapcar (lambda (step) |
| 899 | (python-syntax-context 'paren)))) | 1045 | (* python-indent-offset step)) |
| 900 | (goto-char (line-end-position)) | 1046 | (number-sequence steps 0 -1)))) |
| 901 | (while (and (re-search-backward | 1047 | (reverse |
| 902 | "\\." (line-beginning-position) t) | 1048 | (if (not (zerop remainder)) |
| 903 | (python-syntax-context-type))) | 1049 | (cons indentation levels) |
| 904 | (if (and (looking-at "\\.") | 1050 | levels))))) |
| 905 | (not (python-syntax-context-type))) | 1051 | |
| 906 | ;; The indentation is the same column of the | 1052 | (defun python-indent--previous-level (levels indentation) |
| 907 | ;; first matching dot that's not inside a | 1053 | "Return previous level from LEVELS relative to INDENTATION." |
| 908 | ;; comment, a string or a paren | 1054 | (let* ((levels (sort (copy-sequence levels) #'>)) |
| 909 | (current-column) | 1055 | (default (car levels))) |
| 910 | ;; No dot found on previous line, just add another | 1056 | (catch 'return |
| 911 | ;; indentation level. | 1057 | (dolist (level levels) |
| 912 | (+ (current-indentation) python-indent-offset))))) | 1058 | (when (funcall #'< level indentation) |
| 913 | ;; Check if prev line is a block continuation | 1059 | (throw 'return level))) |
| 914 | ((let ((block-continuation-start | 1060 | default))) |
| 915 | (python-info-block-continuation-line-p))) | 1061 | |
| 916 | (when block-continuation-start | 1062 | (defun python-indent-calculate-indentation (&optional previous) |
| 917 | ;; If block-continuation-start is set jump to that | 1063 | "Calculate indentation. |
| 918 | ;; marker and use first column after the block start | 1064 | Get indentation of PREVIOUS level when argument is non-nil. |
| 919 | ;; as indentation value. | 1065 | Return the max level of the cycle when indentation reaches the |
| 920 | (goto-char block-continuation-start) | 1066 | minimum." |
| 921 | (re-search-forward | 1067 | (let* ((indentation (python-indent--calculate-indentation)) |
| 922 | (python-rx block-start (* space)) | 1068 | (levels (python-indent--calculate-levels indentation))) |
| 923 | (line-end-position) t) | 1069 | (if previous |
| 924 | (current-column)))) | 1070 | (python-indent--previous-level levels (current-indentation)) |
| 925 | ;; Check if current line is an assignment continuation | 1071 | (apply #'max levels)))) |
| 926 | ((let ((assignment-continuation-start | 1072 | |
| 927 | (python-info-assignment-continuation-line-p))) | 1073 | (defun python-indent-line (&optional previous) |
| 928 | (when assignment-continuation-start | ||
| 929 | ;; If assignment-continuation is set jump to that | ||
| 930 | ;; marker and use first column after the assignment | ||
| 931 | ;; operator as indentation value. | ||
| 932 | (goto-char assignment-continuation-start) | ||
| 933 | (current-column)))) | ||
| 934 | (t | ||
| 935 | (forward-line -1) | ||
| 936 | (goto-char (python-info-beginning-of-backslash)) | ||
| 937 | (if (save-excursion | ||
| 938 | (and | ||
| 939 | (forward-line -1) | ||
| 940 | (goto-char | ||
| 941 | (or (python-info-beginning-of-backslash) (point))) | ||
| 942 | (python-info-line-ends-backslash-p))) | ||
| 943 | ;; The two previous lines ended in a backslash so we must | ||
| 944 | ;; respect previous line indentation. | ||
| 945 | (current-indentation) | ||
| 946 | ;; What happens here is that we are dealing with the second | ||
| 947 | ;; line of a backslash continuation, in that case we just going | ||
| 948 | ;; to add one indentation level. | ||
| 949 | (+ (current-indentation) python-indent-offset))))) | ||
| 950 | ;; When inside a paren there's a need to handle nesting | ||
| 951 | ;; correctly | ||
| 952 | (`inside-paren | ||
| 953 | (cond | ||
| 954 | ;; If current line closes the outermost open paren use the | ||
| 955 | ;; current indentation of the context-start line. | ||
| 956 | ((save-excursion | ||
| 957 | (skip-syntax-forward "\s" (line-end-position)) | ||
| 958 | (when (and (looking-at (regexp-opt '(")" "]" "}"))) | ||
| 959 | (progn | ||
| 960 | (forward-char 1) | ||
| 961 | (not (python-syntax-context 'paren)))) | ||
| 962 | (goto-char context-start) | ||
| 963 | (current-indentation)))) | ||
| 964 | ;; If open paren is contained on a line by itself add another | ||
| 965 | ;; indentation level, else look for the first word after the | ||
| 966 | ;; opening paren and use it's column position as indentation | ||
| 967 | ;; level. | ||
| 968 | ((let* ((content-starts-in-newline) | ||
| 969 | (indent | ||
| 970 | (save-excursion | ||
| 971 | (if (setq content-starts-in-newline | ||
| 972 | (progn | ||
| 973 | (goto-char context-start) | ||
| 974 | (forward-char) | ||
| 975 | (save-restriction | ||
| 976 | (narrow-to-region | ||
| 977 | (line-beginning-position) | ||
| 978 | (line-end-position)) | ||
| 979 | (python-util-forward-comment)) | ||
| 980 | (looking-at "$"))) | ||
| 981 | (+ (current-indentation) python-indent-offset) | ||
| 982 | (current-column))))) | ||
| 983 | ;; Adjustments | ||
| 984 | (cond | ||
| 985 | ;; If current line closes a nested open paren de-indent one | ||
| 986 | ;; level. | ||
| 987 | ((progn | ||
| 988 | (back-to-indentation) | ||
| 989 | (looking-at (regexp-opt '(")" "]" "}")))) | ||
| 990 | (- indent python-indent-offset)) | ||
| 991 | ;; If the line of the opening paren that wraps the current | ||
| 992 | ;; line starts a block add another level of indentation to | ||
| 993 | ;; follow new pep8 recommendation. See: http://ur1.ca/5rojx | ||
| 994 | ((save-excursion | ||
| 995 | (when (and content-starts-in-newline | ||
| 996 | (progn | ||
| 997 | (goto-char context-start) | ||
| 998 | (back-to-indentation) | ||
| 999 | (looking-at (python-rx block-start)))) | ||
| 1000 | (+ indent python-indent-offset)))) | ||
| 1001 | (t indent))))))))))) | ||
| 1002 | |||
| 1003 | (defun python-indent-calculate-levels () | ||
| 1004 | "Calculate `python-indent-levels' and reset `python-indent-current-level'." | ||
| 1005 | (if (or (python-info-continuation-line-p) | ||
| 1006 | (not (python-info-dedenter-statement-p))) | ||
| 1007 | ;; XXX: This asks for a refactor. Even if point is on a | ||
| 1008 | ;; dedenter statement, it could be multiline and in that case | ||
| 1009 | ;; the continuation lines should be indented with normal rules. | ||
| 1010 | (let* ((indentation (python-indent-calculate-indentation))) | ||
| 1011 | (if (not (numberp indentation)) | ||
| 1012 | (setq python-indent-levels indentation) | ||
| 1013 | (let* ((remainder (% indentation python-indent-offset)) | ||
| 1014 | (steps (/ (- indentation remainder) python-indent-offset))) | ||
| 1015 | (setq python-indent-levels (list 0)) | ||
| 1016 | (dotimes (step steps) | ||
| 1017 | (push (* python-indent-offset (1+ step)) python-indent-levels)) | ||
| 1018 | (when (not (eq 0 remainder)) | ||
| 1019 | (push (+ (* python-indent-offset steps) remainder) | ||
| 1020 | python-indent-levels))))) | ||
| 1021 | (setq python-indent-levels | ||
| 1022 | (or | ||
| 1023 | (mapcar (lambda (pos) | ||
| 1024 | (save-excursion | ||
| 1025 | (goto-char pos) | ||
| 1026 | (current-indentation))) | ||
| 1027 | (python-info-dedenter-opening-block-positions)) | ||
| 1028 | (list 0)))) | ||
| 1029 | (when (listp python-indent-levels) | ||
| 1030 | (setq python-indent-current-level (1- (length python-indent-levels)) | ||
| 1031 | python-indent-levels (nreverse python-indent-levels)))) | ||
| 1032 | |||
| 1033 | (defun python-indent-toggle-levels () | ||
| 1034 | "Toggle `python-indent-current-level' over `python-indent-levels'." | ||
| 1035 | (setq python-indent-current-level (1- python-indent-current-level)) | ||
| 1036 | (when (< python-indent-current-level 0) | ||
| 1037 | (setq python-indent-current-level (1- (length python-indent-levels))))) | ||
| 1038 | |||
| 1039 | (defun python-indent-line (&optional force-toggle) | ||
| 1040 | "Internal implementation of `python-indent-line-function'. | 1074 | "Internal implementation of `python-indent-line-function'. |
| 1041 | Uses the offset calculated in | 1075 | Use the PREVIOUS level when argument is non-nil, otherwise indent |
| 1042 | `python-indent-calculate-indentation' and available levels | 1076 | to the maxium available level. When indentation is the minimum |
| 1043 | indicated by the variable `python-indent-levels' to set the | 1077 | possible and PREVIOUS is non-nil, cycle back to the maximum |
| 1044 | current indentation. | 1078 | level." |
| 1079 | (let ((follow-indentation-p | ||
| 1080 | ;; Check if point is within indentation. | ||
| 1081 | (and (<= (line-beginning-position) (point)) | ||
| 1082 | (>= (+ (line-beginning-position) | ||
| 1083 | (current-indentation)) | ||
| 1084 | (point))))) | ||
| 1085 | (save-excursion | ||
| 1086 | (indent-line-to | ||
| 1087 | (python-indent-calculate-indentation previous)) | ||
| 1088 | (python-info-dedenter-opening-block-message)) | ||
| 1089 | (when follow-indentation-p | ||
| 1090 | (back-to-indentation)))) | ||
| 1045 | 1091 | ||
| 1046 | When the variable `last-command' is equal to one of the symbols | 1092 | (defun python-indent-calculate-levels () |
| 1047 | inside `python-indent-trigger-commands' or FORCE-TOGGLE is | 1093 | "Return possible indentation levels." |
| 1048 | non-nil it cycles levels indicated in the variable | 1094 | (python-indent--calculate-levels |
| 1049 | `python-indent-levels' by setting the current level in the | 1095 | (python-indent--calculate-indentation))) |
| 1050 | variable `python-indent-current-level'. | ||
| 1051 | |||
| 1052 | When the variable `last-command' is not equal to one of the | ||
| 1053 | symbols inside `python-indent-trigger-commands' and FORCE-TOGGLE | ||
| 1054 | is nil it calculates possible indentation levels and saves them | ||
| 1055 | in the variable `python-indent-levels'. Afterwards it sets the | ||
| 1056 | variable `python-indent-current-level' correctly so offset is | ||
| 1057 | equal to | ||
| 1058 | (nth python-indent-current-level python-indent-levels)" | ||
| 1059 | (if (and (or (and (memq this-command python-indent-trigger-commands) | ||
| 1060 | (eq last-command this-command)) | ||
| 1061 | force-toggle) | ||
| 1062 | (not (equal python-indent-levels '(0)))) | ||
| 1063 | (if (listp python-indent-levels) | ||
| 1064 | (python-indent-toggle-levels)) | ||
| 1065 | (python-indent-calculate-levels)) | ||
| 1066 | (if (eq python-indent-levels 'noindent) | ||
| 1067 | python-indent-levels | ||
| 1068 | (let* ((starting-pos (point-marker)) | ||
| 1069 | (indent-ending-position | ||
| 1070 | (+ (line-beginning-position) (current-indentation))) | ||
| 1071 | (follow-indentation-p | ||
| 1072 | (or (bolp) | ||
| 1073 | (and (<= (line-beginning-position) starting-pos) | ||
| 1074 | (>= indent-ending-position starting-pos)))) | ||
| 1075 | (next-indent (nth python-indent-current-level python-indent-levels))) | ||
| 1076 | (unless (= next-indent (current-indentation)) | ||
| 1077 | (beginning-of-line) | ||
| 1078 | (delete-horizontal-space) | ||
| 1079 | (indent-to next-indent) | ||
| 1080 | (goto-char starting-pos)) | ||
| 1081 | (and follow-indentation-p (back-to-indentation))) | ||
| 1082 | (python-info-dedenter-opening-block-message))) | ||
| 1083 | 1096 | ||
| 1084 | (defun python-indent-line-function () | 1097 | (defun python-indent-line-function () |
| 1085 | "`indent-line-function' for Python mode. | 1098 | "`indent-line-function' for Python mode. |
| 1086 | See `python-indent-line' for details." | 1099 | When the variable `last-command' is equal to one of the symbols |
| 1087 | (python-indent-line)) | 1100 | inside `python-indent-trigger-commands' it cycles possible |
| 1101 | indentation levels from right to left." | ||
| 1102 | (python-indent-line | ||
| 1103 | (and (memq this-command python-indent-trigger-commands) | ||
| 1104 | (eq last-command this-command)))) | ||
| 1088 | 1105 | ||
| 1089 | (defun python-indent-dedent-line () | 1106 | (defun python-indent-dedent-line () |
| 1090 | "De-indent current line." | 1107 | "De-indent current line." |
| 1091 | (interactive "*") | 1108 | (interactive "*") |
| 1092 | (when (and (not (python-syntax-comment-or-string-p)) | 1109 | (when (and (not (bolp)) |
| 1093 | (<= (point) (save-excursion | 1110 | (not (python-syntax-comment-or-string-p)) |
| 1094 | (back-to-indentation) | 1111 | (= (+ (line-beginning-position) |
| 1095 | (point))) | 1112 | (current-indentation)) |
| 1096 | (> (current-column) 0)) | 1113 | (point))) |
| 1097 | (python-indent-line t) | 1114 | (python-indent-line t) |
| 1098 | t)) | 1115 | t)) |
| 1099 | 1116 | ||
| 1100 | (defun python-indent-dedent-line-backspace (arg) | 1117 | (defun python-indent-dedent-line-backspace (arg) |
| 1101 | "De-indent current line. | 1118 | "De-indent current line. |
| 1102 | Argument ARG is passed to `backward-delete-char-untabify' when | 1119 | Argument ARG is passed to `backward-delete-char-untabify' when |
| 1103 | point is not in between the indentation." | 1120 | point is not in between the indentation." |
| 1104 | (interactive "*p") | 1121 | (interactive "*p") |
| 1105 | (when (not (python-indent-dedent-line)) | 1122 | (unless (python-indent-dedent-line) |
| 1106 | (backward-delete-char-untabify arg))) | 1123 | (backward-delete-char-untabify arg))) |
| 1124 | |||
| 1107 | (put 'python-indent-dedent-line-backspace 'delete-selection 'supersede) | 1125 | (put 'python-indent-dedent-line-backspace 'delete-selection 'supersede) |
| 1108 | 1126 | ||
| 1109 | (defun python-indent-region (start end) | 1127 | (defun python-indent-region (start end) |
diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el index e8b6bf5adf7..135f945dbb9 100644 --- a/lisp/progmodes/sh-script.el +++ b/lisp/progmodes/sh-script.el | |||
| @@ -1,7 +1,6 @@ | |||
| 1 | ;;; sh-script.el --- shell-script editing commands for Emacs -*- lexical-binding:t -*- | 1 | ;;; sh-script.el --- shell-script editing commands for Emacs -*- lexical-binding:t -*- |
| 2 | 2 | ||
| 3 | ;; Copyright (C) 1993-1997, 1999, 2001-2015 Free Software Foundation, | 3 | ;; Copyright (C) 1993-1997, 1999, 2001-2015 Free Software Foundation, Inc. |
| 4 | ;; Inc. | ||
| 5 | 4 | ||
| 6 | ;; Author: Daniel Pfeiffer <occitan@esperanto.org> | 5 | ;; Author: Daniel Pfeiffer <occitan@esperanto.org> |
| 7 | ;; Version: 2.0f | 6 | ;; Version: 2.0f |
| @@ -1599,7 +1598,6 @@ buffer indents as it currently is indented. | |||
| 1599 | 1598 | ||
| 1600 | 1599 | ||
| 1601 | \\[backward-delete-char-untabify] Delete backward one position, even if it was a tab. | 1600 | \\[backward-delete-char-untabify] Delete backward one position, even if it was a tab. |
| 1602 | \\[newline-and-indent] Delete unquoted space and indent new line same as this one. | ||
| 1603 | \\[sh-end-of-command] Go to end of successive commands. | 1601 | \\[sh-end-of-command] Go to end of successive commands. |
| 1604 | \\[sh-beginning-of-command] Go to beginning of successive commands. | 1602 | \\[sh-beginning-of-command] Go to beginning of successive commands. |
| 1605 | \\[sh-set-shell] Set this buffer's shell, and maybe its magic number. | 1603 | \\[sh-set-shell] Set this buffer's shell, and maybe its magic number. |
| @@ -2501,7 +2499,8 @@ Lines containing only comments are considered empty." | |||
| 2501 | (current-column))) | 2499 | (current-column))) |
| 2502 | current) | 2500 | current) |
| 2503 | (save-excursion | 2501 | (save-excursion |
| 2504 | (indent-to (if (eq this-command 'newline-and-indent) | 2502 | (indent-to (if (or (eq this-command 'newline-and-indent) |
| 2503 | (and electric-indent-mode (eq this-command 'newline))) | ||
| 2505 | previous | 2504 | previous |
| 2506 | (if (< (current-column) | 2505 | (if (< (current-column) |
| 2507 | (setq current (progn (back-to-indentation) | 2506 | (setq current (progn (back-to-indentation) |
diff --git a/lisp/subr.el b/lisp/subr.el index 05345853edc..68cd230c5e2 100644 --- a/lisp/subr.el +++ b/lisp/subr.el | |||
| @@ -1082,7 +1082,12 @@ The return value is a positive integer." | |||
| 1082 | ;;;; Extracting fields of the positions in an event. | 1082 | ;;;; Extracting fields of the positions in an event. |
| 1083 | 1083 | ||
| 1084 | (defun posnp (obj) | 1084 | (defun posnp (obj) |
| 1085 | "Return non-nil if OBJ appears to be a valid `posn' object." | 1085 | "Return non-nil if OBJ appears to be a valid `posn' object specifying a window. |
| 1086 | If OBJ is a valid `posn' object, but specifies a frame rather | ||
| 1087 | than a window, return nil." | ||
| 1088 | ;; FIXME: Correct the behavior of this function so that all valid | ||
| 1089 | ;; `posn' objects are recognized, after updating other code that | ||
| 1090 | ;; depends on its present behavior. | ||
| 1086 | (and (windowp (car-safe obj)) | 1091 | (and (windowp (car-safe obj)) |
| 1087 | (atom (car-safe (setq obj (cdr obj)))) ;AREA-OR-POS. | 1092 | (atom (car-safe (setq obj (cdr obj)))) ;AREA-OR-POS. |
| 1088 | (integerp (car-safe (car-safe (setq obj (cdr obj))))) ;XOFFSET. | 1093 | (integerp (car-safe (car-safe (setq obj (cdr obj))))) ;XOFFSET. |
| @@ -1142,24 +1147,28 @@ For a scroll-bar event, the result column is 0, and the row | |||
| 1142 | corresponds to the vertical position of the click in the scroll bar. | 1147 | corresponds to the vertical position of the click in the scroll bar. |
| 1143 | POSITION should be a list of the form returned by the `event-start' | 1148 | POSITION should be a list of the form returned by the `event-start' |
| 1144 | and `event-end' functions." | 1149 | and `event-end' functions." |
| 1145 | (let* ((pair (posn-x-y position)) | 1150 | (let* ((pair (posn-x-y position)) |
| 1146 | (window (posn-window position)) | 1151 | (frame-or-window (posn-window position)) |
| 1147 | (area (posn-area position))) | 1152 | (frame (if (framep frame-or-window) |
| 1153 | frame-or-window | ||
| 1154 | (window-frame frame-or-window))) | ||
| 1155 | (window (when (windowp frame-or-window) frame-or-window)) | ||
| 1156 | (area (posn-area position))) | ||
| 1148 | (cond | 1157 | (cond |
| 1149 | ((null window) | 1158 | ((null frame-or-window) |
| 1150 | '(0 . 0)) | 1159 | '(0 . 0)) |
| 1151 | ((eq area 'vertical-scroll-bar) | 1160 | ((eq area 'vertical-scroll-bar) |
| 1152 | (cons 0 (scroll-bar-scale pair (1- (window-height window))))) | 1161 | (cons 0 (scroll-bar-scale pair (1- (window-height window))))) |
| 1153 | ((eq area 'horizontal-scroll-bar) | 1162 | ((eq area 'horizontal-scroll-bar) |
| 1154 | (cons (scroll-bar-scale pair (window-width window)) 0)) | 1163 | (cons (scroll-bar-scale pair (window-width window)) 0)) |
| 1155 | (t | 1164 | (t |
| 1156 | (let* ((frame (if (framep window) window (window-frame window))) | 1165 | ;; FIXME: This should take line-spacing properties on |
| 1157 | ;; FIXME: This should take line-spacing properties on | 1166 | ;; newlines into account. |
| 1158 | ;; newlines into account. | 1167 | (let* ((spacing (when (display-graphic-p frame) |
| 1159 | (spacing (when (display-graphic-p frame) | 1168 | (or (with-current-buffer |
| 1160 | (or (with-current-buffer (window-buffer window) | 1169 | (window-buffer (frame-selected-window frame)) |
| 1161 | line-spacing) | 1170 | line-spacing) |
| 1162 | (frame-parameter frame 'line-spacing))))) | 1171 | (frame-parameter frame 'line-spacing))))) |
| 1163 | (cond ((floatp spacing) | 1172 | (cond ((floatp spacing) |
| 1164 | (setq spacing (truncate (* spacing | 1173 | (setq spacing (truncate (* spacing |
| 1165 | (frame-char-height frame))))) | 1174 | (frame-char-height frame))))) |
diff --git a/lisp/tar-mode.el b/lisp/tar-mode.el index 1ee54515bea..6c7f7553f82 100644 --- a/lisp/tar-mode.el +++ b/lisp/tar-mode.el | |||
| @@ -50,9 +50,6 @@ | |||
| 50 | ;; | 50 | ;; |
| 51 | ;; o chmod should understand "a+x,og-w". | 51 | ;; o chmod should understand "a+x,og-w". |
| 52 | ;; | 52 | ;; |
| 53 | ;; o It's not possible to add a NEW file to a tar archive; not that | ||
| 54 | ;; important, but still... | ||
| 55 | ;; | ||
| 56 | ;; o The code is less efficient that it could be - in a lot of places, I | 53 | ;; o The code is less efficient that it could be - in a lot of places, I |
| 57 | ;; pull a 512-character string out of the buffer and parse it, when I could | 54 | ;; pull a 512-character string out of the buffer and parse it, when I could |
| 58 | ;; be parsing it in place, not garbaging a string. Should redo that. | 55 | ;; be parsing it in place, not garbaging a string. Should redo that. |
| @@ -369,6 +366,80 @@ write-date, checksum, link-type, and link-name." | |||
| 369 | string) | 366 | string) |
| 370 | (tar-parse-octal-integer string)) | 367 | (tar-parse-octal-integer string)) |
| 371 | 368 | ||
| 369 | (defun tar-new-regular-file-header (filename &optional size time) | ||
| 370 | "Return a Tar header for a regular file. | ||
| 371 | The header will lack a proper checksum; use `tar-header-block-checksum' | ||
| 372 | to compute one, or request `tar-header-serialize' to do that. | ||
| 373 | |||
| 374 | Other tar-mode facilities may also require the data-start header | ||
| 375 | field to be set to a valid value. | ||
| 376 | |||
| 377 | If SIZE is not given or nil, it defaults to 0. | ||
| 378 | If TIME is not given or nil, assume now." | ||
| 379 | (make-tar-header | ||
| 380 | nil | ||
| 381 | filename | ||
| 382 | #o644 0 0 (or size 0) | ||
| 383 | (or time (current-time)) | ||
| 384 | nil ; checksum | ||
| 385 | nil nil | ||
| 386 | nil nil nil nil nil)) | ||
| 387 | |||
| 388 | (defun tar--pad-to (pos) | ||
| 389 | (make-string (+ pos (- (point)) (point-min)) 0)) | ||
| 390 | |||
| 391 | (defun tar--put-at (pos val &optional fmt mask) | ||
| 392 | (when val | ||
| 393 | (insert (tar--pad-to pos) | ||
| 394 | (if fmt | ||
| 395 | (format fmt (if mask (logand mask val) val)) | ||
| 396 | val)))) | ||
| 397 | |||
| 398 | (defun tar-header-serialize (header &optional update-checksum) | ||
| 399 | "Return the serialization of a Tar HEADER as a string. | ||
| 400 | This function calls `tar-header-block-check-checksum' to ensure the | ||
| 401 | checksum is correct. | ||
| 402 | |||
| 403 | If UPDATE-CHECKSUM is non-nil, update HEADER with the newly-computed | ||
| 404 | checksum before doing the check." | ||
| 405 | (with-temp-buffer | ||
| 406 | (set-buffer-multibyte nil) | ||
| 407 | (let ((encoded-name | ||
| 408 | (encode-coding-string (tar-header-name header) | ||
| 409 | tar-file-name-coding-system))) | ||
| 410 | (unless (< (length encoded-name) 99) | ||
| 411 | ;; FIXME: Implement it. | ||
| 412 | (error "Long file name support is not implemented")) | ||
| 413 | (insert encoded-name)) | ||
| 414 | (tar--put-at tar-mode-offset (tar-header-mode header) "%6o\0 " #o777777) | ||
| 415 | (tar--put-at tar-uid-offset (tar-header-uid header) "%6o\0 " #o777777) | ||
| 416 | (tar--put-at tar-gid-offset (tar-header-gid header) "%6o\0 " #o777777) | ||
| 417 | (tar--put-at tar-size-offset (tar-header-size header) "%11o ") | ||
| 418 | (insert (tar--pad-to tar-time-offset) | ||
| 419 | (tar-octal-time (tar-header-date header)) | ||
| 420 | " ") | ||
| 421 | ;; Omit tar-header-checksum (tar-chk-offset) for now. | ||
| 422 | (tar--put-at tar-linkp-offset (tar-header-link-type header)) | ||
| 423 | (tar--put-at tar-link-offset (tar-header-link-name header)) | ||
| 424 | (when (tar-header-magic header) | ||
| 425 | (tar--put-at tar-magic-offset (tar-header-magic header)) | ||
| 426 | (tar--put-at tar-uname-offset (tar-header-uname header)) | ||
| 427 | (tar--put-at tar-gname-offset (tar-header-gname header)) | ||
| 428 | (tar--put-at tar-dmaj-offset (tar-header-dmaj header) "%7o\0" #o7777777) | ||
| 429 | (tar--put-at tar-dmin-offset (tar-header-dmin header) "%7o\0" #o7777777)) | ||
| 430 | (tar--put-at 512 "") | ||
| 431 | (let ((ck (tar-header-block-checksum (buffer-string)))) | ||
| 432 | (goto-char (+ (point-min) tar-chk-offset)) | ||
| 433 | (delete-char 8) | ||
| 434 | (insert (format "%6o\0 " ck)) | ||
| 435 | (when update-checksum | ||
| 436 | (setf (tar-header-checksum header) ck)) | ||
| 437 | (tar-header-block-check-checksum (buffer-string) | ||
| 438 | (tar-header-checksum header) | ||
| 439 | (tar-header-name header))) | ||
| 440 | ;; . | ||
| 441 | (buffer-string))) | ||
| 442 | |||
| 372 | 443 | ||
| 373 | (defun tar-header-block-checksum (string) | 444 | (defun tar-header-block-checksum (string) |
| 374 | "Compute and return a tar-acceptable checksum for this block." | 445 | "Compute and return a tar-acceptable checksum for this block." |
| @@ -547,6 +618,7 @@ MODE should be an integer which is a file mode value." | |||
| 547 | (define-key map "p" 'tar-previous-line) | 618 | (define-key map "p" 'tar-previous-line) |
| 548 | (define-key map "\^P" 'tar-previous-line) | 619 | (define-key map "\^P" 'tar-previous-line) |
| 549 | (define-key map [up] 'tar-previous-line) | 620 | (define-key map [up] 'tar-previous-line) |
| 621 | (define-key map "I" 'tar-new-entry) | ||
| 550 | (define-key map "R" 'tar-rename-entry) | 622 | (define-key map "R" 'tar-rename-entry) |
| 551 | (define-key map "u" 'tar-unflag) | 623 | (define-key map "u" 'tar-unflag) |
| 552 | (define-key map "v" 'tar-view) | 624 | (define-key map "v" 'tar-view) |
| @@ -731,10 +803,14 @@ tar-file's buffer." | |||
| 731 | (interactive "p") | 803 | (interactive "p") |
| 732 | (tar-next-line (- arg))) | 804 | (tar-next-line (- arg))) |
| 733 | 805 | ||
| 806 | (defun tar-current-position () | ||
| 807 | "Return the `tar-parse-info' index for the current line." | ||
| 808 | (count-lines (point-min) (line-beginning-position))) | ||
| 809 | |||
| 734 | (defun tar-current-descriptor (&optional noerror) | 810 | (defun tar-current-descriptor (&optional noerror) |
| 735 | "Return the tar-descriptor of the current line, or signals an error." | 811 | "Return the tar-descriptor of the current line, or signals an error." |
| 736 | ;; I wish lines had plists, like in ZMACS... | 812 | ;; I wish lines had plists, like in ZMACS... |
| 737 | (or (nth (count-lines (point-min) (line-beginning-position)) | 813 | (or (nth (tar-current-position) |
| 738 | tar-parse-info) | 814 | tar-parse-info) |
| 739 | (if noerror | 815 | (if noerror |
| 740 | nil | 816 | nil |
| @@ -948,6 +1024,37 @@ the current tar-entry." | |||
| 948 | (write-region start end to-file nil nil nil t))) | 1024 | (write-region start end to-file nil nil nil t))) |
| 949 | (message "Copied tar entry %s to %s" name to-file))) | 1025 | (message "Copied tar entry %s to %s" name to-file))) |
| 950 | 1026 | ||
| 1027 | (defun tar-new-entry (filename &optional index) | ||
| 1028 | "Insert a new empty regular file before point." | ||
| 1029 | (interactive "*sFile name: ") | ||
| 1030 | (let* ((buffer (current-buffer)) | ||
| 1031 | (index (or index (tar-current-position))) | ||
| 1032 | (d-list (and (not (zerop index)) | ||
| 1033 | (nthcdr (+ -1 index) tar-parse-info))) | ||
| 1034 | (pos (if d-list | ||
| 1035 | (tar-header-data-end (car d-list)) | ||
| 1036 | (point-min))) | ||
| 1037 | (new-descriptor | ||
| 1038 | (tar-new-regular-file-header filename))) | ||
| 1039 | ;; Update the data buffer; fill the missing descriptor fields. | ||
| 1040 | (with-current-buffer tar-data-buffer | ||
| 1041 | (goto-char pos) | ||
| 1042 | (insert (tar-header-serialize new-descriptor t)) | ||
| 1043 | (setf (tar-header-data-start new-descriptor) | ||
| 1044 | (copy-marker (point) nil))) | ||
| 1045 | ;; Update tar-parse-info. | ||
| 1046 | (if d-list | ||
| 1047 | (setcdr d-list (cons new-descriptor (cdr d-list))) | ||
| 1048 | (setq tar-parse-info (cons new-descriptor tar-parse-info))) | ||
| 1049 | ;; Update the listing buffer. | ||
| 1050 | (save-excursion | ||
| 1051 | (goto-char (point-min)) | ||
| 1052 | (forward-line index) | ||
| 1053 | (let ((inhibit-read-only t)) | ||
| 1054 | (insert (tar-header-block-summarize new-descriptor) ?\n))) | ||
| 1055 | ;; . | ||
| 1056 | index)) | ||
| 1057 | |||
| 951 | (defun tar-flag-deleted (p &optional unflag) | 1058 | (defun tar-flag-deleted (p &optional unflag) |
| 952 | "In Tar mode, mark this sub-file to be deleted from the tar file. | 1059 | "In Tar mode, mark this sub-file to be deleted from the tar file. |
| 953 | With a prefix argument, mark that many files." | 1060 | With a prefix argument, mark that many files." |
diff --git a/lisp/textmodes/artist.el b/lisp/textmodes/artist.el index 8a2383c12ff..85d9410868a 100644 --- a/lisp/textmodes/artist.el +++ b/lisp/textmodes/artist.el | |||
| @@ -4963,52 +4963,55 @@ The event, EV, is the mouse event." | |||
| 4963 | (artist-funcall init-fn x1 y1) | 4963 | (artist-funcall init-fn x1 y1) |
| 4964 | (if (not artist-rubber-banding) | 4964 | (if (not artist-rubber-banding) |
| 4965 | (artist-no-rb-set-point1 x1 y1)) | 4965 | (artist-no-rb-set-point1 x1 y1)) |
| 4966 | (track-mouse | 4966 | (unwind-protect |
| 4967 | (while (or (mouse-movement-p ev) | 4967 | (track-mouse |
| 4968 | (member 'down (event-modifiers ev))) | 4968 | (while (or (mouse-movement-p ev) |
| 4969 | (setq ev-start-pos (artist-coord-win-to-buf | 4969 | (member 'down (event-modifiers ev))) |
| 4970 | (posn-col-row (event-start ev)))) | 4970 | (setq ev-start-pos (artist-coord-win-to-buf |
| 4971 | (setq x1 (car ev-start-pos)) | 4971 | (posn-col-row (event-start ev)))) |
| 4972 | (setq y1 (cdr ev-start-pos)) | 4972 | (setq x1 (car ev-start-pos)) |
| 4973 | 4973 | (setq y1 (cdr ev-start-pos)) | |
| 4974 | ;; Cancel previous timer | 4974 | |
| 4975 | (if timer | 4975 | ;; Cancel previous timer |
| 4976 | (cancel-timer timer)) | 4976 | (if timer |
| 4977 | 4977 | (cancel-timer timer)) | |
| 4978 | (if (not (eq initial-win (posn-window (event-start ev)))) | 4978 | |
| 4979 | ;; If we moved outside the window, do nothing | 4979 | (if (not (eq initial-win (posn-window (event-start ev)))) |
| 4980 | nil | 4980 | ;; If we moved outside the window, do nothing |
| 4981 | 4981 | nil | |
| 4982 | ;; Still in same window: | 4982 | |
| 4983 | ;; | 4983 | ;; Still in same window: |
| 4984 | ;; Check if user presses or releases shift key | 4984 | ;; |
| 4985 | (if (artist-shift-has-changed shift-state ev) | 4985 | ;; Check if user presses or releases shift key |
| 4986 | 4986 | (if (artist-shift-has-changed shift-state ev) | |
| 4987 | ;; First check that the draw-how is the same as we | 4987 | |
| 4988 | ;; already have. Otherwise, ignore the changed shift-state. | 4988 | ;; First check that the draw-how is the same as we |
| 4989 | (if (not (eq draw-how | 4989 | ;; already have. Otherwise, ignore the changed shift-state. |
| 4990 | (artist-go-get-draw-how-from-symbol | 4990 | (if (not (eq draw-how |
| 4991 | (if (not shift-state) shifted unshifted)))) | 4991 | (artist-go-get-draw-how-from-symbol |
| 4992 | (message "Cannot switch to shifted operation") | 4992 | (if (not shift-state) shifted unshifted)))) |
| 4993 | 4993 | (message "Cannot switch to shifted operation") | |
| 4994 | ;; progn is "implicit" since this is the else-part | 4994 | |
| 4995 | (setq shift-state (not shift-state)) | 4995 | ;; progn is "implicit" since this is the else-part |
| 4996 | (setq op (if shift-state shifted unshifted)) | 4996 | (setq shift-state (not shift-state)) |
| 4997 | (setq draw-how (artist-go-get-draw-how-from-symbol op)) | 4997 | (setq op (if shift-state shifted unshifted)) |
| 4998 | (setq draw-fn (artist-go-get-draw-fn-from-symbol op)))) | 4998 | (setq draw-how (artist-go-get-draw-how-from-symbol op)) |
| 4999 | 4999 | (setq draw-fn (artist-go-get-draw-fn-from-symbol op)))) | |
| 5000 | ;; Draw the new shape | 5000 | |
| 5001 | (setq shape (artist-funcall draw-fn x1 y1)) | 5001 | ;; Draw the new shape |
| 5002 | (artist-move-to-xy x1 y1) | 5002 | (setq shape (artist-funcall draw-fn x1 y1)) |
| 5003 | 5003 | (artist-move-to-xy x1 y1) | |
| 5004 | ;; Start the timer to call `draw-fn' repeatedly every | 5004 | |
| 5005 | ;; `interval' second | 5005 | ;; Start the timer to call `draw-fn' repeatedly every |
| 5006 | (if (and interval draw-fn) | 5006 | ;; `interval' second |
| 5007 | (setq timer (run-at-time interval interval draw-fn x1 y1)))) | 5007 | (if (and interval draw-fn) |
| 5008 | 5008 | (setq timer (run-at-time interval interval draw-fn x1 y1)))) | |
| 5009 | ;; Read next event | 5009 | |
| 5010 | (setq ev (read-event)))) | 5010 | ;; Read next event |
| 5011 | 5011 | (setq ev (read-event)))) | |
| 5012 | ;; Cleanup: get rid of any active timer. | ||
| 5013 | (if timer | ||
| 5014 | (cancel-timer timer))) | ||
| 5012 | ;; Cancel any timers | 5015 | ;; Cancel any timers |
| 5013 | (if timer | 5016 | (if timer |
| 5014 | (cancel-timer timer)) | 5017 | (cancel-timer timer)) |
diff --git a/lisp/textmodes/reftex.el b/lisp/textmodes/reftex.el index 160d9fb4cdf..7cf54c6d28a 100644 --- a/lisp/textmodes/reftex.el +++ b/lisp/textmodes/reftex.el | |||
| @@ -106,17 +106,21 @@ | |||
| 106 | (defvar reftex-syntax-table nil) | 106 | (defvar reftex-syntax-table nil) |
| 107 | (defvar reftex-syntax-table-for-bib nil) | 107 | (defvar reftex-syntax-table-for-bib nil) |
| 108 | 108 | ||
| 109 | (unless reftex-syntax-table | 109 | (defun reftex--prepare-syntax-tables () |
| 110 | (setq reftex-syntax-table (copy-syntax-table)) | 110 | (setq reftex-syntax-table (copy-syntax-table)) |
| 111 | (modify-syntax-entry ?\( "." reftex-syntax-table) | 111 | (modify-syntax-entry ?\( "." reftex-syntax-table) |
| 112 | (modify-syntax-entry ?\) "." reftex-syntax-table)) | 112 | (modify-syntax-entry ?\) "." reftex-syntax-table) |
| 113 | 113 | ||
| 114 | (unless reftex-syntax-table-for-bib | ||
| 115 | (setq reftex-syntax-table-for-bib (copy-syntax-table)) | 114 | (setq reftex-syntax-table-for-bib (copy-syntax-table)) |
| 116 | (modify-syntax-entry ?\' "." reftex-syntax-table-for-bib) | 115 | (modify-syntax-entry ?\' "." reftex-syntax-table-for-bib) |
| 117 | (modify-syntax-entry ?\" "." reftex-syntax-table-for-bib) | 116 | (modify-syntax-entry ?\" "." reftex-syntax-table-for-bib) |
| 118 | (modify-syntax-entry ?\[ "." reftex-syntax-table-for-bib) | 117 | (modify-syntax-entry ?\[ "." reftex-syntax-table-for-bib) |
| 119 | (modify-syntax-entry ?\] "." reftex-syntax-table-for-bib)) | 118 | (modify-syntax-entry ?\] "." reftex-syntax-table-for-bib) |
| 119 | (modify-syntax-entry ?\( "." reftex-syntax-table-for-bib) | ||
| 120 | (modify-syntax-entry ?\) "." reftex-syntax-table-for-bib)) | ||
| 121 | |||
| 122 | (unless (and reftex-syntax-table reftex-syntax-table-for-bib) | ||
| 123 | (reftex--prepare-syntax-tables)) | ||
| 120 | 124 | ||
| 121 | ;; The following definitions are out of place, but I need them here | 125 | ;; The following definitions are out of place, but I need them here |
| 122 | ;; to make the compilation of reftex-mode not complain. | 126 | ;; to make the compilation of reftex-mode not complain. |
| @@ -180,15 +184,7 @@ on the menu bar. | |||
| 180 | (put 'reftex-auto-recenter-toc 'initialized t)) | 184 | (put 'reftex-auto-recenter-toc 'initialized t)) |
| 181 | 185 | ||
| 182 | ;; Prepare the special syntax tables. | 186 | ;; Prepare the special syntax tables. |
| 183 | (setq reftex-syntax-table (copy-syntax-table (syntax-table))) | 187 | (reftex--prepare-syntax-tables) |
| 184 | (modify-syntax-entry ?\( "." reftex-syntax-table) | ||
| 185 | (modify-syntax-entry ?\) "." reftex-syntax-table) | ||
| 186 | |||
| 187 | (setq reftex-syntax-table-for-bib (copy-syntax-table)) | ||
| 188 | (modify-syntax-entry ?\' "." reftex-syntax-table-for-bib) | ||
| 189 | (modify-syntax-entry ?\" "." reftex-syntax-table-for-bib) | ||
| 190 | (modify-syntax-entry ?\[ "." reftex-syntax-table-for-bib) | ||
| 191 | (modify-syntax-entry ?\] "." reftex-syntax-table-for-bib) | ||
| 192 | 188 | ||
| 193 | (run-hooks 'reftex-mode-hook)) | 189 | (run-hooks 'reftex-mode-hook)) |
| 194 | ;; Mode was turned off | 190 | ;; Mode was turned off |