aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorJoakim Verona2015-02-01 00:37:46 +0100
committerJoakim Verona2015-02-01 00:37:46 +0100
commit69815dfe3704f8a8c733843f1fd04546cbb0f4d0 (patch)
treecee6910753a51b9a5ee88e2431c9bcad099e8ba8 /lisp
parent4edad429cafb2f0b1fda028be58367286ab04f1c (diff)
parenta2c32b0cfc9f6d3410e2832d8ea0d4f1df576d1e (diff)
downloademacs-69815dfe3704f8a8c733843f1fd04546cbb0f4d0.tar.gz
emacs-69815dfe3704f8a8c733843f1fd04546cbb0f4d0.zip
Merge branch 'master' into xwidget
Diffstat (limited to 'lisp')
-rw-r--r--lisp/ChangeLog235
-rw-r--r--lisp/button.el20
-rw-r--r--lisp/calc/calc-ext.el4
-rw-r--r--lisp/calc/calc-help.el2
-rw-r--r--lisp/calc/calc-units.el36
-rw-r--r--lisp/custom.el3
-rw-r--r--lisp/emacs-lisp/backquote.el4
-rw-r--r--lisp/emacs-lisp/cl-generic.el30
-rw-r--r--lisp/emacs-lisp/cl-macs.el215
-rw-r--r--lisp/emacs-lisp/cl-preloaded.el48
-rw-r--r--lisp/emacs-lisp/cl.el1
-rw-r--r--lisp/emacs-lisp/easy-mmode.el11
-rw-r--r--lisp/emacs-lisp/eieio-base.el4
-rw-r--r--lisp/emacs-lisp/eieio-core.el121
-rw-r--r--lisp/emacs-lisp/eieio-datadebug.el2
-rw-r--r--lisp/emacs-lisp/eieio-opt.el99
-rw-r--r--lisp/emacs-lisp/eieio.el71
-rw-r--r--lisp/erc/ChangeLog5
-rw-r--r--lisp/erc/erc-backend.el7
-rw-r--r--lisp/filenotify.el383
-rw-r--r--lisp/files.el71
-rw-r--r--lisp/gnus/ChangeLog27
-rw-r--r--lisp/gnus/gnus-registry.el14
-rw-r--r--lisp/gnus/message.el5
-rw-r--r--lisp/gnus/mm-decode.el2
-rw-r--r--lisp/gnus/nnimap.el29
-rw-r--r--lisp/loadup.el3
-rw-r--r--lisp/net/net-utils.el20
-rw-r--r--lisp/net/shr.el37
-rw-r--r--lisp/net/tramp.el3
-rw-r--r--lisp/outline.el320
-rw-r--r--lisp/progmodes/python.el702
-rw-r--r--lisp/progmodes/sh-script.el7
-rw-r--r--lisp/subr.el33
-rw-r--r--lisp/tar-mode.el115
-rw-r--r--lisp/textmodes/artist.el95
-rw-r--r--lisp/textmodes/reftex.el22
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 @@
12015-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
362015-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
412015-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
572015-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
842015-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
902015-01-30 Oleh Krehel <ohwoeowho@gmail.com>
91
92 * lisp/custom.el (defface): Set `indent' to 1.
93
942015-01-30 Oleh Krehel <ohwoeowho@gmail.com>
95
96 * emacs-lisp/easy-mmode.el (define-minor-mode): Set `indent' to 1.
97
982015-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
1052015-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
1172015-01-28 Stefan Monnier <monnier@iro.umontreal.ca>
118
119 * emacs-lisp/cl.el (cl--function-convert): Simplify.
120
1212015-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
1292015-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
1482015-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
1552015-01-28 Eli Zaretskii <eliz@gnu.org>
156
157 * button.el (button-activate, push-button): Doc fix. (Bug#19628)
158
1592015-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
1712015-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
1772015-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
1822015-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
1872015-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
1922015-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
2102015-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
2152015-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
12015-01-27 Sam Steingold <sds@gnu.org> 2252015-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
72015-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
132015-01-27 Artur Malabarba <bruce.connor.am@gmail.com> 2312015-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 @@
702015-01-26 Lars Ingebrigtsen <larsi@gnus.org> 2882015-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 @@
17422014-12-14 Steve Purcell <steve@sanityinc.com> (tiny change) 19622014-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
17482014-12-14 Cameron Desautels <camdez@gmail.com> 19672014-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.
228If USE-MOUSE-ACTION is non-nil, invoke the button's mouse-action 228If USE-MOUSE-ACTION is non-nil, invoke the button's `mouse-action'
229instead of its normal action; if the button has no mouse-action, 229property instead of `action'; if the button has no `mouse-action',
230the normal action is used instead. 230the value of `action' is used instead.
231 231
232The action can either be a marker or a function. If it's a 232The action can either be a marker or a function. If it's a
233marker then goto it. Otherwise it it is a function then it is 233marker 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.
431POS may be either a buffer position or a mouse-event. If 431POS may be either a buffer position or a mouse-event. If
432USE-MOUSE-ACTION is non-nil, invoke the button's mouse-action 432USE-MOUSE-ACTION is non-nil, invoke the button's `mouse-action'
433instead of its normal action; if the button has no mouse-action, 433property instead of its `action' property; if the button has no
434the normal action is used instead. The action may be either a 434`mouse-action', the value of `action' is used instead.
435function to call or a marker to display and is invoked using 435
436`button-activate' (which see). 436The action in both cases may be either a function to call or a
437marker to display and is invoked using `button-activate' (which
438see).
437 439
438POS defaults to point, except when `push-button' is invoked 440POS defaults to point, except when `push-button' is invoked
439interactively as the result of a mouse-event, in which case, the 441interactively 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
1179calc-convert-temperature calc-convert-units calc-define-unit 1180calc-convert-temperature calc-convert-units
1181calc-convert-exact-units calc-define-unit
1180calc-enter-units-table calc-explain-units calc-extract-units 1182calc-enter-units-table calc-explain-units calc-extract-units
1181calc-get-unit-definition calc-permanent-units calc-quick-units 1183calc-get-unit-definition calc-permanent-units calc-quick-units
1182calc-remove-units calc-simplify-units calc-undefine-unit 1184calc-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
412See Info node `(elisp) Faces' in the Emacs Lisp manual for more 412See Info node `(elisp) Faces' in the Emacs Lisp manual for more
413information." 413information."
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."
120This simply recurses through the body." 120This 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,
229and which will be used for the name of the `cl-block' surrounding the 229and which will be used for the name of the `cl-block' surrounding the
230function's body. 230function's body.
231FORM is of the form (ARGS . BODY)." 231FORM 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.
655Key values are compared by `eql'. 660Key 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 [&not keywordp] sexp 152 [&optional [&not keywordp] sexp
153 &optional [&not keywordp] sexp 153 &optional [&not keywordp] sexp
154 &optional [&not keywordp] sexp] 154 &optional [&not 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
219being pedantic." 219being 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.
194CLASS is a symbol." ;FIXME: Is it a vector or a symbol? 181CLASS 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?
221Return nil if that option doesn't exist." 204Return 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.
937Fills in OBJ's SLOT with its default value." 933Fills 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'.
976Fills in OBJ's SLOT with VALUE." 972Fills 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'.
1000Fills in the default value in CLASS' in SLOT with VALUE." 996Fills 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'."
58Argument THIS-ROOT is the local root of the tree. 58Argument THIS-ROOT is the local root of the tree.
59Argument PREFIX is the character prefix to use. 59Argument PREFIX is the character prefix to use.
60Argument CH-PREFIX is another character prefix to display." 60Argument 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.
218Optional argument CLASS is the class to start with. 209Optional 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:
110Due to the way class options are set up, you can add any tags you wish, 110Due to the way class options are set up, you can add any tags you wish,
111and reference them using the function `class-option'." 111and 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.
376If EXTRA, include that in the string returned to represent the symbol." 367If 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
421The CLOS function `class-direct-superclasses' is aliased to this function." 412The 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.
429The CLOS function `class-direct-subclasses' is aliased to this function." 419The 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.
539If there is no class, nil is returned if ERRORP is nil. 530If there is no class, nil is returned if ERRORP is nil.
540If ERRORP is non-nil, `wrong-argument-type' is signaled." 531If 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.
551Objects in LIST do not need to have a slot named SLOT, nor does 542Objects in LIST do not need to have a slot named SLOT, nor does
552SLOT need to be bound. If these errors occur, those objects will 543SLOT need to be bound. If these errors occur, those objects will
553be ignored." 544be 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.
564LIST must be a list of objects with SLOT in it. 555LIST must be a list of objects with SLOT in it.
565This is useful when you need to do completing read on an object group." 556This 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."
577LIST must be a list of objects, but those objects do not need to have 568LIST must be a list of objects, but those objects do not need to have
578SLOT in it. If it does not, then that element is left out of the association 569SLOT in it. If it does not, then that element is left out of the association
579list." 570list."
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 @@
12015-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
12015-01-22 Paul Eggert <eggert@cs.ucla.edu> 62015-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.
42A key in this hash table is the descriptor as returned from 42A 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.
44The value in the hash table is the cons cell (DIR FILE CALLBACK).") 44The value in the hash table is a list
45
46 \(DIR (FILE . CALLBACK) (FILE . CALLBACK) ...)
47
48Several values for a given DIR happen only for `inotify', when
49different 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.
50If EVENT is a filewatch event, call its callback. 55If EVENT is a filewatch event, call its callback. It has the format
56
57 \(file-notify (DESCRIPTOR ACTIONS FILE COOKIE) CALLBACK)
58
51Otherwise, signal a `file-notify-error'." 59Otherwise, 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."
81This is available in case a file has been moved." 89This 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'.
97For `gfilenotify' and `w32notify' it is the same descriptor as
98used 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.
88EVENT is the same one as in `file-notify-handle-event' except the 107EVENT is the cdr of the event in `file-notify-handle-event'
89car 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.
195This arranges for filesystem events pertaining to FILE to be reported 228This 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
209If FILE is a directory, 'change' watches for file creation or 242If FILE is a directory, `change' watches for file creation or
210deletion in that directory. This does not work recursively. 243deletion in that directory. This does not work recursively.
211 244
212When any event happens, Emacs will call the CALLBACK function passing 245When 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.
303DESCRIPTOR should be an object returned by `file-notify-add-watch'." 333DESCRIPTOR 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
6095PATTERN is assumed to represent a file-name wildcard suitable for the 6095PATTERN is assumed to represent a file-name wildcard suitable for the
6096underlying filesystem. For Unix and GNU/Linux, each character from the 6096underlying filesystem. For Unix and GNU/Linux, each character from the
6097set [ \\t\\n;<>&|()'\"#$] is quoted with a backslash; for DOS/Windows, all 6097set [ \\t\\n;<>&|()`'\"#$] is quoted with a backslash; for DOS/Windows, all
6098the parts of the pattern which don't include wildcard characters are 6098the parts of the pattern which don't include wildcard characters are
6099quoted with double quotes. 6099quoted 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
6590if any returns nil. If `confirm-kill-emacs' is non-nil, calls it." 6590if 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 @@
12015-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
82015-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
182015-01-28 Elias Oltmanns <eo@nebensachen.de>
19
20 * nnimap.el (nnimap-find-expired-articles): Fix handling of
21 (expiry-wait . never).
22
232015-01-28 Lars Ingebrigtsen <larsi@gnus.org>
24
25 * nnimap.el (nnimap-request-group): Clear the buffer before returning
26 the data.
27
12015-01-27 Lars Ingebrigtsen <larsi@gnus.org> 282015-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
253cut the registry back to \(- 50000 \(* 50000 0.1\)\) -> 45000 254cut the registry back to \(- 50000 \(* 50000 0.1\)\) -> 45000
254entries. The pruning process is constrained by the presence of 255entries. 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 264Entries that sort to the front of the list are pruned first.
264Entries which sort to the front of the list will be pruned
265first.
266
267This can slow pruning down. Set to nil to perform no sorting." 265This 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.
4906It is useful if your ISP requires the POP-before-SMTP 4906It is useful if your ISP requires the POP-before-SMTP
4907authentication. See the Gnus manual for details." 4907authentication. 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
296of the heading, so they move with it, if the line is killed and yanked 261of the heading, so they move with it, if the line is killed and yanked
297back. A heading with text hidden under it is marked with an ellipsis (...). 262back. A heading with text hidden under it is marked with an ellipsis (...).
298 263
299Commands:\\<outline-mode-map> 264\\{outline-mode-map}
300\\[outline-next-visible-heading] outline-next-visible-heading move by visible headings 265The 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 268are 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
310The remaining commands are used when point is on a heading line.
311They 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
323The variable `outline-regexp' can be changed to control what is a heading. 270The variable `outline-regexp' can be changed to control what is a heading.
324A line is a heading if `outline-regexp' matches something at the 271A 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.
392If 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.
441When UP is non-nil, the created heading will be one level above.
442Otherwise, 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.
507If transient-mark-mode is on, and mark is active, promote headings in 458If `transient-mark-mode' is on, and mark is active, promote headings in
508the region (from a Lisp program, pass `region' for WHICH). Otherwise: 459the region (from a Lisp program, pass `region' for WHICH). Otherwise:
509without prefix argument, promote current heading and all headings in the 460without prefix argument, promote current heading and all headings in the
510subtree (from a Lisp program, pass `subtree' for WHICH); with prefix 461subtree (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.
546If transient-mark-mode is on, and mark is active, demote headings in 497If `transient-mark-mode' is on, and mark is active, demote headings in
547the region (from a Lisp program, pass `region' for WHICH). Otherwise: 498the region (from a Lisp program, pass `region' for WHICH). Otherwise:
548without prefix argument, demote current heading and all headings in the 499without prefix argument, demote current heading and all headings in the
549subtree (from a Lisp program, pass `subtree' for WHICH); with prefix 500subtree (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.
589If there are no such entries, return nil. 540If there are no such entries, return nil.
590ALIST defaults to `outline-heading-alist'. 541ALIST defaults to `outline-heading-alist'.
591Similar to (car (rassoc LEVEL ALIST)). 542Similar 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.
689With argument, repeats or can move backward if negative. 641With ARG, repeats or can move backward if negative.
690A heading line is one that starts with a `*' (or that 642A 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.
717With argument, repeats or can move forward if negative. 669With ARG, repeats or can move forward if negative.
718A heading line is one that starts with a `*' (or that 670A 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.
741The function is called with the overlay as its only argument. 693The function is called with the overlay as its only argument.
742If nil, `show-entry' is called to reveal the invisible text.") 694If 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.
820Show the heading too, if it is currently invisible." 775Show 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.
982Prefix arg LEVEL is how many levels below the current level should be shown. 971Prefix arg LEVEL is how many levels below the current level should be shown.
983Default is enough to cause the following heading to appear." 972Default 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
1091Text shown between the headers isn't copied. Two newlines are 1083Text shown between the headers isn't copied. Two newlines are
1092inserted between saved headers. Yanking the result may be a 1084inserted 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.")
711Can 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.
720The function `python-indent-calculate-levels' does not use it
721anymore. If you were defadvising it and or depended on this
722variable for indentation customizations, refactor your code to
723work 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.
729The function `python-indent-calculate-levels' does not use it
730anymore. If you were defadvising it and or depended on this
731variable for indentation customizations, refactor your code to
732work 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.
752Context information is returned with a cons with the form: 774Context is returned in a cons with the form (STATUS . START).
753 (STATUS . START) 775
754 776STATUS can be one of the following:
755Where status can be any of the following symbols: 777
756 778keyword
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.
765START 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)))))
833Returns `noindent' if the indentation does not depend on Python syntax, 979 ;; Default case: do not indent.
834such 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 984May return an integer for the maximum possible indentation at
839 (widen) 985current context or a list of integers. The latter case is only
840 (save-excursion 986happening for :at-dedenter-block-start context since the
841 (pcase context-status 987possibilities 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 1037Argument INDENTATION can either be an integer or a list of
892 (back-to-indentation) 1038integers. Levels are returned in ascending order, and in the
893 (when (looking-at "\\.") 1039case 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 1064Get indentation of PREVIOUS level when argument is non-nil.
919 ;; as indentation value. 1065Return the max level of the cycle when indentation reaches the
920 (goto-char block-continuation-start) 1066minimum."
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'.
1041Uses the offset calculated in 1075Use the PREVIOUS level when argument is non-nil, otherwise indent
1042`python-indent-calculate-indentation' and available levels 1076to the maxium available level. When indentation is the minimum
1043indicated by the variable `python-indent-levels' to set the 1077possible and PREVIOUS is non-nil, cycle back to the maximum
1044current indentation. 1078level."
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
1046When the variable `last-command' is equal to one of the symbols 1092(defun python-indent-calculate-levels ()
1047inside `python-indent-trigger-commands' or FORCE-TOGGLE is 1093 "Return possible indentation levels."
1048non-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)))
1050variable `python-indent-current-level'.
1051
1052When the variable `last-command' is not equal to one of the
1053symbols inside `python-indent-trigger-commands' and FORCE-TOGGLE
1054is nil it calculates possible indentation levels and saves them
1055in the variable `python-indent-levels'. Afterwards it sets the
1056variable `python-indent-current-level' correctly so offset is
1057equal 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.
1086See `python-indent-line' for details." 1099When the variable `last-command' is equal to one of the symbols
1087 (python-indent-line)) 1100inside `python-indent-trigger-commands' it cycles possible
1101indentation 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.
1102Argument ARG is passed to `backward-delete-char-untabify' when 1119Argument ARG is passed to `backward-delete-char-untabify' when
1103point is not in between the indentation." 1120point 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.
1086If OBJ is a valid `posn' object, but specifies a frame rather
1087than 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
1142corresponds to the vertical position of the click in the scroll bar. 1147corresponds to the vertical position of the click in the scroll bar.
1143POSITION should be a list of the form returned by the `event-start' 1148POSITION should be a list of the form returned by the `event-start'
1144and `event-end' functions." 1149and `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.
371The header will lack a proper checksum; use `tar-header-block-checksum'
372to compute one, or request `tar-header-serialize' to do that.
373
374Other tar-mode facilities may also require the data-start header
375field to be set to a valid value.
376
377If SIZE is not given or nil, it defaults to 0.
378If 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.
400This function calls `tar-header-block-check-checksum' to ensure the
401checksum is correct.
402
403If UPDATE-CHECKSUM is non-nil, update HEADER with the newly-computed
404checksum 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.
953With a prefix argument, mark that many files." 1060With 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