aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoakim Verona2015-02-08 21:55:28 +0100
committerJoakim Verona2015-02-08 21:55:28 +0100
commit5e1d5ef39ca0d2fbff26d659f2ec6ce863b14529 (patch)
tree860e0d53399626aee6249ebb5f972879f403b228
parent148262ce3db990ed16989341345e232570b3a338 (diff)
parent7d631aa0ffab875e4979727f632703ad5b4100a2 (diff)
downloademacs-xwidget.tar.gz
emacs-xwidget.zip
merge masterxwidget
-rw-r--r--ChangeLog5
-rw-r--r--configure.ac13
-rw-r--r--doc/lispref/ChangeLog10
-rw-r--r--doc/lispref/display.texi9
-rw-r--r--doc/lispref/sequences.texi47
-rw-r--r--doc/misc/ChangeLog17
-rw-r--r--doc/misc/auth.texi22
-rw-r--r--doc/misc/gnus.texi24
-rw-r--r--etc/ChangeLog4
-rw-r--r--etc/GNUS-NEWS2
-rw-r--r--etc/NEWS8
-rw-r--r--lisp/ChangeLog202
-rw-r--r--lisp/bindings.el1
-rw-r--r--lisp/delsel.el17
-rw-r--r--lisp/doc-view.el17
-rw-r--r--lisp/emacs-lisp/bytecomp.el59
-rw-r--r--lisp/emacs-lisp/cconv.el31
-rw-r--r--lisp/emacs-lisp/eieio-base.el3
-rw-r--r--lisp/emacs-lisp/eieio-compat.el7
-rw-r--r--lisp/emacs-lisp/eieio-core.el43
-rw-r--r--lisp/emacs-lisp/package.el60
-rw-r--r--lisp/emacs-lisp/seq.el55
-rw-r--r--lisp/emulation/viper-cmd.el4
-rw-r--r--lisp/emulation/viper-keym.el8
-rw-r--r--lisp/faces.el3
-rw-r--r--lisp/frame.el23
-rw-r--r--lisp/gnus/ChangeLog30
-rw-r--r--lisp/gnus/gnus-int.el2
-rw-r--r--lisp/gnus/gnus-start.el34
-rw-r--r--lisp/gnus/gnus-sum.el6
-rw-r--r--lisp/gnus/mail-source.el15
-rw-r--r--lisp/gnus/nnimap.el65
-rw-r--r--lisp/help-fns.el31
-rw-r--r--lisp/help-mode.el9
-rw-r--r--lisp/help.el2
-rw-r--r--lisp/image-mode.el6
-rw-r--r--lisp/json.el6
-rw-r--r--lisp/net/ldap.el4
-rw-r--r--lisp/net/network-stream.el6
-rw-r--r--lisp/newcomment.el32
-rw-r--r--lisp/outline.el7
-rw-r--r--lisp/play/gamegrid.el20
-rw-r--r--lisp/progmodes/python.el288
-rw-r--r--lisp/subr.el7
-rw-r--r--lisp/textmodes/css-mode.el11
-rw-r--r--lisp/vc/vc-cvs.el2
-rw-r--r--src/ChangeLog126
-rw-r--r--src/data.c5
-rw-r--r--src/dispnew.c135
-rw-r--r--src/eval.c22
-rw-r--r--src/frame.c208
-rw-r--r--src/frame.h13
-rw-r--r--src/gtkutil.c118
-rw-r--r--src/w32fns.c18
-rw-r--r--src/w32term.c217
-rw-r--r--src/widget.c39
-rw-r--r--src/window.c2
-rw-r--r--src/xdisp.c39
-rw-r--r--src/xfns.c16
-rw-r--r--src/xterm.c214
-rw-r--r--test/ChangeLog36
-rw-r--r--test/automated/package-test.el28
-rw-r--r--test/automated/python-tests.el255
-rw-r--r--test/automated/seq-tests.el26
-rw-r--r--test/automated/vc-tests.el14
65 files changed, 1985 insertions, 823 deletions
diff --git a/ChangeLog b/ChangeLog
index ca9f44aacf7..908ffe6230e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
12015-02-08 Ulrich Müller <ulm@gentoo.org>
2
3 * configure.ac (--with-gameuser): Default to 'games' group instead
4 of 'games' user.
5
12015-02-04 Paul Eggert <eggert@cs.ucla.edu> 62015-02-04 Paul Eggert <eggert@cs.ucla.edu>
2 7
3 * .gitattributes: Ignore blanks at EOL in texinfo.tex. 8 * .gitattributes: Ignore blanks at EOL in texinfo.tex.
diff --git a/configure.ac b/configure.ac
index a679bd0a240..3874cf1ee96 100644
--- a/configure.ac
+++ b/configure.ac
@@ -399,17 +399,12 @@ AC_ARG_WITH(gameuser,dnl
399 An argument prefixed by ':' specifies a group instead.])]) 399 An argument prefixed by ':' specifies a group instead.])])
400gameuser= 400gameuser=
401gamegroup= 401gamegroup=
402# We don't test if we can actually chown/chgrp here, because configure
403# may run without root privileges. lib-src/Makefile.in will handle
404# any errors due to missing user/group gracefully.
402case ${with_gameuser} in 405case ${with_gameuser} in
403 no) ;; 406 no) ;;
404 "" | yes) 407 "" | yes) gamegroup=games ;;
405 AC_MSG_CHECKING([whether a 'games' user exists])
406 if id -u games >/dev/null 2>&1; then
407 AC_MSG_RESULT([yes])
408 gameuser=games
409 else
410 AC_MSG_RESULT([no])
411 fi
412 ;;
413 :*) gamegroup=`echo "${with_gameuser}" | sed -e "s/://"` ;; 408 :*) gamegroup=`echo "${with_gameuser}" | sed -e "s/://"` ;;
414 *) gameuser=${with_gameuser} ;; 409 *) gameuser=${with_gameuser} ;;
415esac 410esac
diff --git a/doc/lispref/ChangeLog b/doc/lispref/ChangeLog
index aa4d3200830..3fe3d6fd6a0 100644
--- a/doc/lispref/ChangeLog
+++ b/doc/lispref/ChangeLog
@@ -1,3 +1,13 @@
12015-02-06 Nicolas Petton <nicolas@petton.fr>
2
3 * sequences.texi (Sequence Functions): Add documentation for
4 seq-mapcat, seq-partition and seq-group-by.
5
62015-02-05 Martin Rudalics <rudalics@gmx.at>
7
8 * display.texi (Size of Displayed Text): Remove description of
9 optional argument BUFFER of `window-text-pixel-size'.
10
12015-02-01 Martin Rudalics <rudalics@gmx.at> 112015-02-01 Martin Rudalics <rudalics@gmx.at>
2 12
3 * display.texi (Size of Displayed Text): Describe optional 13 * display.texi (Size of Displayed Text): Describe optional
diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index 10b17a3f389..b09b82a6724 100644
--- a/doc/lispref/display.texi
+++ b/doc/lispref/display.texi
@@ -1880,7 +1880,7 @@ displayed in a given window. This function is used by
1880@code{fit-frame-to-buffer} (@pxref{Size and Position}) to make a window 1880@code{fit-frame-to-buffer} (@pxref{Size and Position}) to make a window
1881exactly as large as the text it contains. 1881exactly as large as the text it contains.
1882 1882
1883@defun window-text-pixel-size &optional window from to x-limit y-limit mode-and-header-line buffer 1883@defun window-text-pixel-size &optional window from to x-limit y-limit mode-and-header-line
1884This function returns the size of the text of @var{window}'s buffer in 1884This function returns the size of the text of @var{window}'s buffer in
1885pixels. @var{window} must be a live window and defaults to the selected 1885pixels. @var{window} must be a live window and defaults to the selected
1886one. The return value is a cons of the maximum pixel-width of any text 1886one. The return value is a cons of the maximum pixel-width of any text
@@ -1919,13 +1919,6 @@ means to not include the height of the mode- or header-line of
1919@code{mode-line} or @code{header-line}, include only the height of that 1919@code{mode-line} or @code{header-line}, include only the height of that
1920line, if present, in the return value. If it is @code{t}, include the 1920line, if present, in the return value. If it is @code{t}, include the
1921height of both, if present, in the return value. 1921height of both, if present, in the return value.
1922
1923The optional argument @var{buffer} allows to specify an alternate buffer
1924whose text size will be calculated. If @var{buffer} is @code{nil} or
1925omitted, then operate on the buffer of @var{window}. If it is @code{t},
1926then operate on the current buffer as if it were displayed in
1927@var{window}. If it specifies a live buffer, then operate on that
1928buffer as if it were displayed in @var{window}.
1929@end defun 1922@end defun
1930 1923
1931 1924
diff --git a/doc/lispref/sequences.texi b/doc/lispref/sequences.texi
index f82c4962759..f268c0d11e2 100644
--- a/doc/lispref/sequences.texi
+++ b/doc/lispref/sequences.texi
@@ -695,9 +695,54 @@ concatenation of @var{sequences}. @var{type} may be: @code{vector},
695@end example 695@end example
696@end defun 696@end defun
697 697
698@defun seq-mapcat function sequence &optional type
699 This function returns the result of applying @code{seq-concatenate}
700to the result of applying @var{function} to each element of
701@var{sequence}. The result is a sequence of type @var{type}, or a
702list if @var{type} is @code{nil}.
703
704@example
705@group
706(seq-mapcat #'seq-reverse '((3 2 1) (6 5 4)))
707@result{} (1 2 3 4 5 6)
708@end group
709@end example
710@end defun
711
712@defun seq-partition sequence n
713 This function returns a list of the elements of @var{sequence}
714grouped into sub-sequences of length @var{n}. The last sequence may
715contain less elements than @var{n}. @var{n} must be an integer. If
716@var{n} is a negative integer or 0, nil is returned.
717
718@example
719@group
720(seq-partition '(0 1 2 3 4 5 6 7) 3)
721@result{} ((0 1 2) (3 4 5) (6 7))
722@end group
723@end example
724@end defun
725
726@defun seq-group-by function sequence
727 This function separates the elements of @var{sequence} into an alist
728whose keys are the result of applying @var{function} to each element
729of @var{sequence}. Keys are compared using @code{equal}.
730
731@example
732@group
733(seq-group-by #'integerp '(1 2.1 3 2 3.2))
734@result{} ((t 2 3 1) (nil 3.2 2.1))
735@end group
736@group
737(seq-group-by #'car '((a 1) (b 2) (a 3) (c 4)))
738@result{} ((a (a 3) (a 1)) (b (b 2)) (c (c 4)))
739@end group
740@end example
741@end defun
742
698@defmac seq-doseq (var sequence [result]) body@dots{} 743@defmac seq-doseq (var sequence [result]) body@dots{}
699@cindex sequence iteration 744@cindex sequence iteration
700This macro is like @code{dolist}, except that @var{sequence} can be a list, 745 This macro is like @code{dolist}, except that @var{sequence} can be a list,
701vector or string (@pxref{Iteration} for more information about the 746vector or string (@pxref{Iteration} for more information about the
702@code{dolist} macro). This is primarily useful for side-effects. 747@code{dolist} macro). This is primarily useful for side-effects.
703@end defmac 748@end defmac
diff --git a/doc/misc/ChangeLog b/doc/misc/ChangeLog
index 534dd108a66..bc22b677288 100644
--- a/doc/misc/ChangeLog
+++ b/doc/misc/ChangeLog
@@ -1,3 +1,20 @@
12015-02-05 Glenn Morris <rgm@gnu.org>
2
3 * auth.texi (Multiple GMail accounts with Gnus): Markup fix.
4
52015-02-05 Teodor Zlatanov <tzz@lifelogs.com>
6
7 * auth.texi (Multiple GMail accounts with Gnus): Add FAQ.
8
92015-02-05 Lars Ingebrigtsen <larsi@gnus.org>
10
11 * gnus.texi (Using IMAP): Fix menu node name.
12
132015-02-05 Trevor Murphy <trevor.m.murphy@gmail.com>
14
15 * gnus.texi (Support for IMAP Extensions): Document the Gmail label
16 extension.
17
12015-02-04 Paul Eggert <eggert@cs.ucla.edu> 182015-02-04 Paul Eggert <eggert@cs.ucla.edu>
2 19
3 * texinfo.tex: Update from gnulib. 20 * texinfo.tex: Update from gnulib.
diff --git a/doc/misc/auth.texi b/doc/misc/auth.texi
index 44fcad8d493..7c0254a9a3a 100644
--- a/doc/misc/auth.texi
+++ b/doc/misc/auth.texi
@@ -59,6 +59,7 @@ It is a way for multiple applications to share a single configuration
59@menu 59@menu
60* Overview:: Overview of the auth-source library. 60* Overview:: Overview of the auth-source library.
61* Help for users:: 61* Help for users::
62* Multiple GMail accounts with Gnus::
62* Secret Service API:: 63* Secret Service API::
63* Help for developers:: 64* Help for developers::
64* GnuPG and EasyPG Assistant Configuration:: 65* GnuPG and EasyPG Assistant Configuration::
@@ -229,6 +230,27 @@ don't use a port entry, you match any Tramp method, as explained
229earlier. Since Tramp has about 88 connection methods, this may be 230earlier. Since Tramp has about 88 connection methods, this may be
230necessary if you have an unusual (see earlier comment on those) setup. 231necessary if you have an unusual (see earlier comment on those) setup.
231 232
233@node Multiple GMail accounts with Gnus
234@chapter Multiple GMail accounts with Gnus
235
236For multiple GMail accounts with Gnus, you have to make two nnimap
237entries in your @code{gnus-secondary-select-methods} with distinct
238names:
239
240@example
241(setq gnus-secondary-select-methods '((nnimap "gmail"
242 (nnimap-address "imap.gmail.com"))
243 (nnimap "gmail2"
244 (nnimap-address "imap.gmail.com"))))
245@end example
246
247Your netrc entries will then be:
248
249@example
250machine gmail login account@@gmail.com password "accountpassword" port imap
251machine gmail2 login account2@@gmail.com password "account2password" port imap
252@end example
253
232@node Secret Service API 254@node Secret Service API
233@chapter Secret Service API 255@chapter Secret Service API
234 256
diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi
index cb808743ec2..d714656457f 100644
--- a/doc/misc/gnus.texi
+++ b/doc/misc/gnus.texi
@@ -14182,6 +14182,7 @@ from different locations, or with different user agents.
14182* Connecting to an IMAP Server:: Getting started with @acronym{IMAP}. 14182* Connecting to an IMAP Server:: Getting started with @acronym{IMAP}.
14183* Customizing the IMAP Connection:: Variables for @acronym{IMAP} connection. 14183* Customizing the IMAP Connection:: Variables for @acronym{IMAP} connection.
14184* Client-Side IMAP Splitting:: Put mail in the correct mail box. 14184* Client-Side IMAP Splitting:: Put mail in the correct mail box.
14185* Support for IMAP Extensions:: Getting extensions and labels from servers.
14185@end menu 14186@end menu
14186 14187
14187 14188
@@ -14328,6 +14329,29 @@ Here's a complete example @code{nnimap} backend with a client-side
14328@end example 14329@end example
14329 14330
14330 14331
14332@node Support for IMAP Extensions
14333@subsection Support for IMAP Extensions
14334
14335@cindex Gmail
14336@cindex X-GM-LABELS
14337@cindex IMAP labels
14338
14339If you're using Google's Gmail, you may want to see your Gmail labels
14340when reading your mail. Gnus can give you this information if you ask
14341for @samp{X-GM-LABELS} in the variable @code{gnus-extra-headers}. For
14342example:
14343
14344@example
14345(setq gnus-extra-headers
14346 '(To Newsgroups X-GM-LABELS))
14347@end example
14348
14349This will result in Gnus storing your labels in message header
14350structures for later use. The content is always a parenthesized
14351(possible empty) list.
14352
14353
14354
14331@node Getting Mail 14355@node Getting Mail
14332@section Getting Mail 14356@section Getting Mail
14333@cindex reading mail 14357@cindex reading mail
diff --git a/etc/ChangeLog b/etc/ChangeLog
index 37031890945..1fcea545a73 100644
--- a/etc/ChangeLog
+++ b/etc/ChangeLog
@@ -1,3 +1,7 @@
12015-02-08 Artur Malabarba <bruce.connor.am@gmail.com>
2
3 * NEWS: Document `comment-line'.
4
12015-02-03 Artur Malabarba <bruce.connor.am@gmail.com> 52015-02-03 Artur Malabarba <bruce.connor.am@gmail.com>
2 6
3 * NEWS: Document package.el's improved dependency-handling. 7 * NEWS: Document package.el's improved dependency-handling.
diff --git a/etc/GNUS-NEWS b/etc/GNUS-NEWS
index 4f311e3d9b5..ee3584fdb82 100644
--- a/etc/GNUS-NEWS
+++ b/etc/GNUS-NEWS
@@ -9,6 +9,8 @@ For older news, see Gnus info node "New Features".
9 9
10* New features 10* New features
11 11
12** nnimap can request and use the Gmail "X-GM-LABELS".
13
12** New package `gnus-notifications.el' can send notifications when you 14** New package `gnus-notifications.el' can send notifications when you
13 receive new messages. 15 receive new messages.
14 16
diff --git a/etc/NEWS b/etc/NEWS
index 72e23562868..4c7160ebca6 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -53,7 +53,7 @@ build with 'make V=1'.
53group instead of a user if its argument is prefixed by ':' (a colon). 53group instead of a user if its argument is prefixed by ':' (a colon).
54This will cause the game score files in ${localstatedir}/games/emacs 54This will cause the game score files in ${localstatedir}/games/emacs
55to be owned by that group, and the helper program for updating them to 55to be owned by that group, and the helper program for updating them to
56be installed setgid. 56be installed setgid. The option now defaults to the 'games' group.
57 57
58--- 58---
59** The `grep-changelog' script (and its manual page) are no longer included. 59** The `grep-changelog' script (and its manual page) are no longer included.
@@ -66,6 +66,8 @@ so if you want to use it, you can always take a copy from an older Emacs.
66 66
67* Changes in Emacs 25.1 67* Changes in Emacs 25.1
68 68
69** New command `comment-line' bound to `C-x C-;'.
70
69** New function `custom-prompt-customize-unsaved-options' checks for 71** New function `custom-prompt-customize-unsaved-options' checks for
70unsaved customizations and prompts user to customize (if found). 72unsaved customizations and prompts user to customize (if found).
71 73
@@ -599,6 +601,10 @@ in languages like German where downcasing rules depend on grammar.
599 601
600* Lisp Changes in Emacs 25.1 602* Lisp Changes in Emacs 25.1
601 603
604** lexical closures can use (:documentation <form>) to build their docstring.
605It should be placed right where the docstring would be, and <form> is then
606evaluated (and should return a string) when the closure is built.
607
602** define-inline provides a new way to define inlinable functions. 608** define-inline provides a new way to define inlinable functions.
603 609
604** New function macroexpand-1 to perform a single step of macroexpansion. 610** New function macroexpand-1 to perform a single step of macroexpansion.
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 9e473e21626..ad4f3b9a7f3 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,200 @@
12015-02-08 Artur Malabarba <bruce.connor.am@gmail.com>
2
3 * newcomment.el (comment-line): Fix missing paren.
4
52015-02-08 Ulrich Müller <ulm@gentoo.org>
6
7 * play/gamegrid.el: Update comment to reflect that the
8 'update-game-score' helper program is now setgid by default.
9
102015-02-08 David Kastrup <dak@gnu.org>
11
12 * subr.el (apply-partially): Use lexical binding here.
13
142015-02-08 Artur Malabarba <bruce.connor.am@gmail.com>
15
16 * newcomment.el (comment-line): New command.
17
18 * bindings.el (ctl-x-map): Bind to `C-x C-;'.
19
202015-02-08 Oleh Krehel <ohwoeowho@gmail.com>
21
22 * outline.el (outline-show-entry): Fix one invisible char for the
23 file's last outline. Fixes Bug#19493.
24
252015-02-08 Stefan Monnier <monnier@iro.umontreal.ca>
26
27 * subr.el (indirect-function): Change advertised calling convention.
28
292015-02-08 Fabián Ezequiel Gallina <fgallina@gnu.org>
30
31 python.el: Fix completion-at-point. (Bug#19667)
32
33 * progmodes/python.el
34 (python-shell-completion-native-get-completions): Force process buffer.
35 (python-shell-completion-at-point): Handle case where call is not
36 in a shell buffer.
37
382015-02-08 Fabián Ezequiel Gallina <fgallina@gnu.org>
39
40 python.el: Fix shell font-lock multiline input. (Bug#19744)
41
42 * progmodes/python.el
43 (python-shell-font-lock-post-command-hook): Handle multiline input.
44
452015-02-08 Fabián Ezequiel Gallina <fgallina@gnu.org>
46
47 python.el: Make shell font-lock respect markers. (Bug#19650)
48
49 * progmodes/python.el (python-shell-font-lock-cleanup-buffer):
50 Use `erase-buffer`.
51 (python-shell-font-lock-comint-output-filter-function):
52 Handle newlines.
53 (python-shell-font-lock-post-command-hook): Respect markers on
54 text fontification.
55
562015-02-07 Fabián Ezequiel Gallina <fgallina@gnu.org>
57
58 python.el: Keep eldoc visible while typing args. (Bug#19637)
59
60 * progmodes/python.el (python-eldoc--get-symbol-at-point):
61 New function based on Carlos Pita <carlosjosepita@gmail.com> patch.
62 (python-eldoc--get-doc-at-point, python-eldoc-at-point): Use it.
63
642015-02-07 Fabián Ezequiel Gallina <fgallina@gnu.org>
65
66 Fix hideshow integration. (Bug#19761)
67
68 * progmodes/python.el
69 (python-hideshow-forward-sexp-function): New function based on
70 Carlos Pita <carlosjosepita@gmail.com> patch.
71 (python-mode): Make `hs-special-modes-alist` use it and initialize
72 the end regexp with the empty string to avoid skipping parens.
73
742015-02-07 Fabián Ezequiel Gallina <fgallina@gnu.org>
75
76 * progmodes/python.el (python-check-custom-command): Do not use
77 defvar-local for compat with Emacs<24.3.
78
792015-02-07 Martin Rudalics <rudalics@gmx.at>
80
81 * frame.el (frame-notice-user-settings):
82 Update `frame-size-history'.
83 (make-frame): Update `frame-size-history'.
84 Call `frame-after-make-frame'.
85 * faces.el (face-set-after-frame-default): Remove call to
86 frame-can-run-window-configuration-change-hook.
87
882015-02-06 Dmitry Gutov <dgutov@yandex.ru>
89
90 * vc/vc-cvs.el (vc-cvs-dir-status-files): Don't pass DIR to
91 `vc-cvs-command' (bug#19732).
92
932015-02-06 Nicolas Petton <nicolas@petton.fr>
94
95 * emacs-lisp/seq.el (seq-mapcat, seq-partition, seq-group-by): New functions.
96 * emacs-lisp/seq.el (seq-drop-while, seq-take-while, seq-count)
97 (seq--drop-list, seq--take-list, seq--take-while-list): Better docstring.
98
992015-02-06 Artur Malabarba <bruce.connor.am@gmail.com>
100
101 * doc-view.el (doc-view-kill-proc-and-buffer): Obsolete. Use
102 `image-kill-buffer' instead.
103
1042015-02-06 Thomas Fitzsimmons <fitzsim@fitzsim.org>
105
106 * net/ldap.el (ldap-search-internal): Fix docstring.
107
1082015-02-06 Lars Ingebrigtsen <larsi@gnus.org>
109
110 * subr.el (define-error): The error conditions may be constant
111 lists, so use `append' to concatenate them.
112
1132015-02-06 Wolfgang Jenkner <wjenkner@inode.at>
114
115 * net/network-stream.el (network-stream-open-tls): Respect the
116 :end-of-capability setting.
117
1182015-02-05 Artur Malabarba <bruce.connor.am@gmail.com>
119
120 * emacs-lisp/package.el (package--sort-by-dependence):
121 New function. Return PACKAGE-LIST sorted by dependencies.
122 (package-menu-execute): Use it to delete packages in order.
123 (package--sort-deps-in-alist): New function.
124 (package-menu-mark-install): Can mark dependencies.
125 (package--newest-p): New function.
126 (package-delete): Don't delesect when deleting an older version of
127 an upgraded package.
128
129 * emacs-lisp/package.el: Add missing (require 'subr-x)
130
1312015-02-05 Stefan Monnier <monnier@iro.umontreal.ca>
132
133 * textmodes/css-mode.el (scss-smie--not-interpolation-p): Vars can be
134 hyphenated (bug#19263).
135
136 * textmodes/css-mode.el (css-fill-paragraph): Fix filling in presence
137 of variable interpolation (bug#19751).
138
1392015-02-05 Era Eriksson <era+emacs@iki.fi>
140
141 * json.el (json-end-of-file): New error (bug#19768).
142 (json-pop, json-read): Use it.
143
1442015-02-05 Kelly Dean <kelly@prtime.org>
145
146 * help-mode.el (help-xref-interned): Pass BUFFER and FRAME to
147 `describe-variable'.
148
149 * help-fns.el (describe-function-or-variable): New function.
150
151 * help.el (help-map): Bind `describe-function-or-variable' to o.
152 (help-for-help-internal): Document o key.
153
1542015-02-05 Stefan Monnier <monnier@iro.umontreal.ca>
155
156 * emacs-lisp/eieio-compat.el (eieio--defmethod): Use new
157 special (:documentation ...) feature.
158 * emacs-lisp/eieio-core.el (eieio-make-class-predicate)
159 (eieio-make-child-predicate): Same.
160 (eieio-copy-parents-into-subclass): Remove unused arg.
161 (eieio-defclass-internal): Adjust call accordingly and remove redundant
162 `pname' var.
163 (eieio--slot-name-index): Remove unused arg `obj' and adjust all
164 callers accordingly.
165
166 * emacs-lisp/cconv.el (cconv--convert-function):
167 Add `docstring' argument.
168 (cconv-convert): Use it to handle the new (:documentation ...) form.
169 (cconv-analyze-form): Handle the new (:documentation ...) form.
170
171 * emacs-lisp/bytecomp.el:
172 (byte-compile-initial-macro-environment): Use macroexp-progn.
173 (byte-compile-cl-warn): Don't silence use of cl-macroexpand-all.
174 (byte-compile-file-form-defvar-function): Rename from
175 byte-compile-file-form-define-abbrev-table.
176 (defvaralias, byte-compile-file-form-custom-declare-variable): Use it.
177 (byte-compile): Use byte-compile-top-level rather than
178 byte-compile-lambda so we can compile non-values.
179 (byte-compile-form): Add warnings for failed uses of lexical vars via
180 quoted symbols.
181 (byte-compile-unfold-bcf): Improve message for failed inlining.
182 (byte-compile-make-closure): Handle new format of internal-make-closure
183 for dynamically-generated docstrings.
184
185 * delsel.el: Deprecate the `kill' option. Use lexical-binding.
186 (open-line): Delete like all other commands, instead of killing.
187 (delete-active-region): Don't define any return any value.
188
189 * progmodes/python.el: Try to preserve compatibility with Emacs-24.
190 (python-mode): Don't assume eldoc-documentation-function has a non-nil
191 default.
192
1932015-02-04 Sam Steingold <sds@gnu.org>
194
195 * progmodes/python.el (python-indent-calculate-indentation):
196 Avoid the error when computing top-level indentation.
197
12015-02-04 Stefan Monnier <monnier@iro.umontreal.ca> 1982015-02-04 Stefan Monnier <monnier@iro.umontreal.ca>
2 199
3 * emacs-lisp/cl-generic.el (cl--generic-member-method): Fix paren typo. 200 * emacs-lisp/cl-generic.el (cl--generic-member-method): Fix paren typo.
@@ -14,6 +211,9 @@
14 211
152015-02-04 Artur Malabarba <bruce.connor.am@gmail.com> 2122015-02-04 Artur Malabarba <bruce.connor.am@gmail.com>
16 213
214 * image-mode.el (image-kill-buffer): New command.
215 (image-mode-map): Bind it to k.
216
17 * emacs-lisp/package.el (package-delete): Remove package from 217 * emacs-lisp/package.el (package-delete): Remove package from
18 `package-selected-packages' even if it can't be deleted. 218 `package-selected-packages' even if it can't be deleted.
19 (package-installed-p): Accept package-desc objects. 219 (package-installed-p): Accept package-desc objects.
@@ -14330,7 +14530,7 @@
14330 Change default to "# encoding: %s" to differentiate it from the 14530 Change default to "# encoding: %s" to differentiate it from the
14331 default Ruby encoding comment template. 14531 default Ruby encoding comment template.
14332 14532
143332013-11-20 era eriksson <era+emacsbugs@iki.fi> 145332013-11-20 Era Eriksson <era+emacsbugs@iki.fi>
14334 14534
14335 * ses.el (ses-mode): Doc fix. (Bug#14748) 14535 * ses.el (ses-mode): Doc fix. (Bug#14748)
14336 14536
diff --git a/lisp/bindings.el b/lisp/bindings.el
index 883914ecdc2..4cc9f6ad368 100644
--- a/lisp/bindings.el
+++ b/lisp/bindings.el
@@ -1130,6 +1130,7 @@ if `inhibit-field-text-motion' is non-nil."
1130(define-key esc-map "j" 'indent-new-comment-line) 1130(define-key esc-map "j" 'indent-new-comment-line)
1131(define-key esc-map "\C-j" 'indent-new-comment-line) 1131(define-key esc-map "\C-j" 'indent-new-comment-line)
1132(define-key ctl-x-map ";" 'comment-set-column) 1132(define-key ctl-x-map ";" 'comment-set-column)
1133(define-key ctl-x-map "C-;" 'comment-line)
1133(define-key ctl-x-map "f" 'set-fill-column) 1134(define-key ctl-x-map "f" 'set-fill-column)
1134(define-key ctl-x-map "$" 'set-selective-display) 1135(define-key ctl-x-map "$" 'set-selective-display)
1135 1136
diff --git a/lisp/delsel.el b/lisp/delsel.el
index e6bb3b952b3..740b60345ed 100644
--- a/lisp/delsel.el
+++ b/lisp/delsel.el
@@ -1,4 +1,4 @@
1;;; delsel.el --- delete selection if you insert 1;;; delsel.el --- delete selection if you insert -*- lexical-binding:t -*-
2 2
3;; Copyright (C) 1992, 1997-1998, 2001-2015 Free Software Foundation, 3;; Copyright (C) 1992, 1997-1998, 2001-2015 Free Software Foundation,
4;; Inc. 4;; Inc.
@@ -35,16 +35,12 @@
35;; property on their symbols; commands which insert text but don't 35;; property on their symbols; commands which insert text but don't
36;; have this property won't delete the selection. It can be one of 36;; have this property won't delete the selection. It can be one of
37;; the values: 37;; the values:
38;; 'yank 38;; `yank'
39;; For commands which do a yank; ensures the region about to be 39;; For commands which do a yank; ensures the region about to be
40;; deleted isn't yanked. 40;; deleted isn't yanked.
41;; 'supersede 41;; `supersede'
42;; Delete the active region and ignore the current command, 42;; Delete the active region and ignore the current command,
43;; i.e. the command will just delete the region. 43;; i.e. the command will just delete the region.
44;; 'kill
45;; `kill-region' is used on the selection, rather than
46;; `delete-region'. (Text selected with the mouse will typically
47;; be yankable anyhow.)
48;; t 44;; t
49;; The normal case: delete the active region prior to executing 45;; The normal case: delete the active region prior to executing
50;; the command which will insert replacement text. 46;; the command which will insert replacement text.
@@ -93,8 +89,7 @@ If KILLP in not-nil, the active region is killed instead of deleted."
93 (cons (current-buffer) 89 (cons (current-buffer)
94 (and (consp buffer-undo-list) (car buffer-undo-list))))) 90 (and (consp buffer-undo-list) (car buffer-undo-list)))))
95 (t 91 (t
96 (funcall region-extract-function 'delete-only))) 92 (funcall region-extract-function 'delete-only))))
97 t)
98 93
99(defun delete-selection-repeat-replace-region (arg) 94(defun delete-selection-repeat-replace-region (arg)
100 "Repeat replacing text of highlighted region with typed text. 95 "Repeat replacing text of highlighted region with typed text.
@@ -167,7 +162,7 @@ With ARG, repeat that many times. `C-u' means until end of buffer."
167 For commands which need to dynamically determine this behavior. 162 For commands which need to dynamically determine this behavior.
168 FUNCTION should take no argument and return one of the above values or nil." 163 FUNCTION should take no argument and return one of the above values or nil."
169 (condition-case data 164 (condition-case data
170 (cond ((eq type 'kill) 165 (cond ((eq type 'kill) ;Deprecated, backward compatibility.
171 (delete-active-region t) 166 (delete-active-region t)
172 (if (and overwrite-mode 167 (if (and overwrite-mode
173 (eq this-command 'self-insert-command)) 168 (eq this-command 'self-insert-command))
@@ -255,7 +250,7 @@ See `delete-selection-helper'."
255(put 'newline-and-indent 'delete-selection t) 250(put 'newline-and-indent 'delete-selection t)
256(put 'newline 'delete-selection t) 251(put 'newline 'delete-selection t)
257(put 'electric-newline-and-maybe-indent 'delete-selection t) 252(put 'electric-newline-and-maybe-indent 'delete-selection t)
258(put 'open-line 'delete-selection 'kill) 253(put 'open-line 'delete-selection t)
259 254
260;; This is very useful for canceling a selection in the minibuffer without 255;; This is very useful for canceling a selection in the minibuffer without
261;; aborting the minibuffer. 256;; aborting the minibuffer.
diff --git a/lisp/doc-view.el b/lisp/doc-view.el
index 0e63d37adc5..5f1c94a0128 100644
--- a/lisp/doc-view.el
+++ b/lisp/doc-view.el
@@ -415,7 +415,6 @@ Typically \"page-%s.png\".")
415 (define-key map "H" 'doc-view-fit-height-to-window) 415 (define-key map "H" 'doc-view-fit-height-to-window)
416 (define-key map "P" 'doc-view-fit-page-to-window) 416 (define-key map "P" 'doc-view-fit-page-to-window)
417 ;; Killing the buffer (and the process) 417 ;; Killing the buffer (and the process)
418 (define-key map (kbd "k") 'doc-view-kill-proc-and-buffer)
419 (define-key map (kbd "K") 'doc-view-kill-proc) 418 (define-key map (kbd "K") 'doc-view-kill-proc)
420 ;; Slicing the image 419 ;; Slicing the image
421 (define-key map (kbd "s s") 'doc-view-set-slice) 420 (define-key map (kbd "s s") 'doc-view-set-slice)
@@ -645,12 +644,8 @@ at the top edge of the page moves to the previous page."
645 (setq doc-view--current-timer nil)) 644 (setq doc-view--current-timer nil))
646 (setq mode-line-process nil)) 645 (setq mode-line-process nil))
647 646
648(defun doc-view-kill-proc-and-buffer () 647(define-obsolete-function-alias 'doc-view-kill-proc-and-buffer
649 "Kill the current converter process and buffer." 648 #'image-kill-buffer "25.1")
650 (interactive)
651 (doc-view-kill-proc)
652 (when (eq major-mode 'doc-view-mode)
653 (kill-buffer (current-buffer))))
654 649
655(defun doc-view-make-safe-dir (dir) 650(defun doc-view-make-safe-dir (dir)
656 (condition-case nil 651 (condition-case nil
@@ -1685,6 +1680,9 @@ If BACKWARD is non-nil, jump to the previous match."
1685;; desktop.el integration 1680;; desktop.el integration
1686 1681
1687(defun doc-view-desktop-save-buffer (_desktop-dirname) 1682(defun doc-view-desktop-save-buffer (_desktop-dirname)
1683 ;; FIXME: This is wrong, since this info is per-window but we only do it once
1684 ;; here for the buffer. IOW it should be saved via something like
1685 ;; `window-persistent-parameters'.
1688 `((page . ,(doc-view-current-page)) 1686 `((page . ,(doc-view-current-page))
1689 (slice . ,(doc-view-current-slice)))) 1687 (slice . ,(doc-view-current-slice))))
1690 1688
@@ -1695,8 +1693,13 @@ If BACKWARD is non-nil, jump to the previous match."
1695 (let ((page (cdr (assq 'page misc))) 1693 (let ((page (cdr (assq 'page misc)))
1696 (slice (cdr (assq 'slice misc)))) 1694 (slice (cdr (assq 'slice misc))))
1697 (desktop-restore-file-buffer file name misc) 1695 (desktop-restore-file-buffer file name misc)
1696 ;; FIXME: We need to run this code after displaying the buffer.
1698 (with-selected-window (or (get-buffer-window (current-buffer) 0) 1697 (with-selected-window (or (get-buffer-window (current-buffer) 0)
1699 (selected-window)) 1698 (selected-window))
1699 ;; FIXME: This should be done for all windows restored that show
1700 ;; this buffer. Basically, the page/slice should be saved as
1701 ;; window-parameters in the window-state(s) and then restoring this
1702 ;; window-state should call us back (to interpret/use those parameters).
1700 (doc-view-goto-page page) 1703 (doc-view-goto-page page)
1701 (when slice (apply 'doc-view-set-slice slice))))) 1704 (when slice (apply 'doc-view-set-slice slice)))))
1702 1705
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index 2bd8d07851b..548aaa9626b 100644
--- a/lisp/emacs-lisp/bytecomp.el
+++ b/lisp/emacs-lisp/bytecomp.el
@@ -31,6 +31,10 @@
31;; faster. [`LAP' == `Lisp Assembly Program'.] 31;; faster. [`LAP' == `Lisp Assembly Program'.]
32;; The user entry points are byte-compile-file and byte-recompile-directory. 32;; The user entry points are byte-compile-file and byte-recompile-directory.
33 33
34;;; Todo:
35
36;; - Turn "not bound at runtime" functions into autoloads.
37
34;;; Code: 38;;; Code:
35 39
36;; ======================================================================== 40;; ========================================================================
@@ -450,7 +454,7 @@ Return the compile-time value of FORM."
450 (eval-when-compile . ,(lambda (&rest body) 454 (eval-when-compile . ,(lambda (&rest body)
451 (let ((result nil)) 455 (let ((result nil))
452 (byte-compile-recurse-toplevel 456 (byte-compile-recurse-toplevel
453 (cons 'progn body) 457 (macroexp-progn body)
454 (lambda (form) 458 (lambda (form)
455 (setf result 459 (setf result
456 (byte-compile-eval 460 (byte-compile-eval
@@ -459,7 +463,7 @@ Return the compile-time value of FORM."
459 (list 'quote result)))) 463 (list 'quote result))))
460 (eval-and-compile . ,(lambda (&rest body) 464 (eval-and-compile . ,(lambda (&rest body)
461 (byte-compile-recurse-toplevel 465 (byte-compile-recurse-toplevel
462 (cons 'progn body) 466 (macroexp-progn body)
463 (lambda (form) 467 (lambda (form)
464 ;; Don't compile here, since we don't know 468 ;; Don't compile here, since we don't know
465 ;; whether to compile as byte-compile-form 469 ;; whether to compile as byte-compile-form
@@ -1458,7 +1462,7 @@ extra args."
1458 ;; These would sometimes be warned about 1462 ;; These would sometimes be warned about
1459 ;; but such warnings are never useful, 1463 ;; but such warnings are never useful,
1460 ;; so don't warn about them. 1464 ;; so don't warn about them.
1461 macroexpand cl-macroexpand-all 1465 macroexpand
1462 cl--compiling-file)))) 1466 cl--compiling-file))))
1463 (byte-compile-warn "function `%s' from cl package called at runtime" 1467 (byte-compile-warn "function `%s' from cl package called at runtime"
1464 func))) 1468 func)))
@@ -2319,10 +2323,12 @@ list that represents a doc string reference.
2319 form)) 2323 form))
2320 2324
2321(put 'define-abbrev-table 'byte-hunk-handler 2325(put 'define-abbrev-table 'byte-hunk-handler
2322 'byte-compile-file-form-define-abbrev-table) 2326 'byte-compile-file-form-defvar-function)
2323(defun byte-compile-file-form-define-abbrev-table (form) 2327(put 'defvaralias 'byte-hunk-handler 'byte-compile-file-form-defvar-function)
2324 (if (eq 'quote (car-safe (car-safe (cdr form)))) 2328
2325 (byte-compile--declare-var (car-safe (cdr (cadr form))))) 2329(defun byte-compile-file-form-defvar-function (form)
2330 (pcase-let (((or `',name (let name nil)) (nth 1 form)))
2331 (if name (byte-compile--declare-var name)))
2326 (byte-compile-keep-pending form)) 2332 (byte-compile-keep-pending form))
2327 2333
2328(put 'custom-declare-variable 'byte-hunk-handler 2334(put 'custom-declare-variable 'byte-hunk-handler
@@ -2330,8 +2336,7 @@ list that represents a doc string reference.
2330(defun byte-compile-file-form-custom-declare-variable (form) 2336(defun byte-compile-file-form-custom-declare-variable (form)
2331 (when (byte-compile-warning-enabled-p 'callargs) 2337 (when (byte-compile-warning-enabled-p 'callargs)
2332 (byte-compile-nogroup-warn form)) 2338 (byte-compile-nogroup-warn form))
2333 (byte-compile--declare-var (nth 1 (nth 1 form))) 2339 (byte-compile-file-form-defvar-function form))
2334 (byte-compile-keep-pending form))
2335 2340
2336(put 'require 'byte-hunk-handler 'byte-compile-file-form-require) 2341(put 'require 'byte-hunk-handler 'byte-compile-file-form-require)
2337(defun byte-compile-file-form-require (form) 2342(defun byte-compile-file-form-require (form)
@@ -2580,17 +2585,11 @@ If FORM is a lambda or a macro, byte-compile it as a function."
2580 fun) 2585 fun)
2581 (t 2586 (t
2582 (when (symbolp form) 2587 (when (symbolp form)
2583 (unless (memq (car-safe fun) '(closure lambda))
2584 (error "Don't know how to compile %S" fun))
2585 (setq lexical-binding (eq (car fun) 'closure)) 2588 (setq lexical-binding (eq (car fun) 'closure))
2586 (setq fun (byte-compile--reify-function fun))) 2589 (setq fun (byte-compile--reify-function fun)))
2587 (unless (eq (car-safe fun) 'lambda)
2588 (error "Don't know how to compile %S" fun))
2589 ;; Expand macros. 2590 ;; Expand macros.
2590 (setq fun (byte-compile-preprocess fun)) 2591 (setq fun (byte-compile-preprocess fun))
2591 ;; Get rid of the `function' quote added by the `lambda' macro. 2592 (setq fun (byte-compile-top-level fun nil 'eval))
2592 (if (eq (car-safe fun) 'function) (setq fun (cadr fun)))
2593 (setq fun (byte-compile-lambda fun))
2594 (if macro (push 'macro fun)) 2593 (if macro (push 'macro fun))
2595 (if (symbolp form) 2594 (if (symbolp form)
2596 (fset form fun) 2595 (fset form fun)
@@ -2966,6 +2965,16 @@ for symbols generated by the byte compiler itself."
2966 (interactive-only 2965 (interactive-only
2967 (or (get fn 'interactive-only) 2966 (or (get fn 'interactive-only)
2968 (memq fn byte-compile-interactive-only-functions)))) 2967 (memq fn byte-compile-interactive-only-functions))))
2968 (when (memq fn '(set symbol-value run-hooks ;; add-to-list
2969 add-hook remove-hook run-hook-with-args
2970 run-hook-with-args-until-success
2971 run-hook-with-args-until-failure))
2972 (pcase (cdr form)
2973 (`(',var . ,_)
2974 (when (assq var byte-compile-lexical-variables)
2975 (byte-compile-log-warning
2976 (format "%s cannot use lexical var `%s'" fn var)
2977 nil :error)))))
2969 (when (macroexp--const-symbol-p fn) 2978 (when (macroexp--const-symbol-p fn)
2970 (byte-compile-warn "`%s' called as a function" fn)) 2979 (byte-compile-warn "`%s' called as a function" fn))
2971 (when (and (byte-compile-warning-enabled-p 'interactive-only) 2980 (when (and (byte-compile-warning-enabled-p 'interactive-only)
@@ -3079,8 +3088,9 @@ for symbols generated by the byte compiler itself."
3079 (dotimes (_ (- (/ (1+ fmax2) 2) alen)) 3088 (dotimes (_ (- (/ (1+ fmax2) 2) alen))
3080 (byte-compile-push-constant nil))) 3089 (byte-compile-push-constant nil)))
3081 ((zerop (logand fmax2 1)) 3090 ((zerop (logand fmax2 1))
3082 (byte-compile-log-warning "Too many arguments for inlined function" 3091 (byte-compile-log-warning
3083 nil :error) 3092 (format "Too many arguments for inlined function %S" form)
3093 nil :error)
3084 (byte-compile-discard (- alen (/ fmax2 2)))) 3094 (byte-compile-discard (- alen (/ fmax2 2))))
3085 (t 3095 (t
3086 ;; Turn &rest args into a list. 3096 ;; Turn &rest args into a list.
@@ -3453,15 +3463,22 @@ discarding."
3453 (if byte-compile--for-effect (setq byte-compile--for-effect nil) 3463 (if byte-compile--for-effect (setq byte-compile--for-effect nil)
3454 (let* ((vars (nth 1 form)) 3464 (let* ((vars (nth 1 form))
3455 (env (nth 2 form)) 3465 (env (nth 2 form))
3456 (body (nthcdr 3 form)) 3466 (docstring-exp (nth 3 form))
3467 (body (nthcdr 4 form))
3457 (fun 3468 (fun
3458 (byte-compile-lambda `(lambda ,vars . ,body) nil (length env)))) 3469 (byte-compile-lambda `(lambda ,vars . ,body) nil (length env))))
3459 (cl-assert (> (length env) 0)) ;Otherwise, we don't need a closure. 3470 (cl-assert (or (> (length env) 0)
3471 docstring-exp)) ;Otherwise, we don't need a closure.
3460 (cl-assert (byte-code-function-p fun)) 3472 (cl-assert (byte-code-function-p fun))
3461 (byte-compile-form `(make-byte-code 3473 (byte-compile-form `(make-byte-code
3462 ',(aref fun 0) ',(aref fun 1) 3474 ',(aref fun 0) ',(aref fun 1)
3463 (vconcat (vector . ,env) ',(aref fun 2)) 3475 (vconcat (vector . ,env) ',(aref fun 2))
3464 ,@(nthcdr 3 (mapcar (lambda (x) `',x) fun))))))) 3476 ,@(let ((rest (nthcdr 3 (mapcar (lambda (x) `',x) fun))))
3477 (if docstring-exp
3478 `(,(car rest)
3479 ,docstring-exp
3480 ,@(cddr rest))
3481 rest)))))))
3465 3482
3466(defun byte-compile-get-closed-var (form) 3483(defun byte-compile-get-closed-var (form)
3467 "Byte-compile the special `internal-get-closed-var' form." 3484 "Byte-compile the special `internal-get-closed-var' form."
diff --git a/lisp/emacs-lisp/cconv.el b/lisp/emacs-lisp/cconv.el
index e9d33e6c646..fa824075933 100644
--- a/lisp/emacs-lisp/cconv.el
+++ b/lisp/emacs-lisp/cconv.el
@@ -48,7 +48,7 @@
48;; if the function is suitable for lambda lifting (if all calls are known) 48;; if the function is suitable for lambda lifting (if all calls are known)
49;; 49;;
50;; (lambda (v0 ...) ... fv0 .. fv1 ...) => 50;; (lambda (v0 ...) ... fv0 .. fv1 ...) =>
51;; (internal-make-closure (v0 ...) (fv1 ...) 51;; (internal-make-closure (v0 ...) (fv0 ...) <doc>
52;; ... (internal-get-closed-var 0) ... (internal-get-closed-var 1) ...) 52;; ... (internal-get-closed-var 0) ... (internal-get-closed-var 1) ...)
53;; 53;;
54;; If the function has no free variables, we don't do anything. 54;; If the function has no free variables, we don't do anything.
@@ -65,6 +65,14 @@
65;; 65;;
66;;; Code: 66;;; Code:
67 67
68;; PROBLEM cases found during conversion to lexical binding.
69;; We should try and detect and warn about those cases, even
70;; for lexical-binding==nil to help prepare the migration.
71;; - Uses of run-hooks, and friends.
72;; - Cases where we want to apply the same code to different vars depending on
73;; some test. These sometimes use a (let ((foo (if bar 'a 'b)))
74;; ... (symbol-value foo) ... (set foo ...)).
75
68;; TODO: (not just for cconv but also for the lexbind changes in general) 76;; TODO: (not just for cconv but also for the lexbind changes in general)
69;; - let (e)debug find the value of lexical variables from the stack. 77;; - let (e)debug find the value of lexical variables from the stack.
70;; - make eval-region do the eval-sexp-add-defvars dance. 78;; - make eval-region do the eval-sexp-add-defvars dance.
@@ -87,9 +95,8 @@
87;; the bytecomp only compiles it once. 95;; the bytecomp only compiles it once.
88;; - Since we know here when a variable is not mutated, we could pass that 96;; - Since we know here when a variable is not mutated, we could pass that
89;; info to the byte-compiler, e.g. by using a new `immutable-let'. 97;; info to the byte-compiler, e.g. by using a new `immutable-let'.
90;; - add tail-calls to bytecode.c and the byte compiler.
91;; - call known non-escaping functions with `goto' rather than `call'. 98;; - call known non-escaping functions with `goto' rather than `call'.
92;; - optimize mapcar to a while loop. 99;; - optimize mapc to a dolist loop.
93 100
94;; (defmacro dlet (binders &rest body) 101;; (defmacro dlet (binders &rest body)
95;; ;; Works in both lexical and non-lexical mode. 102;; ;; Works in both lexical and non-lexical mode.
@@ -195,7 +202,7 @@ Returns a form where all lambdas don't have any free variables."
195 (unless (memq (car b) s) (push b res))) 202 (unless (memq (car b) s) (push b res)))
196 (nreverse res))) 203 (nreverse res)))
197 204
198(defun cconv--convert-function (args body env parentform) 205(defun cconv--convert-function (args body env parentform &optional docstring)
199 (cl-assert (equal body (caar cconv-freevars-alist))) 206 (cl-assert (equal body (caar cconv-freevars-alist)))
200 (let* ((fvs (cdr (pop cconv-freevars-alist))) 207 (let* ((fvs (cdr (pop cconv-freevars-alist)))
201 (body-new '()) 208 (body-new '())
@@ -240,11 +247,11 @@ Returns a form where all lambdas don't have any free variables."
240 `(,@(nreverse special-forms) (let ,letbind . ,body-new))))) 247 `(,@(nreverse special-forms) (let ,letbind . ,body-new)))))
241 248
242 (cond 249 (cond
243 ((null envector) ;if no freevars - do nothing 250 ((not (or envector docstring)) ;If no freevars - do nothing.
244 `(function (lambda ,args . ,body-new))) 251 `(function (lambda ,args . ,body-new)))
245 (t 252 (t
246 `(internal-make-closure 253 `(internal-make-closure
247 ,args ,envector . ,body-new))))) 254 ,args ,envector ,docstring . ,body-new)))))
248 255
249(defun cconv-convert (form env extend) 256(defun cconv-convert (form env extend)
250 ;; This function actually rewrites the tree. 257 ;; This function actually rewrites the tree.
@@ -407,7 +414,9 @@ places where they originally did not directly appear."
407 cond-forms))) 414 cond-forms)))
408 415
409 (`(function (lambda ,args . ,body) . ,_) 416 (`(function (lambda ,args . ,body) . ,_)
410 (cconv--convert-function args body env form)) 417 (let ((docstring (if (eq :documentation (car-safe (car body)))
418 (cconv-convert (cadr (pop body)) env extend))))
419 (cconv--convert-function args body env form docstring)))
411 420
412 (`(internal-make-closure . ,_) 421 (`(internal-make-closure . ,_)
413 (byte-compile-report-error 422 (byte-compile-report-error
@@ -533,7 +542,7 @@ FORM is the parent form that binds this var."
533 ;; use = `(,binder ,read ,mutated ,captured ,called) 542 ;; use = `(,binder ,read ,mutated ,captured ,called)
534 (pcase vardata 543 (pcase vardata
535 (`(,_ nil nil nil nil) nil) 544 (`(,_ nil nil nil nil) nil)
536 (`((,(and (pred (lambda (var) (eq ?_ (aref (symbol-name var) 0)))) var) . ,_) 545 (`((,(and var (guard (eq ?_ (aref (symbol-name var) 0)))) . ,_)
537 ,_ ,_ ,_ ,_) 546 ,_ ,_ ,_ ,_)
538 (byte-compile-log-warning 547 (byte-compile-log-warning
539 (format "%s `%S' not left unused" varkind var)))) 548 (format "%s `%S' not left unused" varkind var))))
@@ -643,6 +652,8 @@ and updates the data stored in ENV."
643 (cconv--analyze-use vardata form "variable")))) 652 (cconv--analyze-use vardata form "variable"))))
644 653
645 (`(function (lambda ,vrs . ,body-forms)) 654 (`(function (lambda ,vrs . ,body-forms))
655 (when (eq :documentation (car-safe (car body-forms)))
656 (cconv-analyze-form (cadr (pop body-forms)) env))
646 (cconv--analyze-function vrs body-forms env form)) 657 (cconv--analyze-function vrs body-forms env form))
647 658
648 (`(setq . ,forms) 659 (`(setq . ,forms)
@@ -665,6 +676,10 @@ and updates the data stored in ENV."
665 (dolist (forms cond-forms) 676 (dolist (forms cond-forms)
666 (dolist (form forms) (cconv-analyze-form form env)))) 677 (dolist (form forms) (cconv-analyze-form form env))))
667 678
679 ;; ((and `(quote ,v . ,_) (guard (assq v env)))
680 ;; (byte-compile-log-warning
681 ;; (format "Possible confusion variable/symbol for `%S'" v)))
682
668 (`(quote . ,_) nil) ; quote form 683 (`(quote . ,_) nil) ; quote form
669 (`(function . ,_) nil) ; same as quote 684 (`(function . ,_) nil) ; same as quote
670 685
diff --git a/lisp/emacs-lisp/eieio-base.el b/lisp/emacs-lisp/eieio-base.el
index 46585ee76c6..fcf02b92736 100644
--- a/lisp/emacs-lisp/eieio-base.el
+++ b/lisp/emacs-lisp/eieio-base.el
@@ -290,8 +290,7 @@ constructor functions are considered valid.
290Second, any text properties will be stripped from strings." 290Second, any text properties will be stripped from strings."
291 (cond ((consp proposed-value) 291 (cond ((consp proposed-value)
292 ;; Lists with something in them need special treatment. 292 ;; Lists with something in them need special treatment.
293 (let ((slot-idx (eieio--slot-name-index class 293 (let ((slot-idx (eieio--slot-name-index class slot))
294 nil slot))
295 (type nil) 294 (type nil)
296 (classtype nil)) 295 (classtype nil))
297 (setq slot-idx (- slot-idx 296 (setq slot-idx (- slot-idx
diff --git a/lisp/emacs-lisp/eieio-compat.el b/lisp/emacs-lisp/eieio-compat.el
index fcca99d79d5..7468c040e10 100644
--- a/lisp/emacs-lisp/eieio-compat.el
+++ b/lisp/emacs-lisp/eieio-compat.el
@@ -188,11 +188,10 @@ Summary:
188 (args (help-function-arglist code 'preserve-names)) 188 (args (help-function-arglist code 'preserve-names))
189 (doc-only (if docstring 189 (doc-only (if docstring
190 (let ((split (help-split-fundoc docstring nil))) 190 (let ((split (help-split-fundoc docstring nil)))
191 (if split (cdr split) docstring)))) 191 (if split (cdr split) docstring)))))
192 (new-docstring (help-add-fundoc-usage doc-only
193 (cons 'cl-cnm args))))
194 ;; FIXME: ¡Add new-docstring to those closures!
195 (lambda (cnm &rest args) 192 (lambda (cnm &rest args)
193 (:documentation
194 (help-add-fundoc-usage doc-only (cons 'cl-cnm args)))
196 (cl-letf (((symbol-function 'call-next-method) cnm) 195 (cl-letf (((symbol-function 'call-next-method) cnm)
197 ((symbol-function 'next-method-p) 196 ((symbol-function 'next-method-p)
198 (lambda () (cl--generic-isnot-nnm-p cnm)))) 197 (lambda () (cl--generic-isnot-nnm-p cnm))))
diff --git a/lisp/emacs-lisp/eieio-core.el b/lisp/emacs-lisp/eieio-core.el
index 77d8c01388b..fa8fefa1df0 100644
--- a/lisp/emacs-lisp/eieio-core.el
+++ b/lisp/emacs-lisp/eieio-core.el
@@ -288,16 +288,17 @@ It creates an autoload function for CNAME's constructor."
288 288
289(defun eieio-make-class-predicate (class) 289(defun eieio-make-class-predicate (class)
290 (lambda (obj) 290 (lambda (obj)
291 ;; (:docstring (format "Test OBJ to see if it's an object of type %S." 291 (:documentation
292 ;; class)) 292 (format "Return non-nil if OBJ is an object of type `%S'.\n\n(fn OBJ)"
293 class))
293 (and (eieio-object-p obj) 294 (and (eieio-object-p obj)
294 (same-class-p obj class)))) 295 (same-class-p obj class))))
295 296
296(defun eieio-make-child-predicate (class) 297(defun eieio-make-child-predicate (class)
297 (lambda (obj) 298 (lambda (obj)
298 ;; (:docstring (format 299 (:documentation
299 ;; "Test OBJ to see if it's an object is a child of type %S." 300 (format "Return non-nil if OBJ is an object of type `%S' or a subclass.
300 ;; class)) 301\n(fn OBJ)" class))
301 (and (eieio-object-p obj) 302 (and (eieio-object-p obj)
302 (object-of-class-p obj class)))) 303 (object-of-class-p obj class))))
303 304
@@ -312,8 +313,7 @@ See `defclass' for more information."
312 (run-hooks 'eieio-hook) 313 (run-hooks 'eieio-hook)
313 (setq eieio-hook nil) 314 (setq eieio-hook nil)
314 315
315 (let* ((pname superclasses) 316 (let* ((oldc (let ((c (eieio--class-v cname))) (if (eieio--class-p c) c)))
316 (oldc (let ((c (eieio--class-v cname))) (if (eieio--class-p c) c)))
317 (newc (if (and oldc (not (eieio--class-default-object-cache oldc))) 317 (newc (if (and oldc (not (eieio--class-default-object-cache oldc)))
318 ;; The oldc class is a stub setup by eieio-defclass-autoload. 318 ;; The oldc class is a stub setup by eieio-defclass-autoload.
319 ;; Reuse it instead of creating a new one, so that existing 319 ;; Reuse it instead of creating a new one, so that existing
@@ -338,9 +338,9 @@ See `defclass' for more information."
338 (setf (eieio--class-children newc) children) 338 (setf (eieio--class-children newc) children)
339 (remhash cname eieio-defclass-autoload-map)))) 339 (remhash cname eieio-defclass-autoload-map))))
340 340
341 (if pname 341 (if superclasses
342 (progn 342 (progn
343 (dolist (p pname) 343 (dolist (p superclasses)
344 (if (not (and p (symbolp p))) 344 (if (not (and p (symbolp p)))
345 (error "Invalid parent class %S" p) 345 (error "Invalid parent class %S" p)
346 (let ((c (eieio--class-v p))) 346 (let ((c (eieio--class-v p)))
@@ -396,7 +396,7 @@ See `defclass' for more information."
396 396
397 ;; Before adding new slots, let's add all the methods and classes 397 ;; Before adding new slots, let's add all the methods and classes
398 ;; in from the parent class. 398 ;; in from the parent class.
399 (eieio-copy-parents-into-subclass newc superclasses) 399 (eieio-copy-parents-into-subclass newc)
400 400
401 ;; Store the new class vector definition into the symbol. We need to 401 ;; Store the new class vector definition into the symbol. We need to
402 ;; do this first so that we can call defmethod for the accessor. 402 ;; do this first so that we can call defmethod for the accessor.
@@ -784,7 +784,7 @@ if default value is nil."
784 )) 784 ))
785 )) 785 ))
786 786
787(defun eieio-copy-parents-into-subclass (newc _parents) 787(defun eieio-copy-parents-into-subclass (newc)
788 "Copy into NEWC the slots of PARENTS. 788 "Copy into NEWC the slots of PARENTS.
789Follow the rules of not overwriting early parents when applying to 789Follow the rules of not overwriting early parents when applying to
790the new child class." 790the new child class."
@@ -911,7 +911,7 @@ Argument FN is the function calling this verifier."
911 (if (eieio--class-p c) (eieio-class-un-autoload obj)) 911 (if (eieio--class-p c) (eieio-class-un-autoload obj))
912 c)) 912 c))
913 (t (eieio--object-class-object obj)))) 913 (t (eieio--object-class-object obj))))
914 (c (eieio--slot-name-index class obj slot))) 914 (c (eieio--slot-name-index class slot)))
915 (if (not c) 915 (if (not c)
916 ;; It might be missing because it is a :class allocated slot. 916 ;; It might be missing because it is a :class allocated slot.
917 ;; Let's check that info out. 917 ;; Let's check that info out.
@@ -935,7 +935,7 @@ Fills in OBJ's SLOT with its default value."
935 (cl-check-type slot symbol) 935 (cl-check-type slot symbol)
936 (let* ((cl (cond ((symbolp obj) (eieio--class-v obj)) 936 (let* ((cl (cond ((symbolp obj) (eieio--class-v obj))
937 (t (eieio--object-class-object obj)))) 937 (t (eieio--object-class-object obj))))
938 (c (eieio--slot-name-index cl obj slot))) 938 (c (eieio--slot-name-index cl slot)))
939 (if (not c) 939 (if (not c)
940 ;; It might be missing because it is a :class allocated slot. 940 ;; It might be missing because it is a :class allocated slot.
941 ;; Let's check that info out. 941 ;; Let's check that info out.
@@ -973,7 +973,7 @@ Fills in OBJ's SLOT with VALUE."
973 (cl-check-type obj eieio-object) 973 (cl-check-type obj eieio-object)
974 (cl-check-type slot symbol) 974 (cl-check-type slot symbol)
975 (let* ((class (eieio--object-class-object obj)) 975 (let* ((class (eieio--object-class-object obj))
976 (c (eieio--slot-name-index class obj slot))) 976 (c (eieio--slot-name-index class slot)))
977 (if (not c) 977 (if (not c)
978 ;; It might be missing because it is a :class allocated slot. 978 ;; It might be missing because it is a :class allocated slot.
979 ;; Let's check that info out. 979 ;; Let's check that info out.
@@ -997,7 +997,7 @@ Fills in the default value in CLASS' in SLOT with VALUE."
997 (setq class (eieio--class-object class)) 997 (setq class (eieio--class-object class))
998 (cl-check-type class eieio--class) 998 (cl-check-type class eieio--class)
999 (cl-check-type slot symbol) 999 (cl-check-type slot symbol)
1000 (let* ((c (eieio--slot-name-index class nil slot))) 1000 (let* ((c (eieio--slot-name-index class slot)))
1001 (if (not c) 1001 (if (not c)
1002 ;; It might be missing because it is a :class allocated slot. 1002 ;; It might be missing because it is a :class allocated slot.
1003 ;; Let's check that info out. 1003 ;; Let's check that info out.
@@ -1021,12 +1021,9 @@ Fills in the default value in CLASS' in SLOT with VALUE."
1021 1021
1022;;; EIEIO internal search functions 1022;;; EIEIO internal search functions
1023;; 1023;;
1024(defun eieio--slot-name-index (class obj slot) 1024(defun eieio--slot-name-index (class slot)
1025 "In CLASS for OBJ find the index of the named SLOT. 1025 "In CLASS find the index of the named SLOT.
1026The slot is a symbol which is installed in CLASS by the `defclass' 1026The slot is a symbol which is installed in CLASS by the `defclass' call.
1027call. OBJ can be nil, but if it is an object, and the slot in question
1028is protected, access will be allowed if OBJ is a child of the currently
1029scoped class.
1030If SLOT is the value created with :initarg instead, 1027If SLOT is the value created with :initarg instead,
1031reverse-lookup that name, and recurse with the associated slot value." 1028reverse-lookup that name, and recurse with the associated slot value."
1032 ;; Removed checks to outside this call 1029 ;; Removed checks to outside this call
@@ -1035,7 +1032,7 @@ reverse-lookup that name, and recurse with the associated slot value."
1035 (if (integerp fsi) 1032 (if (integerp fsi)
1036 (+ (eval-when-compile eieio--object-num-slots) fsi) 1033 (+ (eval-when-compile eieio--object-num-slots) fsi)
1037 (let ((fn (eieio--initarg-to-attribute class slot))) 1034 (let ((fn (eieio--initarg-to-attribute class slot)))
1038 (if fn (eieio--slot-name-index class obj fn) nil))))) 1035 (if fn (eieio--slot-name-index class fn) nil)))))
1039 1036
1040(defun eieio--class-slot-name-index (class slot) 1037(defun eieio--class-slot-name-index (class slot)
1041 "In CLASS find the index of the named SLOT. 1038 "In CLASS find the index of the named SLOT.
@@ -1255,7 +1252,7 @@ method invocation orders of the involved classes."
1255 (eieio--class-precedence-list tag)))) 1252 (eieio--class-precedence-list tag))))
1256 1253
1257 1254
1258;;;### (autoloads nil "eieio-compat" "eieio-compat.el" "b568ffb3c90ed5d0ae673f0051d608ee") 1255;;;### (autoloads nil "eieio-compat" "eieio-compat.el" "5b04c9a8fff2bd3f3d3ac54aba0f65b7")
1259;;; Generated autoloads from eieio-compat.el 1256;;; Generated autoloads from eieio-compat.el
1260 1257
1261(autoload 'eieio--defalias "eieio-compat" "\ 1258(autoload 'eieio--defalias "eieio-compat" "\
diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el
index 67cd44d6758..c3a2061aae2 100644
--- a/lisp/emacs-lisp/package.el
+++ b/lisp/emacs-lisp/package.el
@@ -161,6 +161,7 @@
161 161
162;;; Code: 162;;; Code:
163 163
164(eval-when-compile (require 'subr-x))
164(eval-when-compile (require 'cl-lib)) 165(eval-when-compile (require 'cl-lib))
165(eval-when-compile (require 'epg)) ;For setf accessors. 166(eval-when-compile (require 'epg)) ;For setf accessors.
166 167
@@ -1510,6 +1511,11 @@ with PKG-DESC entry removed."
1510 (and (memq pkg (mapcar #'car (package-desc-reqs (cadr p)))) 1511 (and (memq pkg (mapcar #'car (package-desc-reqs (cadr p))))
1511 (car p)))))) 1512 (car p))))))
1512 1513
1514(defun package--newest-p (pkg)
1515 "Return t if PKG is the newest package with its name."
1516 (equal (cadr (assq (package-desc-name pkg) package-alist))
1517 pkg))
1518
1513(defun package-delete (pkg-desc &optional force nosave) 1519(defun package-delete (pkg-desc &optional force nosave)
1514 "Delete package PKG-DESC. 1520 "Delete package PKG-DESC.
1515 1521
@@ -1527,7 +1533,10 @@ If NOSAVE is non-nil, the package is not removed from
1527 ;; don't want it marked as selected, so we remove it from 1533 ;; don't want it marked as selected, so we remove it from
1528 ;; `package-selected-packages' even if it can't be deleted. 1534 ;; `package-selected-packages' even if it can't be deleted.
1529 (when (and (null nosave) 1535 (when (and (null nosave)
1530 (package--user-selected-p name)) 1536 (package--user-selected-p name)
1537 ;; Don't delesect if this is an older version of an
1538 ;; upgraded package.
1539 (package--newest-p pkg-desc))
1531 (customize-save-variable 1540 (customize-save-variable
1532 'package-selected-packages (remove name package-selected-packages))) 1541 'package-selected-packages (remove name package-selected-packages)))
1533 (cond ((not (string-prefix-p (file-name-as-directory 1542 (cond ((not (string-prefix-p (file-name-as-directory
@@ -2262,7 +2271,7 @@ If optional arg BUTTON is non-nil, describe its associated package."
2262(defun package-menu-mark-install (&optional _num) 2271(defun package-menu-mark-install (&optional _num)
2263 "Mark a package for installation and move to the next line." 2272 "Mark a package for installation and move to the next line."
2264 (interactive "p") 2273 (interactive "p")
2265 (if (member (package-menu-get-status) '("available" "new")) 2274 (if (member (package-menu-get-status) '("available" "new" "dependency"))
2266 (tabulated-list-put-tag "I" t) 2275 (tabulated-list-put-tag "I" t)
2267 (forward-line))) 2276 (forward-line)))
2268 2277
@@ -2351,6 +2360,40 @@ call will upgrade the package."
2351 (length upgrades) 2360 (length upgrades)
2352 (if (= (length upgrades) 1) "" "s"))))) 2361 (if (= (length upgrades) 1) "" "s")))))
2353 2362
2363(defun package--sort-deps-in-alist (package only)
2364 "Return a list of dependencies for PACKAGE sorted by dependency.
2365PACKAGE is included as the first element of the returned list.
2366ONLY is an alist associating package names to package objects.
2367Only these packages will be in the return value an their cdrs are
2368destructively set to nil in ONLY."
2369 (let ((out))
2370 (dolist (dep (package-desc-reqs package))
2371 (when-let ((cell (assq (car dep) only))
2372 (dep-package (cdr-safe cell)))
2373 (setcdr cell nil)
2374 (setq out (append (package--sort-deps-in-alist dep-package only)
2375 out))))
2376 (cons package out)))
2377
2378(defun package--sort-by-dependence (package-list)
2379 "Return PACKAGE-LIST sorted by dependence.
2380That is, any element of the returned list is guaranteed to not
2381directly depend on any elements that come before it.
2382
2383PACKAGE-LIST is a list of package-desc objects.
2384Indirect dependencies are guaranteed to be returned in order only
2385if all the in-between dependencies are also in PACKAGE-LIST."
2386 (let ((alist (mapcar (lambda (p) (cons (package-desc-name p) p)) package-list))
2387 out-list)
2388 (dolist (cell alist out-list)
2389 ;; `package--sort-deps-in-alist' destructively changes alist, so
2390 ;; some cells might already be empty. We check this here.
2391 (when-let ((pkg-desc (cdr cell)))
2392 (setcdr cell nil)
2393 (setq out-list
2394 (append (package--sort-deps-in-alist pkg-desc alist)
2395 out-list))))))
2396
2354(defun package-menu-execute (&optional noquery) 2397(defun package-menu-execute (&optional noquery)
2355 "Perform marked Package Menu actions. 2398 "Perform marked Package Menu actions.
2356Packages marked for installation are downloaded and installed; 2399Packages marked for installation are downloaded and installed;
@@ -2384,7 +2427,13 @@ Optional argument NOQUERY non-nil means do not ask the user to confirm."
2384 (mapconcat #'package-desc-full-name 2427 (mapconcat #'package-desc-full-name
2385 install-list ", "))))) 2428 install-list ", ")))))
2386 (mapc (lambda (p) 2429 (mapc (lambda (p)
2387 (package-install p (null (package-installed-p p)))) 2430 ;; Mark as selected if it's the exact version of a
2431 ;; package that's already installed, or if it's not
2432 ;; installed at all. Don't mark if it's a new
2433 ;; version of an installed package.
2434 (package-install p (or (package-installed-p p)
2435 (not (package-installed-p
2436 (package-desc-name p))))))
2388 install-list))) 2437 install-list)))
2389 ;; Delete packages, prompting if necessary. 2438 ;; Delete packages, prompting if necessary.
2390 (when delete-list 2439 (when delete-list
@@ -2398,7 +2447,7 @@ Optional argument NOQUERY non-nil means do not ask the user to confirm."
2398 (length delete-list) 2447 (length delete-list)
2399 (mapconcat #'package-desc-full-name 2448 (mapconcat #'package-desc-full-name
2400 delete-list ", "))))) 2449 delete-list ", ")))))
2401 (dolist (elt delete-list) 2450 (dolist (elt (package--sort-by-dependence delete-list))
2402 (condition-case-unless-debug err 2451 (condition-case-unless-debug err
2403 (package-delete elt) 2452 (package-delete elt)
2404 (error (message (cadr err))))) 2453 (error (message (cadr err)))))
@@ -2412,7 +2461,8 @@ Optional argument NOQUERY non-nil means do not ask the user to confirm."
2412 (format "These %d packages are no longer needed, delete them (%s)? " 2461 (format "These %d packages are no longer needed, delete them (%s)? "
2413 (length removable) 2462 (length removable)
2414 (mapconcat #'symbol-name removable ", ")))) 2463 (mapconcat #'symbol-name removable ", "))))
2415 (mapc (lambda (p) (package-delete (cadr (assq p package-alist)))) 2464 ;; We know these are removable, so we can use force instead of sorting them.
2465 (mapc (lambda (p) (package-delete (cadr (assq p package-alist)) 'force 'nosave))
2416 removable)))) 2466 removable))))
2417 (package-menu--generate t t)))) 2467 (package-menu--generate t t))))
2418 2468
diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el
index b28153b7f81..025d94e10b9 100644
--- a/lisp/emacs-lisp/seq.el
+++ b/lisp/emacs-lisp/seq.el
@@ -2,9 +2,9 @@
2 2
3;; Copyright (C) 2014-2015 Free Software Foundation, Inc. 3;; Copyright (C) 2014-2015 Free Software Foundation, Inc.
4 4
5;; Author: Nicolas Petton <petton.nicolas@gmail.com> 5;; Author: Nicolas Petton <nicolas@petton.fr>
6;; Keywords: sequences 6;; Keywords: sequences
7;; Version: 1.0 7;; Version: 1.1
8 8
9;; Maintainer: emacs-devel@gnu.org 9;; Maintainer: emacs-devel@gnu.org
10 10
@@ -92,14 +92,14 @@ returned."
92 (seq-subseq seq 0 (min (max n 0) (seq-length seq))))) 92 (seq-subseq seq 0 (min (max n 0) (seq-length seq)))))
93 93
94(defun seq-drop-while (pred seq) 94(defun seq-drop-while (pred seq)
95 "Return a sequence, from the first element for which (PRED element) is nil, of SEQ. 95 "Return a sequence from the first element for which (PRED element) is nil in SEQ.
96The result is a sequence of the same type as SEQ." 96The result is a sequence of the same type as SEQ."
97 (if (listp seq) 97 (if (listp seq)
98 (seq--drop-while-list pred seq) 98 (seq--drop-while-list pred seq)
99 (seq-drop seq (seq--count-successive pred seq)))) 99 (seq-drop seq (seq--count-successive pred seq))))
100 100
101(defun seq-take-while (pred seq) 101(defun seq-take-while (pred seq)
102 "Return a sequence of the successive elements for which (PRED element) is non-nil in SEQ. 102 "Return the successive elements for which (PRED element) is non-nil in SEQ.
103The result is a sequence of the same type as SEQ." 103The result is a sequence of the same type as SEQ."
104 (if (listp seq) 104 (if (listp seq)
105 (seq--take-while-list pred seq) 105 (seq--take-while-list pred seq)
@@ -152,7 +152,7 @@ If SEQ is empty, return INITIAL-VALUE and FUNCTION is not called."
152 t)) 152 t))
153 153
154(defun seq-count (pred seq) 154(defun seq-count (pred seq)
155 "Return the number of elements for which (PRED element) returns non-nil in seq." 155 "Return the number of elements for which (PRED element) is non-nil in SEQ."
156 (let ((count 0)) 156 (let ((count 0))
157 (seq-doseq (elt seq) 157 (seq-doseq (elt seq)
158 (when (funcall pred elt) 158 (when (funcall pred elt)
@@ -224,15 +224,50 @@ TYPE must be one of following symbols: vector, string or list.
224 (`list (apply #'append (append seqs '(nil)))) 224 (`list (apply #'append (append seqs '(nil))))
225 (t (error "Not a sequence type name: %s" type)))) 225 (t (error "Not a sequence type name: %s" type))))
226 226
227(defun seq-mapcat (function seq &optional type)
228 "Concatenate the result of applying FUNCTION to each element of SEQ.
229The result is a sequence of type TYPE, or a list if TYPE is nil."
230 (apply #'seq-concatenate (or type 'list)
231 (seq-map function seq)))
232
233(defun seq-partition (seq n)
234 "Return a list of the elements of SEQ grouped into sub-sequences of length N.
235The last sequence may contain less than N elements. If N is a
236negative integer or 0, nil is returned."
237 (unless (< n 1)
238 (let ((result '()))
239 (while (not (seq-empty-p seq))
240 (push (seq-take seq n) result)
241 (setq seq (seq-drop seq n)))
242 (nreverse result))))
243
244(defun seq-group-by (function seq)
245 "Apply FUNCTION to each element of SEQ.
246Separate the elements of SEQ into an alist using the results as
247keys. Keys are compared using `equal'."
248 (nreverse
249 (seq-reduce
250 (lambda (acc elt)
251 (let* ((key (funcall function elt))
252 (cell (assoc key acc)))
253 (if cell
254 (setcdr cell (push elt (cdr cell)))
255 (push (list key elt) acc))
256 acc))
257 seq
258 nil)))
259
227(defun seq--drop-list (list n) 260(defun seq--drop-list (list n)
228 "Optimized version of `seq-drop' for lists." 261 "Return a list from LIST without its first N elements.
262This is an optimization for lists in `seq-drop'."
229 (while (and list (> n 0)) 263 (while (and list (> n 0))
230 (setq list (cdr list) 264 (setq list (cdr list)
231 n (1- n))) 265 n (1- n)))
232 list) 266 list)
233 267
234(defun seq--take-list (list n) 268(defun seq--take-list (list n)
235 "Optimized version of `seq-take' for lists." 269 "Return a list from LIST made of its first N elements.
270This is an optimization for lists in `seq-take'."
236 (let ((result '())) 271 (let ((result '()))
237 (while (and list (> n 0)) 272 (while (and list (> n 0))
238 (setq n (1- n)) 273 (setq n (1- n))
@@ -240,13 +275,15 @@ TYPE must be one of following symbols: vector, string or list.
240 (nreverse result))) 275 (nreverse result)))
241 276
242(defun seq--drop-while-list (pred list) 277(defun seq--drop-while-list (pred list)
243 "Optimized version of `seq-drop-while' for lists." 278 "Return a list from the first element for which (PRED element) is nil in LIST.
279This is an optimization for lists in `seq-drop-while'."
244 (while (and list (funcall pred (car list))) 280 (while (and list (funcall pred (car list)))
245 (setq list (cdr list))) 281 (setq list (cdr list)))
246 list) 282 list)
247 283
248(defun seq--take-while-list (pred list) 284(defun seq--take-while-list (pred list)
249 "Optimized version of `seq-take-while' for lists." 285 "Return the successive elements for which (PRED element) is non-nil in LIST.
286This is an optimization for lists in `seq-take-while'."
250 (let ((result '())) 287 (let ((result '()))
251 (while (and list (funcall pred (car list))) 288 (while (and list (funcall pred (car list)))
252 (push (pop list) result)) 289 (push (pop list) result))
diff --git a/lisp/emulation/viper-cmd.el b/lisp/emulation/viper-cmd.el
index e41109a5619..bd03a870fdb 100644
--- a/lisp/emulation/viper-cmd.el
+++ b/lisp/emulation/viper-cmd.el
@@ -961,11 +961,11 @@ Suffixes such as .el or .elc should be stripped."
961(defun viper-ESC (arg) 961(defun viper-ESC (arg)
962 "Emulate ESC key in Emacs. 962 "Emulate ESC key in Emacs.
963Prevents multiple escape keystrokes if viper-no-multiple-ESC is true. 963Prevents multiple escape keystrokes if viper-no-multiple-ESC is true.
964If viper-no-multiple-ESC is 'twice double ESC would ding in vi-state. 964If `viper-no-multiple-ESC' is `twice' double ESC would ding in vi-state.
965Other ESC sequences are emulated via the current Emacs's major mode 965Other ESC sequences are emulated via the current Emacs's major mode
966keymap. This is more convenient on TTYs, since this won't block 966keymap. This is more convenient on TTYs, since this won't block
967function keys such as up, down, etc. ESC will also will also work as 967function keys such as up, down, etc. ESC will also will also work as
968a Meta key in this case. When viper-no-multiple-ESC is nil, ESC works 968a Meta key in this case. When `viper-no-multiple-ESC' is nil, ESC works
969as a Meta key and any number of multiple escapes are allowed." 969as a Meta key and any number of multiple escapes are allowed."
970 (interactive "P") 970 (interactive "P")
971 (let (char) 971 (let (char)
diff --git a/lisp/emulation/viper-keym.el b/lisp/emulation/viper-keym.el
index 179ae169eca..250c292d72e 100644
--- a/lisp/emulation/viper-keym.el
+++ b/lisp/emulation/viper-keym.el
@@ -60,13 +60,13 @@ Full Vi compatibility is not recommended for power use of Viper."
60 :group 'viper) 60 :group 'viper)
61 61
62(defcustom viper-no-multiple-ESC t 62(defcustom viper-no-multiple-ESC t
63 "If true, multiple ESC in Vi mode will cause bell to ring. 63 "If non-nil, multiple ESC in Vi mode will cause bell to ring.
64This is set to t on a windowing terminal and to 'twice on a dumb 64This is set to t on a windowing terminal and to `twice' on a dumb
65terminal (unless the user level is 1, 2, or 5). On a dumb terminal, this 65terminal (unless the user level is 1, 2, or 5). On a dumb terminal, this
66enables cursor keys and is generally more convenient, as terminals usually 66enables cursor keys and is generally more convenient, as terminals usually
67don't have a convenient Meta key. 67don't have a convenient Meta key.
68Setting viper-no-multiple-ESC to nil will allow as many multiple ESC, 68Setting it to nil will allow as many multiple ESC, as is allowed by the
69as is allowed by the major mode in effect." 69major mode in effect."
70 :type 'boolean 70 :type 'boolean
71 :group 'viper) 71 :group 'viper)
72 72
diff --git a/lisp/faces.el b/lisp/faces.el
index 22bf2626722..ce74c728474 100644
--- a/lisp/faces.el
+++ b/lisp/faces.el
@@ -2092,8 +2092,7 @@ frame parameters in PARAMETERS."
2092 (value (cdr (assq param-name parameters)))) 2092 (value (cdr (assq param-name parameters))))
2093 (if value 2093 (if value
2094 (set-face-attribute (nth 1 param) frame 2094 (set-face-attribute (nth 1 param) frame
2095 (nth 2 param) value)))) 2095 (nth 2 param) value))))))
2096 (frame-can-run-window-configuration-change-hook frame t)))
2097 2096
2098(defun tty-handle-reverse-video (frame parameters) 2097(defun tty-handle-reverse-video (frame parameters)
2099 "Handle the reverse-video frame parameter for terminal frames." 2098 "Handle the reverse-video frame parameter for terminal frames."
diff --git a/lisp/frame.el b/lisp/frame.el
index 1d5bbf2317e..ecb433e8335 100644
--- a/lisp/frame.el
+++ b/lisp/frame.el
@@ -465,6 +465,16 @@ there (in decreasing order of priority)."
465 (frame-set-background-mode frame-initial-frame)) 465 (frame-set-background-mode frame-initial-frame))
466 (face-set-after-frame-default frame-initial-frame) 466 (face-set-after-frame-default frame-initial-frame)
467 (setq newparms (delq new-bg newparms))) 467 (setq newparms (delq new-bg newparms)))
468
469 (when (numberp (car frame-size-history))
470 (setq frame-size-history
471 (cons (1- (car frame-size-history))
472 (cons
473 (list frame-initial-frame
474 "frame-notice-user-settings"
475 nil newparms)
476 (cdr frame-size-history)))))
477
468 (modify-frame-parameters frame-initial-frame newparms))))) 478 (modify-frame-parameters frame-initial-frame newparms)))))
469 479
470 ;; Restore the original buffer. 480 ;; Restore the original buffer.
@@ -686,7 +696,7 @@ the new frame according to its own rules."
686 ;; Now make the frame. 696 ;; Now make the frame.
687 (run-hooks 'before-make-frame-hook) 697 (run-hooks 'before-make-frame-hook)
688 698
689;; (setq frame-adjust-size-history '(t)) 699;; (setq frame-size-history '(1000))
690 700
691 (setq frame 701 (setq frame
692 (funcall (gui-method frame-creation-function w) params)) 702 (funcall (gui-method frame-creation-function w) params))
@@ -697,11 +707,14 @@ the new frame according to its own rules."
697 (let ((val (frame-parameter oldframe param))) 707 (let ((val (frame-parameter oldframe param)))
698 (when val (set-frame-parameter frame param val))))) 708 (when val (set-frame-parameter frame param val)))))
699 709
700 (when (eq (car frame-adjust-size-history) t) 710 (when (numberp (car frame-size-history))
701 (setq frame-adjust-size-history 711 (setq frame-size-history
702 (cons t (cons (list "Frame made") 712 (cons (1- (car frame-size-history))
703 (cdr frame-adjust-size-history))))) 713 (cons (list frame "make-frame")
714 (cdr frame-size-history)))))
704 715
716 ;; We can run `window-configuration-change-hook' for this frame now.
717 (frame-after-make-frame frame t)
705 (run-hook-with-args 'after-make-frame-functions frame) 718 (run-hook-with-args 'after-make-frame-functions frame)
706 frame)) 719 frame))
707 720
diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog
index 841cff57ea2..32d3f08f586 100644
--- a/lisp/gnus/ChangeLog
+++ b/lisp/gnus/ChangeLog
@@ -1,3 +1,33 @@
12015-02-05 Teodor Zlatanov <tzz@lifelogs.com>
2
3 * gnus-start.el (gnus-save-newsrc-file-check-timestamp): Remove
4 variable; always check the newrc timestamp.
5 (gnus-save-newsrc-file): Always check timestamp.
6
72015-02-05 Timo Lilja <timo.lilja@iki.fi> (tiny change)
8
9 * mail-source.el (mail-source-call-script): If scripts exit with an
10 error, pop up an error buffer.
11
122015-02-05 Lars Ingebrigtsen <larsi@gnus.org>
13
14 * gnus-sum.el (gnus-extra-headers): Add the popular Gmail X-GM-LABELS
15 as a default.
16
17 * nnimap.el (nnimap-request-group-scan): Ensure that we've selected the
18 correct server.
19
202015-02-05 Vincent Bernat <bernat@luffy.cx> (tiny change)
21
22 * nnimap.el (nnimap-request-group-scan): Fix the function name.
23
24 * gnus-int.el (gnus-request-group-scan): Use the correct function name.
25
262015-02-05 Lars Ingebrigtsen <larsi@gnus.org>
27
28 * gnus-sum.el (gnus-select-newsgroup): Pass the group info along so
29 that nnimap works for non-activated backends.
30
12015-02-04 Stefan Monnier <monnier@iro.umontreal.ca> 312015-02-04 Stefan Monnier <monnier@iro.umontreal.ca>
2 32
3 * mm-util.el (mm-with-unibyte-current-buffer): Don't emit a warning 33 * mm-util.el (mm-with-unibyte-current-buffer): Don't emit a warning
diff --git a/lisp/gnus/gnus-int.el b/lisp/gnus/gnus-int.el
index dd938ce0758..4e870bb84bb 100644
--- a/lisp/gnus/gnus-int.el
+++ b/lisp/gnus/gnus-int.el
@@ -442,7 +442,7 @@ If it is down, start it up (again)."
442(defun gnus-request-group-scan (group info) 442(defun gnus-request-group-scan (group info)
443 "Request that GROUP get a complete rescan." 443 "Request that GROUP get a complete rescan."
444 (let ((gnus-command-method (gnus-find-method-for-group group)) 444 (let ((gnus-command-method (gnus-find-method-for-group group))
445 (func 'request-group-description)) 445 (func 'request-group-scan))
446 (when (gnus-check-backend-function func group) 446 (when (gnus-check-backend-function func group)
447 (funcall (gnus-get-function gnus-command-method func) 447 (funcall (gnus-get-function gnus-command-method func)
448 (gnus-group-real-name group) (nth 1 gnus-command-method) info)))) 448 (gnus-group-real-name group) (nth 1 gnus-command-method) info))))
diff --git a/lisp/gnus/gnus-start.el b/lisp/gnus/gnus-start.el
index aa2568d5559..0c0246a4e14 100644
--- a/lisp/gnus/gnus-start.el
+++ b/lisp/gnus/gnus-start.el
@@ -442,15 +442,6 @@ See also `gnus-before-startup-hook'."
442 :group 'gnus-newsrc 442 :group 'gnus-newsrc
443 :type 'hook) 443 :type 'hook)
444 444
445(defcustom gnus-save-newsrc-file-check-timestamp nil
446 "Check the modification time of the newsrc.eld file before saving it.
447When the newsrc.eld file is updated by multiple machines,
448checking the file's modification time is a good way to avoid
449overwriting updated data."
450 :version "25.1"
451 :group 'gnus-newsrc
452 :type 'boolean)
453
454(defcustom gnus-save-newsrc-hook nil 445(defcustom gnus-save-newsrc-hook nil
455 "A hook called before saving any of the newsrc files." 446 "A hook called before saving any of the newsrc files."
456 :group 'gnus-newsrc 447 :group 'gnus-newsrc
@@ -2833,19 +2824,18 @@ If FORCE is non-nil, the .newsrc file is read."
2833 2824
2834 ;; check timestamp of `gnus-current-startup-file'.eld against 2825 ;; check timestamp of `gnus-current-startup-file'.eld against
2835 ;; `gnus-save-newsrc-file-last-timestamp' 2826 ;; `gnus-save-newsrc-file-last-timestamp'
2836 (when gnus-save-newsrc-file-check-timestamp 2827 (let* ((checkfile (concat gnus-current-startup-file ".eld"))
2837 (let* ((checkfile (concat gnus-current-startup-file ".eld")) 2828 (mtime (nth 5 (file-attributes checkfile))))
2838 (mtime (nth 5 (file-attributes checkfile)))) 2829 (when (and gnus-save-newsrc-file-last-timestamp
2839 (when (and gnus-save-newsrc-file-last-timestamp 2830 (time-less-p gnus-save-newsrc-file-last-timestamp
2840 (time-less-p gnus-save-newsrc-file-last-timestamp 2831 mtime))
2841 mtime)) 2832 (unless (y-or-n-p
2842 (unless (y-or-n-p 2833 (format "%s was updated externally after %s, save?"
2843 (format "%s was updated externally after %s, save?" 2834 checkfile
2844 checkfile 2835 (format-time-string
2845 (format-time-string 2836 "%c"
2846 "%c" 2837 gnus-save-newsrc-file-last-timestamp)))
2847 gnus-save-newsrc-file-last-timestamp))) 2838 (error "Couldn't save %s: updated externally" checkfile))))
2848 (error "Couldn't save %s: updated externally" checkfile)))))
2849 2839
2850 (if gnus-save-startup-file-via-temp-buffer 2840 (if gnus-save-startup-file-via-temp-buffer
2851 (let ((coding-system-for-write gnus-ding-file-coding-system) 2841 (let ((coding-system-for-write gnus-ding-file-coding-system)
diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el
index efe7a4d3d65..66b1050acc4 100644
--- a/lisp/gnus/gnus-sum.el
+++ b/lisp/gnus/gnus-sum.el
@@ -1160,9 +1160,9 @@ which it may alter in any way."
1160 'mail-decode-encoded-address-string 1160 'mail-decode-encoded-address-string
1161 "Function used to decode addresses with encoded words.") 1161 "Function used to decode addresses with encoded words.")
1162 1162
1163(defcustom gnus-extra-headers '(To Cc Keywords Gcc Newsgroups) 1163(defcustom gnus-extra-headers '(To Cc Keywords Gcc Newsgroups X-GM-LABELS)
1164 "*Extra headers to parse." 1164 "*Extra headers to parse."
1165 :version "24.1" ; added Cc Keywords Gcc 1165 :version "25.1"
1166 :group 'gnus-summary 1166 :group 'gnus-summary
1167 :type '(repeat symbol)) 1167 :type '(repeat symbol))
1168 1168
@@ -5620,7 +5620,7 @@ If SELECT-ARTICLES, only select those articles from GROUP."
5620 (mm-decode-coding-string group charset) 5620 (mm-decode-coding-string group charset)
5621 (mm-decode-coding-string (gnus-status-message group) charset)))) 5621 (mm-decode-coding-string (gnus-status-message group) charset))))
5622 5622
5623 (unless (gnus-request-group group t) 5623 (unless (gnus-request-group group t nil (gnus-get-info group))
5624 (when (derived-mode-p 'gnus-summary-mode) 5624 (when (derived-mode-p 'gnus-summary-mode)
5625 (gnus-kill-buffer (current-buffer))) 5625 (gnus-kill-buffer (current-buffer)))
5626 (error "Couldn't request group %s: %s" 5626 (error "Couldn't request group %s: %s"
diff --git a/lisp/gnus/mail-source.el b/lisp/gnus/mail-source.el
index eb05d714aba..94c8950988d 100644
--- a/lisp/gnus/mail-source.el
+++ b/lisp/gnus/mail-source.el
@@ -750,13 +750,16 @@ Deleting old (> %s day(s)) incoming mail file `%s'." diff bfile)
750 (setq script (substring script 0 (match-beginning 0)) 750 (setq script (substring script 0 (match-beginning 0))
751 background 0)) 751 background 0))
752 (setq result 752 (setq result
753 (call-process shell-file-name nil background nil 753 (call-process shell-file-name nil stderr nil
754 shell-command-switch script)) 754 shell-command-switch script))
755 (when (and result 755 (if (and result
756 (not (zerop result))) 756 (not (zerop result)))
757 (set-buffer stderr) 757 (progn
758 (message "Mail source error: %s" (buffer-string))) 758 (split-window-vertically)
759 (kill-buffer stderr))) 759 (other-window 1)
760 (switch-to-buffer stderr)
761 (message "Mail source error: %s " (buffer-string)))
762 (kill-buffer stderr))))
760 763
761;;; 764;;;
762;;; Different fetchers 765;;; Different fetchers
diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el
index e619c0f13c2..e7f91b7cc33 100644
--- a/lisp/gnus/nnimap.el
+++ b/lisp/gnus/nnimap.el
@@ -820,39 +820,40 @@ textual parts.")
820 group)) 820 group))
821 t)))) 821 t))))
822 822
823(deffoo nnimap-request-scan-group (group &optional server info) 823(deffoo nnimap-request-group-scan (group &optional server info)
824 (setq group (nnimap-decode-gnus-group group)) 824 (setq group (nnimap-decode-gnus-group group))
825 (let (marks high low) 825 (when (nnimap-change-group nil server)
826 (with-current-buffer (nnimap-buffer) 826 (let (marks high low)
827 (erase-buffer) 827 (with-current-buffer (nnimap-buffer)
828 (let ((group-sequence 828 (erase-buffer)
829 (nnimap-send-command "SELECT %S" (utf7-encode group t))) 829 (let ((group-sequence
830 (flag-sequence 830 (nnimap-send-command "SELECT %S" (utf7-encode group t)))
831 (nnimap-send-command "UID FETCH 1:* FLAGS"))) 831 (flag-sequence
832 (setf (nnimap-group nnimap-object) group) 832 (nnimap-send-command "UID FETCH 1:* FLAGS")))
833 (nnimap-wait-for-response flag-sequence) 833 (setf (nnimap-group nnimap-object) group)
834 (setq marks 834 (nnimap-wait-for-response flag-sequence)
835 (nnimap-flags-to-marks 835 (setq marks
836 (nnimap-parse-flags 836 (nnimap-flags-to-marks
837 (list (list group-sequence flag-sequence 837 (nnimap-parse-flags
838 1 group "SELECT"))))) 838 (list (list group-sequence flag-sequence
839 (when (and info 839 1 group "SELECT")))))
840 marks) 840 (when (and info
841 (nnimap-update-infos marks (list info)) 841 marks)
842 (nnimap-store-info info (gnus-active (gnus-info-group info)))) 842 (nnimap-update-infos marks (list info))
843 (goto-char (point-max)) 843 (nnimap-store-info info (gnus-active (gnus-info-group info))))
844 (let ((uidnext (nth 5 (car marks)))) 844 (goto-char (point-max))
845 (setq high (or (if uidnext 845 (let ((uidnext (nth 5 (car marks))))
846 (1- uidnext) 846 (setq high (or (if uidnext
847 (nth 3 (car marks))) 847 (1- uidnext)
848 0) 848 (nth 3 (car marks)))
849 low (or (nth 4 (car marks)) uidnext 1))))) 849 0)
850 (with-current-buffer nntp-server-buffer 850 low (or (nth 4 (car marks)) uidnext 1)))))
851 (erase-buffer) 851 (with-current-buffer nntp-server-buffer
852 (insert 852 (erase-buffer)
853 (format 853 (insert
854 "211 %d %d %d %S\n" (1+ (- high low)) low high group)) 854 (format
855 t))) 855 "211 %d %d %d %S\n" (1+ (- high low)) low high group))
856 t))))
856 857
857(deffoo nnimap-request-create-group (group &optional server args) 858(deffoo nnimap-request-create-group (group &optional server args)
858 (setq group (nnimap-decode-gnus-group group)) 859 (setq group (nnimap-decode-gnus-group group))
diff --git a/lisp/help-fns.el b/lisp/help-fns.el
index c0d63935035..61e8d54acb3 100644
--- a/lisp/help-fns.el
+++ b/lisp/help-fns.el
@@ -930,6 +930,37 @@ file-local variable.\n")
930 930
931 931
932;;;###autoload 932;;;###autoload
933(defun describe-function-or-variable (symbol &optional buffer frame)
934 "Display the full documentation of the function or variable SYMBOL.
935If SYMBOL is a variable and has a buffer-local value in BUFFER or FRAME
936\(default to the current buffer and current frame), it is displayed along
937with the global value."
938 (interactive
939 (let* ((v-or-f (variable-at-point))
940 (found (symbolp v-or-f))
941 (v-or-f (if found v-or-f (function-called-at-point)))
942 (found (or found v-or-f))
943 (enable-recursive-minibuffers t)
944 val)
945 (setq val (completing-read (if found
946 (format
947 "Describe function or variable (default %s): " v-or-f)
948 "Describe function or variable: ")
949 obarray
950 (lambda (vv)
951 (or (fboundp vv)
952 (get vv 'variable-documentation)
953 (and (boundp vv) (not (keywordp vv)))))
954 t nil nil
955 (if found (symbol-name v-or-f))))
956 (list (if (equal val "")
957 v-or-f (intern val)))))
958 (if (not (symbolp symbol)) (message "You didn't specify a function or variable")
959 (unless (buffer-live-p buffer) (setq buffer (current-buffer)))
960 (unless (frame-live-p frame) (setq frame (selected-frame)))
961 (help-xref-interned symbol buffer frame)))
962
963;;;###autoload
933(defun describe-syntax (&optional buffer) 964(defun describe-syntax (&optional buffer)
934 "Describe the syntax specifications in the syntax table of BUFFER. 965 "Describe the syntax specifications in the syntax table of BUFFER.
935The descriptions are inserted in a help buffer, which is then displayed. 966The descriptions are inserted in a help buffer, which is then displayed.
diff --git a/lisp/help-mode.el b/lisp/help-mode.el
index c62ddc3dcd0..564362a0c43 100644
--- a/lisp/help-mode.el
+++ b/lisp/help-mode.el
@@ -621,10 +621,13 @@ See `help-make-xrefs'."
621 621
622 622
623;; Additional functions for (re-)creating types of help buffers. 623;; Additional functions for (re-)creating types of help buffers.
624(defun help-xref-interned (symbol) 624
625;;;###autoload
626(defun help-xref-interned (symbol &optional buffer frame)
625 "Follow a hyperlink which appeared to be an arbitrary interned SYMBOL. 627 "Follow a hyperlink which appeared to be an arbitrary interned SYMBOL.
626Both variable, function and face documentation are extracted into a single 628Both variable, function and face documentation are extracted into a single
627help buffer." 629help buffer. If SYMBOL is a variable, include buffer-local value for optional
630BUFFER or FRAME."
628 (with-current-buffer (help-buffer) 631 (with-current-buffer (help-buffer)
629 ;; Push the previous item on the stack before clobbering the output buffer. 632 ;; Push the previous item on the stack before clobbering the output buffer.
630 (help-setup-xref nil nil) 633 (help-setup-xref nil nil)
@@ -640,7 +643,7 @@ help buffer."
640 (get symbol 'variable-documentation)) 643 (get symbol 'variable-documentation))
641 ;; Don't record the current entry in the stack. 644 ;; Don't record the current entry in the stack.
642 (setq help-xref-stack-item nil) 645 (setq help-xref-stack-item nil)
643 (describe-variable symbol)))) 646 (describe-variable symbol buffer frame))))
644 (cond 647 (cond
645 (sdoc 648 (sdoc
646 ;; We now have a help buffer on the variable. 649 ;; We now have a help buffer on the variable.
diff --git a/lisp/help.el b/lisp/help.el
index bf724252d5a..fb1719ac9c9 100644
--- a/lisp/help.el
+++ b/lisp/help.el
@@ -95,6 +95,7 @@
95 (define-key map "k" 'describe-key) 95 (define-key map "k" 'describe-key)
96 (define-key map "l" 'view-lossage) 96 (define-key map "l" 'view-lossage)
97 (define-key map "m" 'describe-mode) 97 (define-key map "m" 'describe-mode)
98 (define-key map "o" 'describe-function-or-variable)
98 (define-key map "n" 'view-emacs-news) 99 (define-key map "n" 'view-emacs-news)
99 (define-key map "p" 'finder-by-keyword) 100 (define-key map "p" 'finder-by-keyword)
100 (define-key map "P" 'describe-package) 101 (define-key map "P" 'describe-package)
@@ -218,6 +219,7 @@ L LANG-ENV Describes a specific language environment, or RET for current.
218m Display documentation of current minor modes and current major mode, 219m Display documentation of current minor modes and current major mode,
219 including their special commands. 220 including their special commands.
220n Display news of recent Emacs changes. 221n Display news of recent Emacs changes.
222o SYMBOL Display the given function or variable's documentation and value.
221p TOPIC Find packages matching a given topic keyword. 223p TOPIC Find packages matching a given topic keyword.
222P PACKAGE Describe the given Emacs Lisp package. 224P PACKAGE Describe the given Emacs Lisp package.
223r Display the Emacs manual in Info mode. 225r Display the Emacs manual in Info mode.
diff --git a/lisp/image-mode.el b/lisp/image-mode.el
index 9e527f1f0b3..e6d6a3edb71 100644
--- a/lisp/image-mode.el
+++ b/lisp/image-mode.el
@@ -380,6 +380,7 @@ call."
380 (define-key map "a-" 'image-decrease-speed) 380 (define-key map "a-" 'image-decrease-speed)
381 (define-key map "a0" 'image-reset-speed) 381 (define-key map "a0" 'image-reset-speed)
382 (define-key map "ar" 'image-reverse-speed) 382 (define-key map "ar" 'image-reverse-speed)
383 (define-key map "k" 'image-kill-buffer)
383 (define-key map [remap forward-char] 'image-forward-hscroll) 384 (define-key map [remap forward-char] 'image-forward-hscroll)
384 (define-key map [remap backward-char] 'image-backward-hscroll) 385 (define-key map [remap backward-char] 'image-backward-hscroll)
385 (define-key map [remap right-char] 'image-forward-hscroll) 386 (define-key map [remap right-char] 'image-forward-hscroll)
@@ -722,6 +723,11 @@ the image by calling `image-mode'."
722 (image-mode-as-text) 723 (image-mode-as-text)
723 (image-mode))) 724 (image-mode)))
724 725
726(defun image-kill-buffer ()
727 "Kill the current buffer."
728 (interactive)
729 (kill-buffer (current-buffer)))
730
725(defun image-after-revert-hook () 731(defun image-after-revert-hook ()
726 (when (image-get-display-property) 732 (when (image-get-display-property)
727 (image-toggle-display-text) 733 (image-toggle-display-text)
diff --git a/lisp/json.el b/lisp/json.el
index 68ab020c379..98974e67b7e 100644
--- a/lisp/json.el
+++ b/lisp/json.el
@@ -166,7 +166,7 @@ without indentation.")
166 "Advance past the character at point, returning it." 166 "Advance past the character at point, returning it."
167 (let ((char (json-peek))) 167 (let ((char (json-peek)))
168 (if (eq char :json-eof) 168 (if (eq char :json-eof)
169 (signal 'end-of-file nil) 169 (signal 'json-end-of-file nil)
170 (json-advance) 170 (json-advance)
171 char))) 171 char)))
172 172
@@ -186,6 +186,8 @@ without indentation.")
186(define-error 'json-string-format "Bad string format" 'json-error) 186(define-error 'json-string-format "Bad string format" 'json-error)
187(define-error 'json-key-format "Bad JSON object key" 'json-error) 187(define-error 'json-key-format "Bad JSON object key" 'json-error)
188(define-error 'json-object-format "Bad JSON object" 'json-error) 188(define-error 'json-object-format "Bad JSON object" 'json-error)
189(define-error 'json-end-of-file "End of file while parsing JSON"
190 '(end-of-file json-error))
189 191
190 192
191 193
@@ -554,7 +556,7 @@ Advances point just past JSON object."
554 (if (functionp (car record)) 556 (if (functionp (car record))
555 (apply (car record) (cdr record)) 557 (apply (car record) (cdr record))
556 (signal 'json-readtable-error record))) 558 (signal 'json-readtable-error record)))
557 (signal 'end-of-file nil)))) 559 (signal 'json-end-of-file nil))))
558 560
559;; Syntactic sugar for the reader 561;; Syntactic sugar for the reader
560 562
diff --git a/lisp/net/ldap.el b/lisp/net/ldap.el
index a77fc3c6514..1df975af3d9 100644
--- a/lisp/net/ldap.el
+++ b/lisp/net/ldap.el
@@ -546,8 +546,8 @@ not their associated values.
546 `auth' is one of the symbols `simple', `krbv41' or `krbv42'. 546 `auth' is one of the symbols `simple', `krbv41' or `krbv42'.
547 `base' is the base for the search as described in RFC 1779. 547 `base' is the base for the search as described in RFC 1779.
548 `scope' is one of the three symbols `sub', `base' or `one'. 548 `scope' is one of the three symbols `sub', `base' or `one'.
549 `binddn' is the distinguished name of the user to bind as (in RFC 1779 syntax). 549 `binddn' is the distinguished name of the user to bind as (in
550 `auth' is one of the symbols `simple', `krbv41' or `krbv42' 550RFC 1779 syntax).
551 `passwd' is the password to use for simple authentication. 551 `passwd' is the password to use for simple authentication.
552 `deref' is one of the symbols `never', `always', `search' or `find'. 552 `deref' is one of the symbols `never', `always', `search' or `find'.
553 `timelimit' is the timeout limit for the connection in seconds. 553 `timelimit' is the timeout limit for the connection in seconds.
diff --git a/lisp/net/network-stream.el b/lisp/net/network-stream.el
index e7b3150b792..0104fa7dd12 100644
--- a/lisp/net/network-stream.el
+++ b/lisp/net/network-stream.el
@@ -374,10 +374,12 @@ asynchronously, if possible."
374 (when (re-search-forward eoc nil t) 374 (when (re-search-forward eoc nil t)
375 (goto-char (match-beginning 0)) 375 (goto-char (match-beginning 0))
376 (delete-region (point-min) (line-beginning-position)))) 376 (delete-region (point-min) (line-beginning-position))))
377 (let* ((capability-command (plist-get parameters :capability-command))) 377 (let ((capability-command (plist-get parameters :capability-command))
378 (eo-capa (or (plist-get parameters :end-of-capability)
379 eoc)))
378 (list stream 380 (list stream
379 (network-stream-get-response stream start eoc) 381 (network-stream-get-response stream start eoc)
380 (network-stream-command stream capability-command eoc) 382 (network-stream-command stream capability-command eo-capa)
381 'tls)))))) 383 'tls))))))
382 384
383(defun network-stream-open-shell (name buffer host service parameters) 385(defun network-stream-open-shell (name buffer host service parameters)
diff --git a/lisp/newcomment.el b/lisp/newcomment.el
index e307eac94eb..172a5634a57 100644
--- a/lisp/newcomment.el
+++ b/lisp/newcomment.el
@@ -1451,6 +1451,38 @@ unless optional argument SOFT is non-nil."
1451 (end-of-line 0) 1451 (end-of-line 0)
1452 (insert comend)))))))))))) 1452 (insert comend))))))))))))
1453 1453
1454;;;###autoload
1455(defun comment-line (n)
1456 "Comment or uncomment current line and leave point after it.
1457With positive prefix, apply to N lines including current one.
1458With negative prefix, apply to -N lines above. Also, further
1459consecutive invocations of this command will inherit the negative
1460argument.
1461
1462If region is active, comment lines in active region instead.
1463Unlike `comment-dwim', this always comments whole lines."
1464 (interactive "p")
1465 (if (use-region-p)
1466 (comment-or-uncomment-region
1467 (save-excursion
1468 (goto-char (region-beginning))
1469 (line-beginning-position))
1470 (save-excursion
1471 (goto-char (region-end))
1472 (line-end-position)))
1473 (when (and (eq last-command 'comment-line-backward)
1474 (natnump n))
1475 (setq n (- n)))
1476 (let ((range
1477 (list (line-beginning-position)
1478 (goto-char (line-end-position n)))))
1479 (comment-or-uncomment-region
1480 (apply #'min range)
1481 (apply #'max range)))
1482 (forward-line 1)
1483 (back-to-indentation)
1484 (unless (natnump n) (setq this-command 'comment-line-backward))))
1485
1454(provide 'newcomment) 1486(provide 'newcomment)
1455 1487
1456;;; newcomment.el ends here 1488;;; newcomment.el ends here
diff --git a/lisp/outline.el b/lisp/outline.el
index ae31b8088f0..059ca626586 100644
--- a/lisp/outline.el
+++ b/lisp/outline.el
@@ -777,7 +777,12 @@ Show the heading too, if it is currently invisible."
777 (save-excursion 777 (save-excursion
778 (outline-back-to-heading t) 778 (outline-back-to-heading t)
779 (outline-flag-region (1- (point)) 779 (outline-flag-region (1- (point))
780 (progn (outline-next-preface) (point)) nil))) 780 (progn
781 (outline-next-preface)
782 (if (= 1 (- (point-max) (point)))
783 (point-max)
784 (point)))
785 nil)))
781 786
782(define-obsolete-function-alias 787(define-obsolete-function-alias
783 'show-entry 'outline-show-entry "25.1") 788 'show-entry 'outline-show-entry "25.1")
diff --git a/lisp/play/gamegrid.el b/lisp/play/gamegrid.el
index b4c3c594731..df06d5a6ab2 100644
--- a/lisp/play/gamegrid.el
+++ b/lisp/play/gamegrid.el
@@ -462,22 +462,22 @@ FILE is created there."
462;; `gamegrid-add-score' was supposed to be used in the past and 462;; `gamegrid-add-score' was supposed to be used in the past and
463;; is covered here for backward-compatibility. 463;; is covered here for backward-compatibility.
464;; 464;;
465;; 2. The helper program "update-game-score" is setuid and the 465;; 2. The helper program "update-game-score" is setgid or setuid
466;; file FILE does already exist in a system wide shared game 466;; and the file FILE does already exist in a system wide shared
467;; directory. This should be the normal case on POSIX systems, 467;; game directory. This should be the normal case on POSIX
468;; if the game was installed system wide. Use 468;; systems, if the game was installed system wide. Use
469;; "update-game-score" to add the score to the file in the 469;; "update-game-score" to add the score to the file in the
470;; shared game directory. 470;; shared game directory.
471;; 471;;
472;; 3. "update-game-score" is setuid, but the file FILE does *not* 472;; 3. "update-game-score" is setgid/setuid, but the file FILE does
473;; exist in the system wide shared game directory. Use 473;; *not* exist in the system wide shared game directory. Use
474;; `gamegrid-add-score-insecure' to create--if necessary--and 474;; `gamegrid-add-score-insecure' to create--if necessary--and
475;; update FILE. This is for the case that a user has installed 475;; update FILE. This is for the case that a user has installed
476;; a game on her own. 476;; a game on her own.
477;; 477;;
478;; 4. "update-game-score" is not setuid. Use it to create/update 478;; 4. "update-game-score" is not setgid/setuid. Use it to
479;; FILE in the user's home directory. There is presumably no 479;; create/update FILE in the user's home directory. There is
480;; shared game directory. 480;; presumably no shared game directory.
481 481
482(defvar gamegrid-shared-game-dir) 482(defvar gamegrid-shared-game-dir)
483 483
@@ -491,7 +491,7 @@ FILE is created there."
491 (gamegrid-add-score-insecure file score)) 491 (gamegrid-add-score-insecure file score))
492 ((and gamegrid-shared-game-dir 492 ((and gamegrid-shared-game-dir
493 (file-exists-p (expand-file-name file shared-game-score-directory))) 493 (file-exists-p (expand-file-name file shared-game-score-directory)))
494 ;; Use the setuid (or setgid) "update-game-score" program 494 ;; Use the setgid (or setuid) "update-game-score" program
495 ;; to update a system-wide score file. 495 ;; to update a system-wide score file.
496 (gamegrid-add-score-with-update-game-score-1 file 496 (gamegrid-add-score-with-update-game-score-1 file
497 (expand-file-name file shared-game-score-directory) score)) 497 (expand-file-name file shared-game-score-directory) score))
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index d340550a017..303c36c3932 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -1068,7 +1068,9 @@ minimum."
1068 (levels (python-indent--calculate-levels indentation))) 1068 (levels (python-indent--calculate-levels indentation)))
1069 (if previous 1069 (if previous
1070 (python-indent--previous-level levels (current-indentation)) 1070 (python-indent--previous-level levels (current-indentation))
1071 (apply #'max levels)))) 1071 (if levels
1072 (apply #'max levels)
1073 0))))
1072 1074
1073(defun python-indent-line (&optional previous) 1075(defun python-indent-line (&optional previous)
1074 "Internal implementation of `python-indent-line-function'. 1076 "Internal implementation of `python-indent-line-function'.
@@ -2331,57 +2333,57 @@ goes wrong and syntax highlighting in the shell gets messed up."
2331 (interactive) 2333 (interactive)
2332 (python-shell-with-shell-buffer 2334 (python-shell-with-shell-buffer
2333 (python-shell-font-lock-with-font-lock-buffer 2335 (python-shell-font-lock-with-font-lock-buffer
2334 (delete-region (point-min) (point-max))))) 2336 (erase-buffer))))
2335 2337
2336(defun python-shell-font-lock-comint-output-filter-function (output) 2338(defun python-shell-font-lock-comint-output-filter-function (output)
2337 "Clean up the font-lock buffer after any OUTPUT." 2339 "Clean up the font-lock buffer after any OUTPUT."
2338 (when (and (not (string= "" output)) 2340 (if (and (not (string= "" output))
2339 ;; Is end of output and is not just a prompt. 2341 ;; Is end of output and is not just a prompt.
2340 (not (member 2342 (not (member
2341 (python-shell-comint-end-of-output-p 2343 (python-shell-comint-end-of-output-p
2342 (ansi-color-filter-apply output)) 2344 (ansi-color-filter-apply output))
2343 '(nil 0)))) 2345 '(nil 0))))
2344 ;; If output is other than an input prompt then "real" output has 2346 ;; If output is other than an input prompt then "real" output has
2345 ;; been received and the font-lock buffer must be cleaned up. 2347 ;; been received and the font-lock buffer must be cleaned up.
2346 (python-shell-font-lock-cleanup-buffer)) 2348 (python-shell-font-lock-cleanup-buffer)
2349 ;; Otherwise just add a newline.
2350 (python-shell-font-lock-with-font-lock-buffer
2351 (goto-char (point-max))
2352 (newline)))
2347 output) 2353 output)
2348 2354
2349(defun python-shell-font-lock-post-command-hook () 2355(defun python-shell-font-lock-post-command-hook ()
2350 "Fontifies current line in shell buffer." 2356 "Fontifies current line in shell buffer."
2351 (if (eq this-command 'comint-send-input) 2357 (when (and (python-util-comint-last-prompt)
2352 ;; Add a newline when user sends input as this may be a block. 2358 (> (point) (cdr (python-util-comint-last-prompt))))
2353 (python-shell-font-lock-with-font-lock-buffer 2359 (let ((input (buffer-substring-no-properties
2354 (goto-char (line-end-position)) 2360 (cdr (python-util-comint-last-prompt)) (point-max)))
2355 (newline)) 2361 (pos (point))
2356 (when (and (python-util-comint-last-prompt) 2362 (buffer-undo-list t)
2357 (> (point) (cdr (python-util-comint-last-prompt)))) 2363 (font-lock-buffer-pos nil))
2358 (let ((input (buffer-substring-no-properties 2364 ;; Keep all markers untouched, this prevents `hippie-expand' and
2359 (cdr (python-util-comint-last-prompt)) (point-max))) 2365 ;; others from getting confused. Bug#19650.
2360 (old-input (python-shell-font-lock-with-font-lock-buffer 2366 (insert-before-markers
2361 (buffer-substring-no-properties 2367 (python-shell-font-lock-with-font-lock-buffer
2362 (line-beginning-position) (point-max)))) 2368 (delete-region (line-beginning-position)
2363 (current-point (point)) 2369 (point-max))
2364 (buffer-undo-list t)) 2370 (setq font-lock-buffer-pos (point))
2365 ;; When input hasn't changed, do nothing. 2371 (insert input)
2366 (when (not (string= input old-input)) 2372 ;; Ensure buffer is fontified, keeping it
2367 (delete-region (cdr (python-util-comint-last-prompt)) (point-max)) 2373 ;; compatible with Emacs < 24.4.
2368 (insert 2374 (if (fboundp 'font-lock-ensure)
2369 (python-shell-font-lock-with-font-lock-buffer 2375 (funcall 'font-lock-ensure)
2370 (delete-region (line-beginning-position) 2376 (font-lock-default-fontify-buffer))
2371 (line-end-position)) 2377 ;; Replace FACE text properties with FONT-LOCK-FACE so
2372 (insert input) 2378 ;; they are not overwritten by comint buffer's font lock.
2373 ;; Ensure buffer is fontified, keeping it 2379 (python-util-text-properties-replace-name
2374 ;; compatible with Emacs < 24.4. 2380 'face 'font-lock-face)
2375 (if (fboundp 'font-lock-ensure) 2381 (buffer-substring font-lock-buffer-pos
2376 (funcall 'font-lock-ensure) 2382 (point-max))))
2377 (font-lock-default-fontify-buffer)) 2383 ;; Remove non-fontified original text.
2378 ;; Replace FACE text properties with FONT-LOCK-FACE so 2384 (delete-region pos (cdr (python-util-comint-last-prompt)))
2379 ;; they are not overwritten by comint buffer's font lock. 2385 ;; Point should be already at pos, this is for extra safety.
2380 (python-util-text-properties-replace-name 2386 (goto-char pos))))
2381 'face 'font-lock-face)
2382 (buffer-substring (line-beginning-position)
2383 (line-end-position))))
2384 (goto-char current-point))))))
2385 2387
2386(defun python-shell-font-lock-turn-on (&optional msg) 2388(defun python-shell-font-lock-turn-on (&optional msg)
2387 "Turn on shell font-lock. 2389 "Turn on shell font-lock.
@@ -3148,67 +3150,68 @@ With argument MSG show activation/deactivation message."
3148 "Get completions using native readline for PROCESS. 3150 "Get completions using native readline for PROCESS.
3149When IMPORT is non-nil takes precedence over INPUT for 3151When IMPORT is non-nil takes precedence over INPUT for
3150completion." 3152completion."
3151 (when (and python-shell-completion-native-enable 3153 (with-current-buffer (process-buffer process)
3152 (python-util-comint-last-prompt) 3154 (when (and python-shell-completion-native-enable
3153 (>= (point) (cdr (python-util-comint-last-prompt)))) 3155 (python-util-comint-last-prompt)
3154 (let* ((input (or import input)) 3156 (>= (point) (cdr (python-util-comint-last-prompt))))
3155 (original-filter-fn (process-filter process)) 3157 (let* ((input (or import input))
3156 (redirect-buffer (get-buffer-create 3158 (original-filter-fn (process-filter process))
3157 python-shell-completion-native-redirect-buffer)) 3159 (redirect-buffer (get-buffer-create
3158 (separators (python-rx 3160 python-shell-completion-native-redirect-buffer))
3159 (or whitespace open-paren close-paren))) 3161 (separators (python-rx
3160 (trigger "\t\t\t") 3162 (or whitespace open-paren close-paren)))
3161 (new-input (concat input trigger)) 3163 (trigger "\t\t\t")
3162 (input-length 3164 (new-input (concat input trigger))
3163 (save-excursion 3165 (input-length
3164 (+ (- (point-max) (comint-bol)) (length new-input)))) 3166 (save-excursion
3165 (delete-line-command (make-string input-length ?\b)) 3167 (+ (- (point-max) (comint-bol)) (length new-input))))
3166 (input-to-send (concat new-input delete-line-command))) 3168 (delete-line-command (make-string input-length ?\b))
3167 ;; Ensure restoring the process filter, even if the user quits 3169 (input-to-send (concat new-input delete-line-command)))
3168 ;; or there's some other error. 3170 ;; Ensure restoring the process filter, even if the user quits
3169 (unwind-protect 3171 ;; or there's some other error.
3170 (with-current-buffer redirect-buffer 3172 (unwind-protect
3171 ;; Cleanup the redirect buffer 3173 (with-current-buffer redirect-buffer
3172 (delete-region (point-min) (point-max)) 3174 ;; Cleanup the redirect buffer
3173 ;; Mimic `comint-redirect-send-command', unfortunately it 3175 (delete-region (point-min) (point-max))
3174 ;; can't be used here because it expects a newline in the 3176 ;; Mimic `comint-redirect-send-command', unfortunately it
3175 ;; command and that's exactly what we are trying to avoid. 3177 ;; can't be used here because it expects a newline in the
3176 (let ((comint-redirect-echo-input nil) 3178 ;; command and that's exactly what we are trying to avoid.
3177 (comint-redirect-verbose nil) 3179 (let ((comint-redirect-echo-input nil)
3178 (comint-redirect-perform-sanity-check nil) 3180 (comint-redirect-verbose nil)
3179 (comint-redirect-insert-matching-regexp nil) 3181 (comint-redirect-perform-sanity-check nil)
3180 ;; Feed it some regex that will never match. 3182 (comint-redirect-insert-matching-regexp nil)
3181 (comint-redirect-finished-regexp "^\\'$") 3183 ;; Feed it some regex that will never match.
3182 (comint-redirect-output-buffer redirect-buffer)) 3184 (comint-redirect-finished-regexp "^\\'$")
3183 ;; Compatibility with Emacs 24.x. Comint changed and 3185 (comint-redirect-output-buffer redirect-buffer))
3184 ;; now `comint-redirect-filter' gets 3 args. This 3186 ;; Compatibility with Emacs 24.x. Comint changed and
3185 ;; checks which version of `comint-redirect-filter' is 3187 ;; now `comint-redirect-filter' gets 3 args. This
3186 ;; in use based on its args and uses `apply-partially' 3188 ;; checks which version of `comint-redirect-filter' is
3187 ;; to make it up for the 3 args case. 3189 ;; in use based on its args and uses `apply-partially'
3188 (if (= (length 3190 ;; to make it up for the 3 args case.
3189 (help-function-arglist 'comint-redirect-filter)) 3) 3191 (if (= (length
3190 (set-process-filter 3192 (help-function-arglist 'comint-redirect-filter)) 3)
3191 process (apply-partially 3193 (set-process-filter
3192 #'comint-redirect-filter original-filter-fn)) 3194 process (apply-partially
3193 (set-process-filter process #'comint-redirect-filter)) 3195 #'comint-redirect-filter original-filter-fn))
3194 (process-send-string process input-to-send) 3196 (set-process-filter process #'comint-redirect-filter))
3195 (accept-process-output 3197 (process-send-string process input-to-send)
3196 process 3198 (accept-process-output
3197 python-shell-completion-native-output-timeout) 3199 process
3198 ;; XXX: can't use `python-shell-accept-process-output' 3200 python-shell-completion-native-output-timeout)
3199 ;; here because there are no guarantees on how output 3201 ;; XXX: can't use `python-shell-accept-process-output'
3200 ;; ends. The workaround here is to call 3202 ;; here because there are no guarantees on how output
3201 ;; `accept-process-output' until we don't find anything 3203 ;; ends. The workaround here is to call
3202 ;; else to accept. 3204 ;; `accept-process-output' until we don't find anything
3203 (while (accept-process-output 3205 ;; else to accept.
3204 process 3206 (while (accept-process-output
3205 python-shell-completion-native-output-timeout)) 3207 process
3206 (cl-remove-duplicates 3208 python-shell-completion-native-output-timeout))
3207 (split-string 3209 (cl-remove-duplicates
3208 (buffer-substring-no-properties 3210 (split-string
3209 (point-min) (point-max)) 3211 (buffer-substring-no-properties
3210 separators t)))) 3212 (point-min) (point-max))
3211 (set-process-filter process original-filter-fn))))) 3213 separators t))))
3214 (set-process-filter process original-filter-fn))))))
3212 3215
3213(defun python-shell-completion-get-completions (process import input) 3216(defun python-shell-completion-get-completions (process import input)
3214 "Do completion at point using PROCESS for IMPORT or INPUT. 3217 "Do completion at point using PROCESS for IMPORT or INPUT.
@@ -3251,20 +3254,23 @@ completion."
3251Optional argument PROCESS forces completions to be retrieved 3254Optional argument PROCESS forces completions to be retrieved
3252using that one instead of current buffer's process." 3255using that one instead of current buffer's process."
3253 (setq process (or process (get-buffer-process (current-buffer)))) 3256 (setq process (or process (get-buffer-process (current-buffer))))
3254 (let* ((last-prompt-end (cdr (python-util-comint-last-prompt))) 3257 (let* ((line-start (if (derived-mode-p 'inferior-python-mode)
3258 ;; Working on a shell buffer: use prompt end.
3259 (cdr (python-util-comint-last-prompt))
3260 (line-beginning-position)))
3255 (import-statement 3261 (import-statement
3256 (when (string-match-p 3262 (when (string-match-p
3257 (rx (* space) word-start (or "from" "import") word-end space) 3263 (rx (* space) word-start (or "from" "import") word-end space)
3258 (buffer-substring-no-properties last-prompt-end (point))) 3264 (buffer-substring-no-properties line-start (point)))
3259 (buffer-substring-no-properties last-prompt-end (point)))) 3265 (buffer-substring-no-properties line-start (point))))
3260 (start 3266 (start
3261 (save-excursion 3267 (save-excursion
3262 (if (not (re-search-backward 3268 (if (not (re-search-backward
3263 (python-rx 3269 (python-rx
3264 (or whitespace open-paren close-paren string-delimiter)) 3270 (or whitespace open-paren close-paren string-delimiter))
3265 last-prompt-end 3271 line-start
3266 t 1)) 3272 t 1))
3267 last-prompt-end 3273 line-start
3268 (forward-char (length (match-string-no-properties 0))) 3274 (forward-char (length (match-string-no-properties 0)))
3269 (point)))) 3275 (point))))
3270 (end (point)) 3276 (end (point))
@@ -3847,8 +3853,10 @@ The skeleton will be bound to python-skeleton-NAME."
3847 :type 'string 3853 :type 'string
3848 :group 'python) 3854 :group 'python)
3849 3855
3850(defvar-local python-check-custom-command nil 3856(defvar python-check-custom-command nil
3851 "Internal use.") 3857 "Internal use.")
3858;; XXX: Avoid `defvar-local' for compat with Emacs<24.3
3859(make-variable-buffer-local 'python-check-custom-command)
3852 3860
3853(defun python-check (command) 3861(defun python-check (command)
3854 "Check a Python file (default current buffer's file). 3862 "Check a Python file (default current buffer's file).
@@ -3917,15 +3925,29 @@ See `python-check-command' for the default."
3917 :type 'string 3925 :type 'string
3918 :group 'python) 3926 :group 'python)
3919 3927
3928(defun python-eldoc--get-symbol-at-point ()
3929 "Get the current symbol for eldoc.
3930Returns the current symbol handling point within arguments."
3931 (save-excursion
3932 (let ((start (python-syntax-context 'paren)))
3933 (when start
3934 (goto-char start))
3935 (when (or start
3936 (eobp)
3937 (memq (char-syntax (char-after)) '(?\ ?-)))
3938 ;; Try to adjust to closest symbol if not in one.
3939 (python-util-forward-comment -1)))
3940 (python-info-current-symbol t)))
3941
3920(defun python-eldoc--get-doc-at-point (&optional force-input force-process) 3942(defun python-eldoc--get-doc-at-point (&optional force-input force-process)
3921 "Internal implementation to get documentation at point. 3943 "Internal implementation to get documentation at point.
3922If not FORCE-INPUT is passed then what `python-info-current-symbol' 3944If not FORCE-INPUT is passed then what `python-eldoc--get-symbol-at-point'
3923returns will be used. If not FORCE-PROCESS is passed what 3945returns will be used. If not FORCE-PROCESS is passed what
3924`python-shell-get-process' returns is used." 3946`python-shell-get-process' returns is used."
3925 (let ((process (or force-process (python-shell-get-process)))) 3947 (let ((process (or force-process (python-shell-get-process))))
3926 (when process 3948 (when process
3927 (let ((input (or force-input 3949 (let ((input (or force-input
3928 (python-info-current-symbol t)))) 3950 (python-eldoc--get-symbol-at-point))))
3929 (and input 3951 (and input
3930 ;; Prevent resizing the echo area when iPython is 3952 ;; Prevent resizing the echo area when iPython is
3931 ;; enabled. Bug#18794. 3953 ;; enabled. Bug#18794.
@@ -3945,7 +3967,7 @@ inferior Python process is updated properly."
3945 "Get help on SYMBOL using `help'. 3967 "Get help on SYMBOL using `help'.
3946Interactively, prompt for symbol." 3968Interactively, prompt for symbol."
3947 (interactive 3969 (interactive
3948 (let ((symbol (python-info-current-symbol t)) 3970 (let ((symbol (python-eldoc--get-symbol-at-point))
3949 (enable-recursive-minibuffers t)) 3971 (enable-recursive-minibuffers t))
3950 (list (read-string (if symbol 3972 (list (read-string (if symbol
3951 (format "Describe symbol (default %s): " symbol) 3973 (format "Describe symbol (default %s): " symbol)
@@ -3954,6 +3976,17 @@ Interactively, prompt for symbol."
3954 (message (python-eldoc--get-doc-at-point symbol))) 3976 (message (python-eldoc--get-doc-at-point symbol)))
3955 3977
3956 3978
3979;;; Hideshow
3980
3981(defun python-hideshow-forward-sexp-function (arg)
3982 "Python specific `forward-sexp' function for `hs-minor-mode'.
3983Argument ARG is ignored."
3984 arg ; Shut up, byte compiler.
3985 (python-nav-end-of-defun)
3986 (unless (python-info-current-line-empty-p)
3987 (backward-char)))
3988
3989
3957;;; Imenu 3990;;; Imenu
3958 3991
3959(defvar python-imenu-format-item-label-function 3992(defvar python-imenu-format-item-label-function
@@ -4682,14 +4715,23 @@ Arguments START and END narrow the buffer region to work on."
4682 (current-column)))) 4715 (current-column))))
4683 (^ '(- (1+ (current-indentation)))))) 4716 (^ '(- (1+ (current-indentation))))))
4684 4717
4685 (add-function :before-until (local 'eldoc-documentation-function) 4718 (if (null eldoc-documentation-function)
4686 #'python-eldoc-function) 4719 ;; Emacs<25
4687 4720 (setq (make-local-variable 'eldoc-documentation-function)
4688 (add-to-list 'hs-special-modes-alist 4721 #'python-eldoc-function)
4689 `(python-mode "^\\s-*\\(?:def\\|class\\)\\>" nil "#" 4722 (add-function :before-until (local 'eldoc-documentation-function)
4690 ,(lambda (_arg) 4723 #'python-eldoc-function))
4691 (python-nav-end-of-defun)) 4724
4692 nil)) 4725 (add-to-list
4726 'hs-special-modes-alist
4727 `(python-mode
4728 "\\s-*\\(?:def\\|class\\)\\>"
4729 ;; Use the empty string as end regexp so it doesn't default to
4730 ;; "\\s)". This way parens at end of defun are properly hidden.
4731 ""
4732 "#"
4733 python-hideshow-forward-sexp-function
4734 nil))
4693 4735
4694 (set (make-local-variable 'outline-regexp) 4736 (set (make-local-variable 'outline-regexp)
4695 (python-rx (* space) block-start)) 4737 (python-rx (* space) block-start))
diff --git a/lisp/subr.el b/lisp/subr.el
index 68cd230c5e2..deadca6efa0 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -136,8 +136,8 @@ ARGS is a list of the first N arguments to pass to FUN.
136The result is a new function which does the same as FUN, except that 136The result is a new function which does the same as FUN, except that
137the first N arguments are fixed at the values with which this function 137the first N arguments are fixed at the values with which this function
138was called." 138was called."
139 `(closure (t) (&rest args) 139 (lambda (&rest args2)
140 (apply ',fun ,@(mapcar (lambda (arg) `',arg) args) args))) 140 (apply fun (append args args2))))
141 141
142(defmacro push (newelt place) 142(defmacro push (newelt place)
143 "Add NEWELT to the list stored in the generalized variable PLACE. 143 "Add NEWELT to the list stored in the generalized variable PLACE.
@@ -316,7 +316,7 @@ Defaults to `error'."
316 (unless parent (setq parent 'error)) 316 (unless parent (setq parent 'error))
317 (let ((conditions 317 (let ((conditions
318 (if (consp parent) 318 (if (consp parent)
319 (apply #'nconc 319 (apply #'append
320 (mapcar (lambda (parent) 320 (mapcar (lambda (parent)
321 (cons parent 321 (cons parent
322 (or (get parent 'error-conditions) 322 (or (get parent 'error-conditions)
@@ -1274,6 +1274,7 @@ is converted into a string by expressing it in decimal."
1274(set-advertised-calling-convention 1274(set-advertised-calling-convention
1275 'all-completions '(string collection &optional predicate) "23.1") 1275 'all-completions '(string collection &optional predicate) "23.1")
1276(set-advertised-calling-convention 'unintern '(name obarray) "23.3") 1276(set-advertised-calling-convention 'unintern '(name obarray) "23.3")
1277(set-advertised-calling-convention 'indirect-function '(object) "25.1")
1277(set-advertised-calling-convention 'redirect-frame-focus '(frame focus-frame) "24.3") 1278(set-advertised-calling-convention 'redirect-frame-focus '(frame focus-frame) "24.3")
1278(set-advertised-calling-convention 'decode-char '(ch charset) "21.4") 1279(set-advertised-calling-convention 'decode-char '(ch charset) "21.4")
1279(set-advertised-calling-convention 'encode-char '(ch charset) "21.4") 1280(set-advertised-calling-convention 'encode-char '(ch charset) "21.4")
diff --git a/lisp/textmodes/css-mode.el b/lisp/textmodes/css-mode.el
index c171bd50f62..f6a3ca64dd9 100644
--- a/lisp/textmodes/css-mode.el
+++ b/lisp/textmodes/css-mode.el
@@ -1,4 +1,4 @@
1;;; css-mode.el --- Major mode to edit CSS files -*- lexical-binding: t -*- 1;;; css-mode.el --- Major mode to edit CSS files -*- lexical-binding: t -*-
2 2
3;; Copyright (C) 2006-2015 Free Software Foundation, Inc. 3;; Copyright (C) 2006-2015 Free Software Foundation, Inc.
4 4
@@ -401,11 +401,16 @@
401 (cond 401 (cond
402 ;; This is a false positive inside a string or comment. 402 ;; This is a false positive inside a string or comment.
403 ((nth 8 (syntax-ppss)) nil) 403 ((nth 8 (syntax-ppss)) nil)
404 ;; This is a false positive when encountering an
405 ;; interpolated variable (bug#19751).
406 ((eq (char-before (- (point) 1)) ?#) nil)
404 ((eq (char-before) ?\}) 407 ((eq (char-before) ?\})
405 (save-excursion 408 (save-excursion
406 (forward-char -1) 409 (forward-char -1)
407 (skip-chars-backward " \t") 410 (skip-chars-backward " \t")
408 (unless (bolp) (newline)))) 411 (when (and (not (bolp))
412 (scss-smie--not-interpolation-p))
413 (newline))))
409 (t 414 (t
410 (while 415 (while
411 (progn 416 (progn
@@ -450,7 +455,7 @@
450(defun scss-smie--not-interpolation-p () 455(defun scss-smie--not-interpolation-p ()
451 (save-excursion 456 (save-excursion
452 (forward-char -1) 457 (forward-char -1)
453 (or (zerop (skip-chars-backward "[:alnum:]")) 458 (or (zerop (skip-chars-backward "-[:alnum:]"))
454 (not (looking-back "#{\\$" (- (point) 3)))))) 459 (not (looking-back "#{\\$" (- (point) 3))))))
455 460
456;;;###autoload (add-to-list 'auto-mode-alist '("\\.scss\\'" . scss-mode)) 461;;;###autoload (add-to-list 'auto-mode-alist '("\\.scss\\'" . scss-mode))
diff --git a/lisp/vc/vc-cvs.el b/lisp/vc/vc-cvs.el
index d803c16d7cf..707090a10eb 100644
--- a/lisp/vc/vc-cvs.el
+++ b/lisp/vc/vc-cvs.el
@@ -1076,7 +1076,7 @@ Query all files in DIR if files is nil."
1076 (if (and (not files) local (not (eq local 'only-file))) 1076 (if (and (not files) local (not (eq local 'only-file)))
1077 (vc-cvs-dir-status-heuristic dir update-function) 1077 (vc-cvs-dir-status-heuristic dir update-function)
1078 (if (not files) (setq files (vc-expand-dirs (list dir) 'CVS))) 1078 (if (not files) (setq files (vc-expand-dirs (list dir) 'CVS)))
1079 (vc-cvs-command (current-buffer) 'async dir "-f" "status" files) 1079 (vc-cvs-command (current-buffer) 'async files "-f" "status")
1080 ;; Alternative implementation: use the "update" command instead of 1080 ;; Alternative implementation: use the "update" command instead of
1081 ;; the "status" command. 1081 ;; the "status" command.
1082 ;; (vc-cvs-command (current-buffer) 'async 1082 ;; (vc-cvs-command (current-buffer) 'async
diff --git a/src/ChangeLog b/src/ChangeLog
index 6b56abbafd1..56f88f5bec4 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,117 @@
12015-02-08 Paul Eggert <eggert@cs.ucla.edu>
2
3 Minor tweaks to frame_size_history_add
4 * frame.c (frame_size_history_add): Don't assume length fits in 'int'.
5 Prefer XCAR and XCDR to Fcar and Fcdr when the arg is a cons.
6 (Fframe_after_make_frame): Simplify.
7 * gtkutil.c: Remove commented-out code.
8 * xfns.c (Fx_create_frame): Fix indenting.
9
102015-02-08 Eli Zaretskii <eliz@gnu.org>
11
12 * frame.c (Fframe_parameter): Don't replace a non-nil value of
13 foreground-color or background-color parameters with a nil value.
14 (Bug#19802)
15
162015-02-08 Stefan Monnier <monnier@iro.umontreal.ca>
17
18 * data.c (Findirect_function): Like `symbol-function', don't signal an
19 error for void functions any more.
20
212015-02-07 Martin Rudalics <rudalics@gmx.at>
22
23 * frame.c (frame_size_history_add): New function.
24 (frame_inhibit_resize): Consider frame_inhibit_implied_resize
25 only after frame's after_make_frame slot is true.
26 Inhibit resizing fullwidth-/height frames in one direction only.
27 Update frame_size_history.
28 (adjust_frame_size): Call frame_size_history_add.
29 (make_frame): Initalize after_make_frame slot.
30 (Fmake_terminal_frame): Adjust adjust_frame_size call.
31 (Fcan_run_window_configuration_change_hook): Rename to
32 Fframe_after_make_frame. Set after_make_frame slot.
33 Return second argument.
34 (x_set_frame_parameters): Postpone handling fullscreen parameter
35 until after width and height parameters have been set.
36 Apply width and height changes only if can_x_set_window_size is true.
37 Update frame_size_history.
38 (Qadjust_frame_size_1, Qadjust_frame_size_2)
39 (Qadjust_frame_size_3, QEmacsFrameResize, Qframe_inhibit_resize)
40 (Qx_set_fullscreen, Qx_check_fullscreen, Qx_set_window_size_1)
41 (Qxg_frame_resized, Qxg_frame_set_char_size_1)
42 (Qxg_frame_set_char_size_2, Qxg_frame_set_char_size_3)
43 (Qxg_change_toolbar_position, Qx_net_wm_state)
44 (Qx_handle_net_wm_state, Qtb_size_cb, Qupdate_frame_tool_bar)
45 (Qfree_frame_tool_bar): New symbol for updating frame_size_history.
46 (Qtip_frame, Qterminal_frame): New symbols.
47 (Vframe_adjust_size_history): Rename to frame_size_history.
48 * frame.h (struct frame):
49 Rename can_run_window_configuration_change_hook slot to
50 after_make_frame.
51 (frame_size_history_add): Extern.
52 * gtkutil.c (xg_frame_resized): Call frame_size_history_add.
53 Don't set FRAME_PIXEL_WIDTH and FRAME_PIXEL_HEIGHT here.
54 (xg_frame_set_char_size): Try to preserve the status of
55 fullwidth/-height frames. Call frame_size_history_add.
56 (tb_size_cb, update_frame_tool_bar, free_frame_tool_bar)
57 (xg_change_toolbar_position): Call frame_size_history_add.
58 * w32fns.c (x_change_tool_bar_height): Handle frame's fullscreen
59 status.
60 (Fx_create_frame): Process fullscreen parameter after frame has
61 been resized.
62 (x_create_tip_frame): Pass Qtip_frame to adjust_frame_size.
63 (Fx_frame_geometry): Don't pollute pure storage.
64 * w32term.c (w32_read_socket): For WM_WINDOWPOSCHANGED,
65 WM_ACTIVATE and WM_ACTIVATEAPP set frame's visibility before
66 calling w32fullscreen_hook. For WM_DISPLAYCHANGE call
67 w32fullscreen_hook immediately.
68 (x_fullscreen_adjust, x_check_fullscreen): Remove.
69 (w32fullscreen_hook): Call change_frame_size just as with a
70 "normal" frame resize operation. Call do_pending_window_change.
71 (x_set_window_size): Try to handle fullwidth and fullheight more
72 accurately. Don't rely on w32_enable_frame_resize_hack.
73 (w32_enable_frame_resize_hack): Remove variable.
74 * widget.c (EmacsFrameResize): Remove dead code.
75 Call frame_size_history_add
76 * window.c (run_window_configuration_change_hook):
77 Check f->after_make_frame instead of
78 f->can_run_window_configuration_change_hook.
79 * xfns.c (x_change_tool_bar_height): Handle frame's fullscreen status.
80 (Fx_create_frame): Process fullscreen parameter after frame has
81 been resized.
82 (Fx_frame_geometry): Don't pollute pure storage.
83 * xterm.c (x_net_wm_state, x_handle_net_wm_state):
84 Call frame_size_history_add.
85 (do_ewmh_fullscreen): Handle x_frame_normalize_before_maximize.
86 (x_check_fullscreen): Count in menubar when calling
87 XResizeWindow. Wait for ConfigureNotify event.
88 Call frame_size_history_add.
89 (x_set_window_size_1): Remove PIXELWISE argument. Try to handle
90 changing a fullheight frame's width or a fullwidth frame's
91 height. Call frame_size_history_add.
92 (x_set_window_size): Simplify xg_frame_set_char_size and
93 x_set_window_size_1 calls.
94 (x_frame_normalize_before_maximize): New variable.
95
962015-02-07 Paul Eggert <eggert@cs.ucla.edu>
97
98 Remove no-longer-used cursor_in_echo_area code
99 * dispnew.c (set_window_cursor_after_update, update_frame_1):
100 Remove checks for negative cursor_in_echo_area, since this var is
101 a boolean, and has been a boolean for some time. Simplify.
102 * dispnew.c (init_display):
103 * xdisp.c (message3_nolog, vmessage): Use bool for boolean.
104
1052015-02-05 Stefan Monnier <monnier@iro.umontreal.ca>
106
107 * eval.c (Ffunction): Handle the new (:documentation ...) form.
108 (syms_of_eval): Declare `:documentation'.
109
1102015-02-05 Martin Rudalics <rudalics@gmx.at>
111
112 * xdisp.c (Fwindow_text_pixel_size): Remove optional BUFFER
113 argument added on 2015-02-01.
114
12015-02-04 Paul Eggert <eggert@cs.ucla.edu> 1152015-02-04 Paul Eggert <eggert@cs.ucla.edu>
2 116
3 Remove no-longer-used two_byte_p calculations 117 Remove no-longer-used two_byte_p calculations
@@ -224,8 +338,8 @@
224 (x_horizontal_scroll_bar_report_motion, w32_read_socket) 338 (x_horizontal_scroll_bar_report_motion, w32_read_socket)
225 (w32_set_vertical_scroll_bar, w32_set_horizontal_scroll_bar) 339 (w32_set_vertical_scroll_bar, w32_set_horizontal_scroll_bar)
226 (w32_draw_window_cursor, x_new_font, x_set_offset) 340 (w32_draw_window_cursor, x_new_font, x_set_offset)
227 (x_set_window_size, x_make_frame_invisible, x_iconify_frame): Use 341 (x_set_window_size, x_make_frame_invisible, x_iconify_frame):
228 bool where appropriate. 342 Use bool where appropriate.
229 343
230 Use bool for boolean in w32fns.c 344 Use bool for boolean in w32fns.c
231 * w32fns.c (w32_defined_color, x_decode_color) 345 * w32fns.c (w32_defined_color, x_decode_color)
@@ -694,8 +808,8 @@
694 Qx_create_frame_2 to adjust_frame_size. 808 Qx_create_frame_2 to adjust_frame_size.
695 * w32menu.c (set_frame_menubar): Simplify adjust_frame_size 809 * w32menu.c (set_frame_menubar): Simplify adjust_frame_size
696 call. 810 call.
697 * window.c (Fset_window_configuration): Pass 811 * window.c (Fset_window_configuration):
698 Qset_window_configuration to adjust_frame_size. 812 Pass Qset_window_configuration to adjust_frame_size.
699 * xdisp.c (redisplay_tool_bar): Assign new height to 813 * xdisp.c (redisplay_tool_bar): Assign new height to
700 frame_default_tool_bar_height. 814 frame_default_tool_bar_height.
701 (redisplay_internal): If we haven't redisplayed this frame's 815 (redisplay_internal): If we haven't redisplayed this frame's
@@ -763,8 +877,8 @@
763 877
764 * w32fns.c (Fw32_register_hot_key): Use XINT instead of XLI. 878 * w32fns.c (Fw32_register_hot_key): Use XINT instead of XLI.
765 879
766 * w32notify.c (Fw32notify_add_watch, w32_get_watch_object): Use 880 * w32notify.c (Fw32notify_add_watch, w32_get_watch_object):
767 make_pointer_integer instead of XIL. 881 Use make_pointer_integer instead of XIL.
768 (Fw32notify_rm_watch): Use XINTPTR instead of XLI. 882 (Fw32notify_rm_watch): Use XINTPTR instead of XLI.
769 883
770 * w32inevt.c (handle_file_notifications): Use make_pointer_integer 884 * w32inevt.c (handle_file_notifications): Use make_pointer_integer
diff --git a/src/data.c b/src/data.c
index d06b9916b3a..47706584f5e 100644
--- a/src/data.c
+++ b/src/data.c
@@ -2125,8 +2125,6 @@ DEFUN ("indirect-function", Findirect_function, Sindirect_function, 1, 2, 0,
2125 doc: /* Return the function at the end of OBJECT's function chain. 2125 doc: /* Return the function at the end of OBJECT's function chain.
2126If OBJECT is not a symbol, just return it. Otherwise, follow all 2126If OBJECT is not a symbol, just return it. Otherwise, follow all
2127function indirections to find the final function binding and return it. 2127function indirections to find the final function binding and return it.
2128If the final symbol in the chain is unbound, signal a void-function error.
2129Optional arg NOERROR non-nil means to return nil instead of signaling.
2130Signal a cyclic-function-indirection error if there is a loop in the 2128Signal a cyclic-function-indirection error if there is a loop in the
2131function chain of symbols. */) 2129function chain of symbols. */)
2132 (register Lisp_Object object, Lisp_Object noerror) 2130 (register Lisp_Object object, Lisp_Object noerror)
@@ -2141,9 +2139,6 @@ function chain of symbols. */)
2141 if (!NILP (result)) 2139 if (!NILP (result))
2142 return result; 2140 return result;
2143 2141
2144 if (NILP (noerror))
2145 xsignal1 (Qvoid_function, object);
2146
2147 return Qnil; 2142 return Qnil;
2148} 2143}
2149 2144
diff --git a/src/dispnew.c b/src/dispnew.c
index e614ceef122..6ee4ccedf0b 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -3911,45 +3911,35 @@ set_window_cursor_after_update (struct window *w)
3911 { 3911 {
3912 cx = cy = vpos = hpos = 0; 3912 cx = cy = vpos = hpos = 0;
3913 3913
3914 if (cursor_in_echo_area >= 0) 3914 /* If the mini-buffer is several lines high, find the last
3915 line that has any text on it. Note: either all lines
3916 are enabled or none. Otherwise we wouldn't be able to
3917 determine Y. */
3918 struct glyph_row *last_row = NULL;
3919 int yb = window_text_bottom_y (w);
3920
3921 for (struct glyph_row *row = w->current_matrix->rows;
3922 row->enabled_p && (!last_row || MATRIX_ROW_BOTTOM_Y (row) <= yb);
3923 row++)
3924 if (row->used[TEXT_AREA] && row->glyphs[TEXT_AREA][0].charpos >= 0)
3925 last_row = row;
3926
3927 if (last_row)
3915 { 3928 {
3916 /* If the mini-buffer is several lines high, find the last 3929 struct glyph *start = last_row->glyphs[TEXT_AREA];
3917 line that has any text on it. Note: either all lines 3930 struct glyph *last = start + last_row->used[TEXT_AREA] - 1;
3918 are enabled or none. Otherwise we wouldn't be able to
3919 determine Y. */
3920 struct glyph_row *row, *last_row;
3921 struct glyph *glyph;
3922 int yb = window_text_bottom_y (w);
3923
3924 last_row = NULL;
3925 row = w->current_matrix->rows;
3926 while (row->enabled_p
3927 && (last_row == NULL
3928 || MATRIX_ROW_BOTTOM_Y (row) <= yb))
3929 {
3930 if (row->used[TEXT_AREA]
3931 && row->glyphs[TEXT_AREA][0].charpos >= 0)
3932 last_row = row;
3933 ++row;
3934 }
3935 3931
3936 if (last_row) 3932 while (last > start && last->charpos < 0)
3937 { 3933 --last;
3938 struct glyph *start = last_row->glyphs[TEXT_AREA];
3939 struct glyph *last = start + last_row->used[TEXT_AREA] - 1;
3940
3941 while (last > start && last->charpos < 0)
3942 --last;
3943 3934
3944 for (glyph = start; glyph < last; ++glyph) 3935 for (struct glyph *glyph = start; glyph < last; glyph++)
3945 { 3936 {
3946 cx += glyph->pixel_width; 3937 cx += glyph->pixel_width;
3947 ++hpos; 3938 hpos++;
3948 }
3949
3950 cy = last_row->y;
3951 vpos = MATRIX_ROW_VPOS (last_row, w->current_matrix);
3952 } 3939 }
3940
3941 cy = last_row->y;
3942 vpos = MATRIX_ROW_VPOS (last_row, w->current_matrix);
3953 } 3943 }
3954 } 3944 }
3955 else 3945 else
@@ -4569,58 +4559,43 @@ update_frame_1 (struct frame *f, bool force_p, bool inhibit_id_p,
4569 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window)) 4559 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
4570 { 4560 {
4571 int top = WINDOW_TOP_EDGE_LINE (XWINDOW (FRAME_MINIBUF_WINDOW (f))); 4561 int top = WINDOW_TOP_EDGE_LINE (XWINDOW (FRAME_MINIBUF_WINDOW (f)));
4572 int row, col; 4562 int col;
4573 4563
4574 if (cursor_in_echo_area < 0) 4564 /* Put cursor at the end of the prompt. If the mini-buffer
4565 is several lines high, find the last line that has
4566 any text on it. */
4567 int row = FRAME_TOTAL_LINES (f);
4568 do
4575 { 4569 {
4576 /* Negative value of cursor_in_echo_area means put 4570 row--;
4577 cursor at beginning of line. */
4578 row = top;
4579 col = 0; 4571 col = 0;
4580 }
4581 else
4582 {
4583 /* Positive value of cursor_in_echo_area means put
4584 cursor at the end of the prompt. If the mini-buffer
4585 is several lines high, find the last line that has
4586 any text on it. */
4587 row = FRAME_TOTAL_LINES (f);
4588 do
4589 {
4590 --row;
4591 col = 0;
4592 4572
4593 if (MATRIX_ROW_ENABLED_P (current_matrix, row)) 4573 if (MATRIX_ROW_ENABLED_P (current_matrix, row))
4594 { 4574 {
4595 /* Frame rows are filled up with spaces that 4575 /* Frame rows are filled up with spaces that
4596 must be ignored here. */ 4576 must be ignored here. */
4597 struct glyph_row *r = MATRIX_ROW (current_matrix, 4577 struct glyph_row *r = MATRIX_ROW (current_matrix, row);
4598 row); 4578 struct glyph *start = r->glyphs[TEXT_AREA];
4599 struct glyph *start = r->glyphs[TEXT_AREA]; 4579
4600 struct glyph *last = start + r->used[TEXT_AREA]; 4580 col = r->used[TEXT_AREA];
4601 4581 while (0 < col && start[col - 1].charpos < 0)
4602 while (last > start 4582 col--;
4603 && (last - 1)->charpos < 0)
4604 --last;
4605
4606 col = last - start;
4607 }
4608 } 4583 }
4609 while (row > top && col == 0); 4584 }
4585 while (row > top && col == 0);
4610 4586
4611 /* Make sure COL is not out of range. */ 4587 /* Make sure COL is not out of range. */
4612 if (col >= FRAME_CURSOR_X_LIMIT (f)) 4588 if (col >= FRAME_CURSOR_X_LIMIT (f))
4589 {
4590 /* If we have another row, advance cursor into it. */
4591 if (row < FRAME_TOTAL_LINES (f) - 1)
4613 { 4592 {
4614 /* If we have another row, advance cursor into it. */ 4593 col = FRAME_LEFT_SCROLL_BAR_COLS (f);
4615 if (row < FRAME_TOTAL_LINES (f) - 1) 4594 row++;
4616 {
4617 col = FRAME_LEFT_SCROLL_BAR_COLS (f);
4618 row++;
4619 }
4620 /* Otherwise move it back in range. */
4621 else
4622 col = FRAME_CURSOR_X_LIMIT (f) - 1;
4623 } 4595 }
4596 /* Otherwise move it back in range. */
4597 else
4598 col = FRAME_CURSOR_X_LIMIT (f) - 1;
4624 } 4599 }
4625 4600
4626 cursor_to (f, row, col); 4601 cursor_to (f, row, col);
@@ -5966,7 +5941,7 @@ init_display (void)
5966 space_glyph.charpos = -1; 5941 space_glyph.charpos = -1;
5967 5942
5968 inverse_video = 0; 5943 inverse_video = 0;
5969 cursor_in_echo_area = 0; 5944 cursor_in_echo_area = false;
5970 5945
5971 /* Now is the time to initialize this; it's used by init_sys_modes 5946 /* Now is the time to initialize this; it's used by init_sys_modes
5972 during startup. */ 5947 during startup. */
diff --git a/src/eval.c b/src/eval.c
index b98b224e622..e828da9288f 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -575,10 +575,23 @@ usage: (function ARG) */)
575 if (!NILP (Vinternal_interpreter_environment) 575 if (!NILP (Vinternal_interpreter_environment)
576 && CONSP (quoted) 576 && CONSP (quoted)
577 && EQ (XCAR (quoted), Qlambda)) 577 && EQ (XCAR (quoted), Qlambda))
578 /* This is a lambda expression within a lexical environment; 578 { /* This is a lambda expression within a lexical environment;
579 return an interpreted closure instead of a simple lambda. */ 579 return an interpreted closure instead of a simple lambda. */
580 return Fcons (Qclosure, Fcons (Vinternal_interpreter_environment, 580 Lisp_Object cdr = XCDR (quoted);
581 XCDR (quoted))); 581 Lisp_Object tmp = cdr;
582 if (CONSP (tmp)
583 && (tmp = XCDR (tmp), CONSP (tmp))
584 && (tmp = XCAR (tmp), CONSP (tmp))
585 && (EQ (QCdocumentation, XCAR (tmp))))
586 { /* Handle the special (:documentation <form>) to build the docstring
587 dynamically. */
588 Lisp_Object docstring = eval_sub (Fcar (XCDR (tmp)));
589 CHECK_STRING (docstring);
590 cdr = Fcons (XCAR (cdr), Fcons (docstring, XCDR (XCDR (cdr))));
591 }
592 return Fcons (Qclosure, Fcons (Vinternal_interpreter_environment,
593 cdr));
594 }
582 else 595 else
583 /* Simply quote the argument. */ 596 /* Simply quote the argument. */
584 return quoted; 597 return quoted;
@@ -3668,6 +3681,7 @@ before making `inhibit-quit' nil. */);
3668 DEFSYM (Qand_rest, "&rest"); 3681 DEFSYM (Qand_rest, "&rest");
3669 DEFSYM (Qand_optional, "&optional"); 3682 DEFSYM (Qand_optional, "&optional");
3670 DEFSYM (Qclosure, "closure"); 3683 DEFSYM (Qclosure, "closure");
3684 DEFSYM (QCdocumentation, ":documentation");
3671 DEFSYM (Qdebug, "debug"); 3685 DEFSYM (Qdebug, "debug");
3672 3686
3673 DEFVAR_LISP ("inhibit-debugger", Vinhibit_debugger, 3687 DEFVAR_LISP ("inhibit-debugger", Vinhibit_debugger,
diff --git a/src/frame.c b/src/frame.c
index 890e8972617..92b6b7c73ba 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -149,6 +149,32 @@ get_frame_param (register struct frame *frame, Lisp_Object prop)
149 return Fcdr (tem); 149 return Fcdr (tem);
150} 150}
151 151
152
153void
154frame_size_history_add (struct frame *f, Lisp_Object fun_symbol,
155 int width, int height, Lisp_Object rest)
156{
157 Lisp_Object frame;
158
159 XSETFRAME (frame, f);
160 if (CONSP (frame_size_history)
161 && INTEGERP (XCAR (frame_size_history))
162 && 0 < XINT (XCAR (frame_size_history)))
163 frame_size_history =
164 Fcons (make_number (XINT (XCAR (frame_size_history)) - 1),
165 Fcons (list4
166 (frame, fun_symbol,
167 ((width > 0)
168 ? list4 (make_number (FRAME_TEXT_WIDTH (f)),
169 make_number (FRAME_TEXT_HEIGHT (f)),
170 make_number (width),
171 make_number (height))
172 : Qnil),
173 rest),
174 XCDR (frame_size_history)));
175}
176
177
152/* Return 1 if `frame-inhibit-implied-resize' is non-nil or fullscreen 178/* Return 1 if `frame-inhibit-implied-resize' is non-nil or fullscreen
153 state of frame F would be affected by a vertical (horizontal if 179 state of frame F would be affected by a vertical (horizontal if
154 HORIZONTAL is true) resize. PARAMETER is the symbol of the frame 180 HORIZONTAL is true) resize. PARAMETER is the symbol of the frame
@@ -156,11 +182,27 @@ get_frame_param (register struct frame *frame, Lisp_Object prop)
156bool 182bool
157frame_inhibit_resize (struct frame *f, bool horizontal, Lisp_Object parameter) 183frame_inhibit_resize (struct frame *f, bool horizontal, Lisp_Object parameter)
158{ 184{
159 return (EQ (frame_inhibit_implied_resize, Qt) 185 Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
160 || (CONSP (frame_inhibit_implied_resize) 186 bool inhibit
161 && !NILP (Fmemq (parameter, frame_inhibit_implied_resize))) 187 = ((f->after_make_frame
162 || !NILP (get_frame_param (f, Qfullscreen)) 188 && (EQ (frame_inhibit_implied_resize, Qt)
163 || FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f)); 189 || (CONSP (frame_inhibit_implied_resize)
190 && !NILP (Fmemq (parameter, frame_inhibit_implied_resize)))))
191 || (horizontal
192 && !EQ (fullscreen, Qnil) && !EQ (fullscreen, Qfullheight))
193 || (!horizontal
194 && !EQ (fullscreen, Qnil) && !EQ (fullscreen, Qfullwidth))
195 || FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f));
196
197 if (inhibit && !FRAME_TERMCAP_P (f) && !FRAME_MSDOS_P (f))
198 frame_size_history_add
199 (f, Qframe_inhibit_resize, 0, 0,
200 list5 (horizontal ? Qt : Qnil, parameter,
201 f->after_make_frame ? Qt : Qnil,
202 frame_inhibit_implied_resize,
203 fullscreen));
204
205 return inhibit;
164} 206}
165 207
166static void 208static void
@@ -369,18 +411,9 @@ adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit,
369 411
370 XSETFRAME (frame, f); 412 XSETFRAME (frame, f);
371 413
372 /* `make-frame' initializes Vframe_adjust_size_history to (Qt) and 414 frame_size_history_add
373 strips its car when exiting. Just in case make sure its size never 415 (f, Qadjust_frame_size_1, new_text_width, new_text_height,
374 exceeds 100. */ 416 list2 (parameter, make_number (inhibit)));
375 if (!NILP (Fconsp (Vframe_adjust_size_history))
376 && EQ (Fcar (Vframe_adjust_size_history), Qt)
377 && XFASTINT (Fsafe_length (Vframe_adjust_size_history)) <= 100)
378 Vframe_adjust_size_history =
379 Fcons (Qt, Fcons (list5 (make_number (0),
380 make_number (new_text_width),
381 make_number (new_text_height),
382 make_number (inhibit), parameter),
383 Fcdr (Vframe_adjust_size_history)));
384 417
385 /* The following two values are calculated from the old window body 418 /* The following two values are calculated from the old window body
386 sizes and any "new" settings for scroll bars, dividers, fringes and 419 sizes and any "new" settings for scroll bars, dividers, fringes and
@@ -391,7 +424,7 @@ adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit,
391 = frame_windows_min_size (frame, Qnil, (inhibit == 5) ? Qt : Qnil, Qt); 424 = frame_windows_min_size (frame, Qnil, (inhibit == 5) ? Qt : Qnil, Qt);
392 425
393 if (inhibit >= 2 && inhibit <= 4) 426 if (inhibit >= 2 && inhibit <= 4)
394 /* If INHIBIT is in [2..4] inhibit if the "old" window sizes stay 427 /* When INHIBIT is in [2..4] inhibit if the "old" window sizes stay
395 within the limits and either frame_inhibit_resize tells us to do 428 within the limits and either frame_inhibit_resize tells us to do
396 so or INHIBIT equals 4. */ 429 so or INHIBIT equals 4. */
397 { 430 {
@@ -449,16 +482,10 @@ adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit,
449 else if (inhibit_vertical) 482 else if (inhibit_vertical)
450 new_text_height = old_text_height; 483 new_text_height = old_text_height;
451 484
452 if (!NILP (Fconsp (Vframe_adjust_size_history)) 485 frame_size_history_add
453 && EQ (Fcar (Vframe_adjust_size_history), Qt) 486 (f, Qadjust_frame_size_2, new_text_width, new_text_height,
454 && XFASTINT (Fsafe_length (Vframe_adjust_size_history)) <= 100) 487 list2 (inhibit_horizontal ? Qt : Qnil,
455 Vframe_adjust_size_history = 488 inhibit_vertical ? Qt : Qnil));
456 Fcons (Qt, Fcons (list5 (make_number (1),
457 make_number (new_text_width),
458 make_number (new_text_height),
459 make_number (new_cols),
460 make_number (new_lines)),
461 Fcdr (Vframe_adjust_size_history)));
462 489
463 x_set_window_size (f, 0, new_text_width, new_text_height, 1); 490 x_set_window_size (f, 0, new_text_width, new_text_height, 1);
464 f->resized_p = true; 491 f->resized_p = true;
@@ -525,6 +552,11 @@ adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit,
525 FrameRows (FRAME_TTY (f)) = new_lines + FRAME_TOP_MARGIN (f); 552 FrameRows (FRAME_TTY (f)) = new_lines + FRAME_TOP_MARGIN (f);
526 } 553 }
527 554
555 frame_size_history_add
556 (f, Qadjust_frame_size_3, new_text_width, new_text_height,
557 list4 (make_number (old_pixel_width), make_number (old_pixel_height),
558 make_number (new_pixel_width), make_number (new_pixel_height)));
559
528 /* Assign new sizes. */ 560 /* Assign new sizes. */
529 FRAME_TEXT_WIDTH (f) = new_text_width; 561 FRAME_TEXT_WIDTH (f) = new_text_width;
530 FRAME_TEXT_HEIGHT (f) = new_text_height; 562 FRAME_TEXT_HEIGHT (f) = new_text_height;
@@ -533,17 +565,6 @@ adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit,
533 SET_FRAME_COLS (f, new_cols); 565 SET_FRAME_COLS (f, new_cols);
534 SET_FRAME_LINES (f, new_lines); 566 SET_FRAME_LINES (f, new_lines);
535 567
536 if (!NILP (Fconsp (Vframe_adjust_size_history))
537 && EQ (Fcar (Vframe_adjust_size_history), Qt)
538 && XFASTINT (Fsafe_length (Vframe_adjust_size_history)) <= 100)
539 Vframe_adjust_size_history =
540 Fcons (Qt, Fcons (list5 (make_number (2),
541 make_number (new_text_width),
542 make_number (new_text_height),
543 make_number (new_cols),
544 make_number (new_lines)),
545 Fcdr (Vframe_adjust_size_history)));
546
547 { 568 {
548 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f)); 569 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
549 int text_area_x, text_area_y, text_area_width, text_area_height; 570 int text_area_x, text_area_y, text_area_width, text_area_height;
@@ -608,7 +629,7 @@ make_frame (bool mini_p)
608 f->redisplay = true; 629 f->redisplay = true;
609 f->garbaged = true; 630 f->garbaged = true;
610 f->can_x_set_window_size = false; 631 f->can_x_set_window_size = false;
611 f->can_run_window_configuration_change_hook = false; 632 f->after_make_frame = false;
612 f->tool_bar_redisplayed_once = false; 633 f->tool_bar_redisplayed_once = false;
613 f->column_width = 1; /* !FRAME_WINDOW_P value. */ 634 f->column_width = 1; /* !FRAME_WINDOW_P value. */
614 f->line_height = 1; /* !FRAME_WINDOW_P value. */ 635 f->line_height = 1; /* !FRAME_WINDOW_P value. */
@@ -1020,7 +1041,8 @@ affects all frames on the same terminal device. */)
1020 { 1041 {
1021 int width, height; 1042 int width, height;
1022 get_tty_size (fileno (FRAME_TTY (f)->input), &width, &height); 1043 get_tty_size (fileno (FRAME_TTY (f)->input), &width, &height);
1023 adjust_frame_size (f, width, height - FRAME_MENU_BAR_LINES (f), 5, 0, Qnil); 1044 adjust_frame_size (f, width, height - FRAME_MENU_BAR_LINES (f),
1045 5, 0, Qterminal_frame);
1024 } 1046 }
1025 1047
1026 adjust_frame_glyphs (f); 1048 adjust_frame_glyphs (f);
@@ -2260,24 +2282,23 @@ If there is no window system support, this function does nothing. */)
2260 return Qnil; 2282 return Qnil;
2261} 2283}
2262 2284
2263DEFUN ("frame-can-run-window-configuration-change-hook", 2285DEFUN ("frame-after-make-frame",
2264 Fcan_run_window_configuration_change_hook, 2286 Fframe_after_make_frame,
2265 Scan_run_window_configuration_change_hook, 2, 2, 0, 2287 Sframe_after_make_frame, 2, 2, 0,
2266 doc: /* Whether `window-configuration-change-hook' is run for frame FRAME. 2288 doc: /* Mark FRAME as made.
2267FRAME nil means use the selected frame. Second argument ALLOW non-nil 2289FRAME nil means use the selected frame. Second argument MADE non-nil
2268means functions on `window-configuration-change-hook' are called 2290means functions on `window-configuration-change-hook' are called
2269whenever the window configuration of FRAME changes. ALLOW nil means 2291whenever the window configuration of FRAME changes. MADE nil means
2270these functions are not called. 2292these functions are not called.
2271 2293
2272This function is currently called by `face-set-after-frame-default' only 2294This function is currently called by `make-frame' only and should be
2273and should be otherwise used with utter care to avoid that running 2295otherwise used with utter care to avoid that running functions on
2274functions on `window-configuration-change-hook' is impeded forever. */) 2296`window-configuration-change-hook' is impeded forever. */)
2275 (Lisp_Object frame, Lisp_Object allow) 2297 (Lisp_Object frame, Lisp_Object made)
2276{ 2298{
2277 struct frame *f = decode_live_frame (frame); 2299 struct frame *f = decode_live_frame (frame);
2278 2300 f->after_make_frame = !NILP (made);
2279 f->can_run_window_configuration_change_hook = NILP (allow) ? false : true; 2301 return made;
2280 return Qnil;
2281} 2302}
2282 2303
2283 2304
@@ -2591,7 +2612,12 @@ If FRAME is nil, describe the currently selected frame. */)
2591 important when param_alist's notion of colors is 2612 important when param_alist's notion of colors is
2592 "unspecified". We need to do the same here. */ 2613 "unspecified". We need to do the same here. */
2593 if (STRINGP (value) && !FRAME_WINDOW_P (f)) 2614 if (STRINGP (value) && !FRAME_WINDOW_P (f))
2594 value = frame_unspecified_color (f, value); 2615 {
2616 Lisp_Object tem = frame_unspecified_color (f, value);
2617
2618 if (!NILP (tem))
2619 value = tem;
2620 }
2595 } 2621 }
2596 else 2622 else
2597 value = Fcdr (Fassq (parameter, Fframe_parameters (frame))); 2623 value = Fcdr (Fassq (parameter, Fframe_parameters (frame)));
@@ -3037,7 +3063,7 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist)
3037 set them both at once. So we wait until we've looked at the 3063 set them both at once. So we wait until we've looked at the
3038 entire list before we set them. */ 3064 entire list before we set them. */
3039 int width IF_LINT (= 0), height IF_LINT (= 0); 3065 int width IF_LINT (= 0), height IF_LINT (= 0);
3040 bool width_change = 0, height_change = 0; 3066 bool width_change = false, height_change = false;
3041 3067
3042 /* Same here. */ 3068 /* Same here. */
3043 Lisp_Object left, top; 3069 Lisp_Object left, top;
@@ -3045,6 +3071,10 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist)
3045 /* Same with these. */ 3071 /* Same with these. */
3046 Lisp_Object icon_left, icon_top; 3072 Lisp_Object icon_left, icon_top;
3047 3073
3074 /* And with this. */
3075 Lisp_Object fullscreen;
3076 bool fullscreen_change = false;
3077
3048 /* Record in these vectors all the parms specified. */ 3078 /* Record in these vectors all the parms specified. */
3049 Lisp_Object *parms; 3079 Lisp_Object *parms;
3050 Lisp_Object *values; 3080 Lisp_Object *values;
@@ -3138,6 +3168,11 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist)
3138 icon_top = val; 3168 icon_top = val;
3139 else if (EQ (prop, Qicon_left)) 3169 else if (EQ (prop, Qicon_left))
3140 icon_left = val; 3170 icon_left = val;
3171 else if (EQ (prop, Qfullscreen))
3172 {
3173 fullscreen = val;
3174 fullscreen_change = true;
3175 }
3141 else if (EQ (prop, Qforeground_color) 3176 else if (EQ (prop, Qforeground_color)
3142 || EQ (prop, Qbackground_color) 3177 || EQ (prop, Qbackground_color)
3143 || EQ (prop, Qfont)) 3178 || EQ (prop, Qfont))
@@ -3218,14 +3253,14 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist)
3218 that here since otherwise a size change implied by an 3253 that here since otherwise a size change implied by an
3219 intermittent font change may get lost as in Bug#17142. */ 3254 intermittent font change may get lost as in Bug#17142. */
3220 if (!width_change) 3255 if (!width_change)
3221 width = (f->new_width 3256 width = ((f->can_x_set_window_size && f->new_width)
3222 ? (f->new_pixelwise 3257 ? (f->new_pixelwise
3223 ? f->new_width 3258 ? f->new_width
3224 : (f->new_width * FRAME_COLUMN_WIDTH (f))) 3259 : (f->new_width * FRAME_COLUMN_WIDTH (f)))
3225 : FRAME_TEXT_WIDTH (f)); 3260 : FRAME_TEXT_WIDTH (f));
3226 3261
3227 if (!height_change) 3262 if (!height_change)
3228 height = (f->new_height 3263 height = ((f->can_x_set_window_size && f->new_height)
3229 ? (f->new_pixelwise 3264 ? (f->new_pixelwise
3230 ? f->new_height 3265 ? f->new_height
3231 : (f->new_height * FRAME_LINE_HEIGHT (f))) 3266 : (f->new_height * FRAME_LINE_HEIGHT (f)))
@@ -3298,6 +3333,20 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist)
3298 /* Actually set that position, and convert to absolute. */ 3333 /* Actually set that position, and convert to absolute. */
3299 x_set_offset (f, leftpos, toppos, -1); 3334 x_set_offset (f, leftpos, toppos, -1);
3300 } 3335 }
3336
3337 if (fullscreen_change)
3338 {
3339 Lisp_Object old_value = get_frame_param (f, Qfullscreen);
3340
3341 frame_size_history_add
3342 (f, Qx_set_fullscreen, 0, 0, list2 (old_value, fullscreen));
3343
3344 store_frame_param (f, Qfullscreen, fullscreen);
3345 if (!EQ (fullscreen, old_value))
3346 x_set_fullscreen (f, fullscreen, old_value);
3347 }
3348
3349
3301#ifdef HAVE_X_WINDOWS 3350#ifdef HAVE_X_WINDOWS
3302 if ((!NILP (icon_left) || !NILP (icon_top)) 3351 if ((!NILP (icon_left) || !NILP (icon_top))
3303 && ! (icon_left_no_change && icon_top_no_change)) 3352 && ! (icon_left_no_change && icon_top_no_change))
@@ -4834,11 +4883,33 @@ syms_of_frame (void)
4834 DEFSYM (Qtool_bar_external, "tool-bar-external"); 4883 DEFSYM (Qtool_bar_external, "tool-bar-external");
4835 DEFSYM (Qtool_bar_size, "tool-bar-size"); 4884 DEFSYM (Qtool_bar_size, "tool-bar-size");
4836 DEFSYM (Qframe_inner_size, "frame-inner-size"); 4885 DEFSYM (Qframe_inner_size, "frame-inner-size");
4886 /* The following are used for frame_size_history. */
4887 DEFSYM (Qadjust_frame_size_1, "adjust-frame-size-1");
4888 DEFSYM (Qadjust_frame_size_2, "adjust-frame-size-2");
4889 DEFSYM (Qadjust_frame_size_3, "adjust-frame-size-3");
4890 DEFSYM (QEmacsFrameResize, "EmacsFrameResize");
4891 DEFSYM (Qframe_inhibit_resize, "frame-inhibit-resize");
4892 DEFSYM (Qx_set_fullscreen, "x-set-fullscreen");
4893 DEFSYM (Qx_check_fullscreen, "x-check-fullscreen");
4894 DEFSYM (Qx_set_window_size_1, "x-set-window-size-1");
4895 DEFSYM (Qxg_frame_resized, "xg-frame-resized");
4896 DEFSYM (Qxg_frame_set_char_size_1, "xg-frame-set-char-size-1");
4897 DEFSYM (Qxg_frame_set_char_size_2, "xg-frame-set-char-size-2");
4898 DEFSYM (Qxg_frame_set_char_size_3, "xg-frame-set-char-size-3");
4899 DEFSYM (Qxg_change_toolbar_position, "xg-change-toolbar-position");
4900 DEFSYM (Qx_net_wm_state, "x-net-wm-state");
4901 DEFSYM (Qx_handle_net_wm_state, "x-handle-net-wm-state");
4902 DEFSYM (Qtb_size_cb, "tb-size-cb");
4903 DEFSYM (Qupdate_frame_tool_bar, "update-frame-tool-bar");
4904 DEFSYM (Qfree_frame_tool_bar, "free-frame-tool-bar");
4905
4837 DEFSYM (Qchange_frame_size, "change-frame-size"); 4906 DEFSYM (Qchange_frame_size, "change-frame-size");
4838 DEFSYM (Qxg_frame_set_char_size, "xg-frame-set-char-size"); 4907 DEFSYM (Qxg_frame_set_char_size, "xg-frame-set-char-size");
4839 DEFSYM (Qset_window_configuration, "set-window-configuration"); 4908 DEFSYM (Qset_window_configuration, "set-window-configuration");
4840 DEFSYM (Qx_create_frame_1, "x-create-frame-1"); 4909 DEFSYM (Qx_create_frame_1, "x-create-frame-1");
4841 DEFSYM (Qx_create_frame_2, "x-create-frame-2"); 4910 DEFSYM (Qx_create_frame_2, "x-create-frame-2");
4911 DEFSYM (Qtip_frame, "tip-frame");
4912 DEFSYM (Qterminal_frame, "terminal-frame");
4842 4913
4843#ifdef HAVE_NS 4914#ifdef HAVE_NS
4844 DEFSYM (Qns_parse_geometry, "ns-parse-geometry"); 4915 DEFSYM (Qns_parse_geometry, "ns-parse-geometry");
@@ -5106,9 +5177,22 @@ even if this option is non-nil. */);
5106 frame_inhibit_implied_resize = Qt; 5177 frame_inhibit_implied_resize = Qt;
5107#endif 5178#endif
5108 5179
5109 DEFVAR_LISP ("frame-adjust-size-history", Vframe_adjust_size_history, 5180 DEFVAR_LISP ("frame-size-history", frame_size_history,
5110 doc: /* History of frame size adjustments. */); 5181 doc: /* History of frame size adjustments.
5111 Vframe_adjust_size_history = Qnil; 5182If non-nil, list recording frame size adjustment. Adjustments are
5183recorded only if the first element of this list is a positive number.
5184Adding an adjustment decrements that number by one.
5185
5186The remaining elements are the adjustments. Each adjustment is a list
5187of four elements `frame', `function', `sizes' and `more'. `frame' is
5188the affected frame and `function' the invoking function. `sizes' is
5189usually a list of four elements `old-width', `old-height', `new-width'
5190and `new-height' representing the old and new sizes recorded/requested
5191by `function'. `more' is a list with additional information.
5192
5193The function `frame--size-history' displays the value of this variable
5194in a more readable form. */);
5195 frame_size_history = Qnil;
5112 5196
5113 staticpro (&Vframe_list); 5197 staticpro (&Vframe_list);
5114 5198
@@ -5141,7 +5225,7 @@ even if this option is non-nil. */);
5141 defsubr (&Sraise_frame); 5225 defsubr (&Sraise_frame);
5142 defsubr (&Slower_frame); 5226 defsubr (&Slower_frame);
5143 defsubr (&Sx_focus_frame); 5227 defsubr (&Sx_focus_frame);
5144 defsubr (&Scan_run_window_configuration_change_hook); 5228 defsubr (&Sframe_after_make_frame);
5145 defsubr (&Sredirect_frame_focus); 5229 defsubr (&Sredirect_frame_focus);
5146 defsubr (&Sframe_focus); 5230 defsubr (&Sframe_focus);
5147 defsubr (&Sframe_parameters); 5231 defsubr (&Sframe_parameters);
diff --git a/src/frame.h b/src/frame.h
index 0c08d12c92e..6f5de3f5689 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -332,9 +332,8 @@ struct frame
332 frame. */ 332 frame. */
333 bool_bf can_x_set_window_size : 1; 333 bool_bf can_x_set_window_size : 1;
334 334
335 /* True means run_window_configuration_change_hook can be processed 335 /* Set to true after this frame was made by `make-frame'. */
336 for this frame. */ 336 bool_bf after_make_frame : 1;
337 bool_bf can_run_window_configuration_change_hook : 1;
338 337
339 /* True means tool bar has been redisplayed at least once in current 338 /* True means tool bar has been redisplayed at least once in current
340 session. */ 339 session. */
@@ -392,9 +391,9 @@ struct frame
392 int left_pos, top_pos; 391 int left_pos, top_pos;
393 392
394 /* Total width of this frame (including fringes, vertical scroll bar 393 /* Total width of this frame (including fringes, vertical scroll bar
395 and internal border widths) and total height (including menu bar, 394 and internal border widths) and total height (including internal
396 tool bar, horizontal scroll bar and internal border widths) in 395 menu and tool bars, horizontal scroll bar and internal border
397 pixels. */ 396 widths) in pixels. */
398 int pixel_width, pixel_height; 397 int pixel_width, pixel_height;
399 398
400 /* These many pixels are the difference between the outer window (i.e. the 399 /* These many pixels are the difference between the outer window (i.e. the
@@ -1124,6 +1123,8 @@ extern void frame_make_pointer_visible (struct frame *);
1124extern Lisp_Object delete_frame (Lisp_Object, Lisp_Object); 1123extern Lisp_Object delete_frame (Lisp_Object, Lisp_Object);
1125extern bool frame_inhibit_resize (struct frame *, bool, Lisp_Object); 1124extern bool frame_inhibit_resize (struct frame *, bool, Lisp_Object);
1126extern void adjust_frame_size (struct frame *, int, int, int, bool, Lisp_Object); 1125extern void adjust_frame_size (struct frame *, int, int, int, bool, Lisp_Object);
1126extern void frame_size_history_add (struct frame *f, Lisp_Object fun_symbol,
1127 int width, int height, Lisp_Object rest);
1127 1128
1128extern Lisp_Object Vframe_list; 1129extern Lisp_Object Vframe_list;
1129 1130
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 21f3cb15e66..6f1707894c1 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -50,12 +50,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
50#include "emacsgtkfixed.h" 50#include "emacsgtkfixed.h"
51#endif 51#endif
52 52
53/** #define FRAME_TOTAL_PIXEL_HEIGHT(f) \ **/
54/** (FRAME_PIXEL_HEIGHT (f) + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f)) **/
55
56/** #define FRAME_TOTAL_PIXEL_WIDTH(f) \ **/
57/** (FRAME_PIXEL_WIDTH (f) + FRAME_TOOLBAR_WIDTH (f)) **/
58
59#ifndef HAVE_GTK_WIDGET_SET_HAS_WINDOW 53#ifndef HAVE_GTK_WIDGET_SET_HAS_WINDOW
60#define gtk_widget_set_has_window(w, b) \ 54#define gtk_widget_set_has_window(w, b) \
61 (gtk_fixed_set_has_window (GTK_FIXED (w), b)) 55 (gtk_fixed_set_has_window (GTK_FIXED (w), b))
@@ -886,24 +880,23 @@ xg_frame_resized (struct frame *f, int pixelwidth, int pixelheight)
886 if (pixelwidth == -1 && pixelheight == -1) 880 if (pixelwidth == -1 && pixelheight == -1)
887 { 881 {
888 if (FRAME_GTK_WIDGET (f) && gtk_widget_get_mapped (FRAME_GTK_WIDGET (f))) 882 if (FRAME_GTK_WIDGET (f) && gtk_widget_get_mapped (FRAME_GTK_WIDGET (f)))
889 gdk_window_get_geometry (gtk_widget_get_window (FRAME_GTK_WIDGET (f)), 883 gdk_window_get_geometry (gtk_widget_get_window (FRAME_GTK_WIDGET (f)),
890 0, 0, 884 0, 0, &pixelwidth, &pixelheight);
891 &pixelwidth, &pixelheight); 885 else
892 else return; 886 return;
893 } 887 }
894 888
895
896 width = FRAME_PIXEL_TO_TEXT_WIDTH (f, pixelwidth); 889 width = FRAME_PIXEL_TO_TEXT_WIDTH (f, pixelwidth);
897 height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixelheight); 890 height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixelheight);
898 891
892 frame_size_history_add
893 (f, Qxg_frame_resized, width, height, Qnil);
894
899 if (width != FRAME_TEXT_WIDTH (f) 895 if (width != FRAME_TEXT_WIDTH (f)
900 || height != FRAME_TEXT_HEIGHT (f) 896 || height != FRAME_TEXT_HEIGHT (f)
901 || pixelwidth != FRAME_PIXEL_WIDTH (f) 897 || pixelwidth != FRAME_PIXEL_WIDTH (f)
902 || pixelheight != FRAME_PIXEL_HEIGHT (f)) 898 || pixelheight != FRAME_PIXEL_HEIGHT (f))
903 { 899 {
904 FRAME_PIXEL_WIDTH (f) = pixelwidth;
905 FRAME_PIXEL_HEIGHT (f) = pixelheight;
906
907 xg_clear_under_internal_border (f); 900 xg_clear_under_internal_border (f);
908 change_frame_size (f, width, height, 0, 1, 0, 1); 901 change_frame_size (f, width, height, 0, 1, 0, 1);
909 SET_FRAME_GARBAGED (f); 902 SET_FRAME_GARBAGED (f);
@@ -921,24 +914,71 @@ xg_frame_set_char_size (struct frame *f, int width, int height)
921{ 914{
922 int pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width); 915 int pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width);
923 int pixelheight = FRAME_TEXT_TO_PIXEL_HEIGHT (f, height); 916 int pixelheight = FRAME_TEXT_TO_PIXEL_HEIGHT (f, height);
917 Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
918 gint gwidth, gheight;
924 919
925 if (FRAME_PIXEL_HEIGHT (f) == 0) 920 if (FRAME_PIXEL_HEIGHT (f) == 0)
926 return; 921 return;
927 922
923 gtk_window_get_size (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
924 &gwidth, &gheight);
925
928 /* Do this before resize, as we don't know yet if we will be resized. */ 926 /* Do this before resize, as we don't know yet if we will be resized. */
929 xg_clear_under_internal_border (f); 927 xg_clear_under_internal_border (f);
930 928
931 /* Must resize our top level widget. Font size may have changed, 929 /* Resize the top level widget so rows and columns remain constant.
932 but not rows/cols. */ 930
933 gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), 931 When the frame is fullheight and we only want to change the width
934 pixelwidth + FRAME_TOOLBAR_WIDTH (f), 932 or it is fullwidth and we only want to change the height we should
935 pixelheight + FRAME_TOOLBAR_HEIGHT (f) 933 be able to preserve the fullscreen property. However, due to the
936 + FRAME_MENUBAR_HEIGHT (f)); 934 fact that we have to send a resize request anyway, the window
937 x_wm_set_size_hint (f, 0, 0); 935 manager will abolish it. At least the respective size should
936 remain unchanged but giving the frame back its normal size will
937 be broken ... */
938 if (EQ (fullscreen, Qfullwidth) && width == FRAME_TEXT_WIDTH (f))
939 {
940 frame_size_history_add
941 (f, Qxg_frame_set_char_size_1, width, height,
942 list2 (make_number (gheight),
943 make_number (pixelheight + FRAME_TOOLBAR_HEIGHT (f)
944 + FRAME_MENUBAR_HEIGHT (f))));
945
946 gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
947 gwidth,
948 pixelheight + FRAME_TOOLBAR_HEIGHT (f)
949 + FRAME_MENUBAR_HEIGHT (f));
950 }
951 else if (EQ (fullscreen, Qfullheight) && height == FRAME_TEXT_HEIGHT (f))
952 {
953 frame_size_history_add
954 (f, Qxg_frame_set_char_size_2, width, height,
955 list2 (make_number (gwidth),
956 make_number (pixelwidth + FRAME_TOOLBAR_WIDTH (f))));
957
958 gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
959 pixelwidth + FRAME_TOOLBAR_WIDTH (f),
960 gheight);
961 }
962
963 else
964 {
965 frame_size_history_add
966 (f, Qxg_frame_set_char_size_3, width, height,
967 list2 (make_number (pixelwidth + FRAME_TOOLBAR_WIDTH (f)),
968 make_number (pixelheight + FRAME_TOOLBAR_HEIGHT (f)
969 + FRAME_MENUBAR_HEIGHT (f))));
970
971 gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
972 pixelwidth + FRAME_TOOLBAR_WIDTH (f),
973 pixelheight + FRAME_TOOLBAR_HEIGHT (f)
974 + FRAME_MENUBAR_HEIGHT (f));
975 fullscreen = Qnil;
976 }
938 977
939 SET_FRAME_GARBAGED (f); 978 SET_FRAME_GARBAGED (f);
940 cancel_mouse_face (f); 979 cancel_mouse_face (f);
941 980
981 x_wm_set_size_hint (f, 0, 0);
942 /* We can not call change_frame_size for a mapped frame, 982 /* We can not call change_frame_size for a mapped frame,
943 we can not set pixel width/height either. The window manager may 983 we can not set pixel width/height either. The window manager may
944 override our resize request, XMonad does this all the time. 984 override our resize request, XMonad does this all the time.
@@ -952,9 +992,17 @@ xg_frame_set_char_size (struct frame *f, int width, int height)
952 (void)gtk_events_pending (); 992 (void)gtk_events_pending ();
953 gdk_flush (); 993 gdk_flush ();
954 x_wait_for_event (f, ConfigureNotify); 994 x_wait_for_event (f, ConfigureNotify);
995
996 if (!NILP (fullscreen))
997 /* Try to restore fullscreen state. */
998 {
999 store_frame_param (f, Qfullscreen, fullscreen);
1000 x_set_fullscreen (f, fullscreen, fullscreen);
1001 }
955 } 1002 }
956 else 1003 else
957 adjust_frame_size (f, -1, -1, 5, 0, Qxg_frame_set_char_size); 1004 adjust_frame_size (f, width, height, 5, 0, Qxg_frame_set_char_size);
1005
958} 1006}
959 1007
960/* Handle height/width changes (i.e. add/remove/move menu/toolbar). 1008/* Handle height/width changes (i.e. add/remove/move menu/toolbar).
@@ -4214,8 +4262,12 @@ tb_size_cb (GtkWidget *widget,
4214 allocated between widgets, it may get another. So we must update 4262 allocated between widgets, it may get another. So we must update
4215 size hints if tool bar size changes. Seen on Fedora 18 at least. */ 4263 size hints if tool bar size changes. Seen on Fedora 18 at least. */
4216 struct frame *f = user_data; 4264 struct frame *f = user_data;
4265
4217 if (xg_update_tool_bar_sizes (f)) 4266 if (xg_update_tool_bar_sizes (f))
4218 adjust_frame_size (f, -1, -1, 2, 0, Qtool_bar_lines); 4267 {
4268 frame_size_history_add (f, Qtb_size_cb, 0, 0, Qnil);
4269 adjust_frame_size (f, -1, -1, 5, 0, Qtool_bar_lines);
4270 }
4219} 4271}
4220 4272
4221/* Create a tool bar for frame F. */ 4273/* Create a tool bar for frame F. */
@@ -4489,10 +4541,11 @@ xg_update_tool_bar_sizes (struct frame *f)
4489 FRAME_TOOLBAR_RIGHT_WIDTH (f) = nr; 4541 FRAME_TOOLBAR_RIGHT_WIDTH (f) = nr;
4490 FRAME_TOOLBAR_TOP_HEIGHT (f) = nt; 4542 FRAME_TOOLBAR_TOP_HEIGHT (f) = nt;
4491 FRAME_TOOLBAR_BOTTOM_HEIGHT (f) = nb; 4543 FRAME_TOOLBAR_BOTTOM_HEIGHT (f) = nb;
4492 return 1;
4493 }
4494 4544
4495 return 0; 4545 return true;
4546 }
4547 else
4548 return false;
4496} 4549}
4497 4550
4498static char * 4551static char *
@@ -4815,7 +4868,10 @@ update_frame_tool_bar (struct frame *f)
4815 xg_pack_tool_bar (f, FRAME_TOOL_BAR_POSITION (f)); 4868 xg_pack_tool_bar (f, FRAME_TOOL_BAR_POSITION (f));
4816 gtk_widget_show_all (x->toolbar_widget); 4869 gtk_widget_show_all (x->toolbar_widget);
4817 if (xg_update_tool_bar_sizes (f)) 4870 if (xg_update_tool_bar_sizes (f))
4818 adjust_frame_size (f, -1, -1, 2, 0, Qtool_bar_lines); 4871 {
4872 frame_size_history_add (f, Qupdate_frame_tool_bar, 0, 0, Qnil);
4873 adjust_frame_size (f, -1, -1, 2, 0, Qtool_bar_lines);
4874 }
4819 } 4875 }
4820 4876
4821 unblock_input (); 4877 unblock_input ();
@@ -4863,6 +4919,7 @@ free_frame_tool_bar (struct frame *f)
4863 NULL); 4919 NULL);
4864 } 4920 }
4865 4921
4922 frame_size_history_add (f, Qfree_frame_tool_bar, 0, 0, Qnil);
4866 adjust_frame_size (f, -1, -1, 2, 0, Qtool_bar_lines); 4923 adjust_frame_size (f, -1, -1, 2, 0, Qtool_bar_lines);
4867 4924
4868 unblock_input (); 4925 unblock_input ();
@@ -4892,8 +4949,13 @@ xg_change_toolbar_position (struct frame *f, Lisp_Object pos)
4892 4949
4893 xg_pack_tool_bar (f, pos); 4950 xg_pack_tool_bar (f, pos);
4894 g_object_unref (top_widget); 4951 g_object_unref (top_widget);
4952
4895 if (xg_update_tool_bar_sizes (f)) 4953 if (xg_update_tool_bar_sizes (f))
4896 adjust_frame_size (f, -1, -1, 2, 0, Qtool_bar_lines); 4954 {
4955 frame_size_history_add (f, Qxg_change_toolbar_position, 0, 0, Qnil);
4956 adjust_frame_size (f, -1, -1, 2, 0, Qtool_bar_lines);
4957 }
4958
4897 4959
4898 unblock_input (); 4960 unblock_input ();
4899} 4961}
diff --git a/src/w32fns.c b/src/w32fns.c
index 8435270438d..08000d87d38 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -1722,6 +1722,7 @@ x_change_tool_bar_height (struct frame *f, int height)
1722 int old_height = FRAME_TOOL_BAR_HEIGHT (f); 1722 int old_height = FRAME_TOOL_BAR_HEIGHT (f);
1723 int lines = (height + unit - 1) / unit; 1723 int lines = (height + unit - 1) / unit;
1724 int old_text_height = FRAME_TEXT_HEIGHT (f); 1724 int old_text_height = FRAME_TEXT_HEIGHT (f);
1725 Lisp_Object fullscreen;
1725 1726
1726 /* Make sure we redisplay all windows in this frame. */ 1727 /* Make sure we redisplay all windows in this frame. */
1727 windows_or_buffers_changed = 23; 1728 windows_or_buffers_changed = 23;
@@ -1746,7 +1747,10 @@ x_change_tool_bar_height (struct frame *f, int height)
1746 f->n_tool_bar_rows = 0; 1747 f->n_tool_bar_rows = 0;
1747 1748
1748 adjust_frame_size (f, -1, -1, 1749 adjust_frame_size (f, -1, -1,
1749 (!f->tool_bar_redisplayed_once ? 1 1750 ((!f->tool_bar_redisplayed_once
1751 && (NILP (fullscreen =
1752 get_frame_param (f, Qfullscreen))
1753 || EQ (fullscreen, Qfullwidth))) ? 1
1750 : (old_height == 0 || height == 0) ? 2 1754 : (old_height == 0 || height == 0) ? 2
1751 : 4), 1755 : 4),
1752 false, Qtool_bar_lines); 1756 false, Qtool_bar_lines);
@@ -4668,8 +4672,6 @@ This function is an internal primitive--use `make-frame' instead. */)
4668 "bufferPredicate", "BufferPredicate", RES_TYPE_SYMBOL); 4672 "bufferPredicate", "BufferPredicate", RES_TYPE_SYMBOL);
4669 x_default_parameter (f, parameters, Qtitle, Qnil, 4673 x_default_parameter (f, parameters, Qtitle, Qnil,
4670 "title", "Title", RES_TYPE_STRING); 4674 "title", "Title", RES_TYPE_STRING);
4671 x_default_parameter (f, parameters, Qfullscreen, Qnil,
4672 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
4673 4675
4674 f->output_data.w32->dwStyle = WS_OVERLAPPEDWINDOW; 4676 f->output_data.w32->dwStyle = WS_OVERLAPPEDWINDOW;
4675 f->output_data.w32->parent_desc = FRAME_DISPLAY_INFO (f)->root_window; 4677 f->output_data.w32->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
@@ -4728,6 +4730,12 @@ This function is an internal primitive--use `make-frame' instead. */)
4728 x_wm_set_size_hint (f, window_prompting, false); 4730 x_wm_set_size_hint (f, window_prompting, false);
4729 unblock_input (); 4731 unblock_input ();
4730 4732
4733 /* Process fullscreen parameter here in the hope that normalizing a
4734 fullheight/fullwidth frame will produce the size set by the last
4735 adjust_frame_size call. */
4736 x_default_parameter (f, parameters, Qfullscreen, Qnil,
4737 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
4738
4731 /* Make the window appear on the frame and enable display, unless 4739 /* Make the window appear on the frame and enable display, unless
4732 the caller says not to. However, with explicit parent, Emacs 4740 the caller says not to. However, with explicit parent, Emacs
4733 cannot control visibility, so don't try. */ 4741 cannot control visibility, so don't try. */
@@ -5832,7 +5840,7 @@ x_create_tip_frame (struct w32_display_info *dpyinfo,
5832 SET_FRAME_COLS (f, 0); 5840 SET_FRAME_COLS (f, 0);
5833 SET_FRAME_LINES (f, 0); 5841 SET_FRAME_LINES (f, 0);
5834 adjust_frame_size (f, width * FRAME_COLUMN_WIDTH (f), 5842 adjust_frame_size (f, width * FRAME_COLUMN_WIDTH (f),
5835 height * FRAME_LINE_HEIGHT (f), 0, true, Qnil); 5843 height * FRAME_LINE_HEIGHT (f), 0, true, Qtip_frame);
5836 5844
5837 /* Add `tooltip' frame parameter's default value. */ 5845 /* Add `tooltip' frame parameter's default value. */
5838 if (NILP (Fframe_parameter (frame, Qtooltip))) 5846 if (NILP (Fframe_parameter (frame, Qtooltip)))
@@ -7558,7 +7566,7 @@ elements (all size values are in pixels).
7558 menu_bar_height = single_bar_height; 7566 menu_bar_height = single_bar_height;
7559 7567
7560 return 7568 return
7561 listn (CONSTYPE_PURE, 10, 7569 listn (CONSTYPE_HEAP, 10,
7562 Fcons (Qframe_position, 7570 Fcons (Qframe_position,
7563 Fcons (make_number (frame_outer_edges.left), 7571 Fcons (make_number (frame_outer_edges.left),
7564 make_number (frame_outer_edges.top))), 7572 make_number (frame_outer_edges.top))),
diff --git a/src/w32term.c b/src/w32term.c
index 251c46c73cf..fb9d2388d6b 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -3344,8 +3344,6 @@ static void x_horizontal_scroll_bar_report_motion (struct frame **, Lisp_Object
3344 enum scroll_bar_part *, 3344 enum scroll_bar_part *,
3345 Lisp_Object *, Lisp_Object *, 3345 Lisp_Object *, Lisp_Object *,
3346 Time *); 3346 Time *);
3347static void x_check_fullscreen (struct frame *);
3348
3349static void 3347static void
3350w32_define_cursor (Window window, Cursor cursor) 3348w32_define_cursor (Window window, Cursor cursor)
3351{ 3349{
@@ -4989,8 +4987,12 @@ w32_read_socket (struct terminal *terminal,
4989 sets the WAIT flag. */ 4987 sets the WAIT flag. */
4990 if ((msg.msg.message == WM_WINDOWPOSCHANGED || msg.msg.wParam) 4988 if ((msg.msg.message == WM_WINDOWPOSCHANGED || msg.msg.wParam)
4991 && (f->want_fullscreen & FULLSCREEN_WAIT)) 4989 && (f->want_fullscreen & FULLSCREEN_WAIT))
4992 w32fullscreen_hook (f); 4990 {
4993 x_check_fullscreen (f); 4991 /* Must set visibility right here since otherwise
4992 w32fullscreen_hook returns immediately. */
4993 SET_FRAME_VISIBLE (f, 1);
4994 w32fullscreen_hook (f);
4995 }
4994 } 4996 }
4995 check_visibility = 1; 4997 check_visibility = 1;
4996 break; 4998 break;
@@ -5269,11 +5271,18 @@ w32_read_socket (struct terminal *terminal,
5269 5271
5270 if (f) 5272 if (f)
5271 { 5273 {
5274 Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
5275
5272 dpyinfo->n_cbits = msg.msg.wParam; 5276 dpyinfo->n_cbits = msg.msg.wParam;
5273 /* The new display could have a different resolution, in 5277 /* The new display could have a different resolution, in
5274 which case we must reconsider what fullscreen 5278 which case we must reconsider what fullscreen means.
5275 means. */ 5279 The following code is untested yet. */
5276 x_check_fullscreen (f); 5280 if (!NILP (fullscreen))
5281 {
5282 x_set_fullscreen (f, fullscreen, fullscreen);
5283 w32fullscreen_hook (f);
5284 }
5285
5277 DebPrint (("display change: %d %d\n", 5286 DebPrint (("display change: %d %d\n",
5278 (short) LOWORD (msg.msg.lParam), 5287 (short) LOWORD (msg.msg.lParam),
5279 (short) HIWORD (msg.msg.lParam))); 5288 (short) HIWORD (msg.msg.lParam)));
@@ -5959,75 +5968,6 @@ x_set_offset (struct frame *f, register int xoff, register int yoff,
5959 unblock_input (); 5968 unblock_input ();
5960} 5969}
5961 5970
5962/* Calculate fullscreen size. Return in *TOP_POS and *LEFT_POS the
5963 wanted positions of the WM window (not Emacs window).
5964 Return in *WIDTH and *HEIGHT the wanted width and height of Emacs
5965 window (FRAME_X_WINDOW).
5966 */
5967
5968static void
5969x_fullscreen_adjust (struct frame *f, int *width, int *height, int *top_pos, int *left_pos)
5970{
5971 int newwidth = FRAME_COLS (f);
5972 int newheight = FRAME_LINES (f);
5973 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
5974
5975 *top_pos = f->top_pos;
5976 *left_pos = f->left_pos;
5977
5978 if (f->want_fullscreen & FULLSCREEN_HEIGHT)
5979 {
5980 int ph;
5981
5982 ph = x_display_pixel_height (dpyinfo);
5983 newheight = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, ph);
5984 ph = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, newheight) - f->y_pixels_diff;
5985 newheight = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, ph);
5986 *top_pos = 0;
5987 }
5988
5989 if (f->want_fullscreen & FULLSCREEN_WIDTH)
5990 {
5991 int pw;
5992
5993 pw = x_display_pixel_width (dpyinfo);
5994 newwidth = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pw);
5995 pw = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, newwidth) - f->x_pixels_diff;
5996 newwidth = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pw);
5997 *left_pos = 0;
5998 }
5999
6000 *width = newwidth;
6001 *height = newheight;
6002}
6003
6004/* Check if we need to resize the frame due to a fullscreen request.
6005 If so needed, resize the frame. */
6006static void
6007x_check_fullscreen (struct frame *f)
6008{
6009 if (f->want_fullscreen & FULLSCREEN_BOTH)
6010 {
6011 int width, height, ign;
6012
6013 x_real_positions (f, &f->left_pos, &f->top_pos);
6014
6015 x_fullscreen_adjust (f, &width, &height, &ign, &ign);
6016
6017 /* We do not need to move the window, it shall be taken care of
6018 when setting WM manager hints. */
6019 if (FRAME_COLS (f) != width || FRAME_LINES (f) != height)
6020 {
6021 change_frame_size (f, width, height, 0, 1, 0, 0);
6022 SET_FRAME_GARBAGED (f);
6023 cancel_mouse_face (f);
6024
6025 /* Wait for the change of frame size to occur. */
6026 f->want_fullscreen |= FULLSCREEN_WAIT;
6027 }
6028 }
6029}
6030
6031static void 5971static void
6032w32fullscreen_hook (struct frame *f) 5972w32fullscreen_hook (struct frame *f)
6033{ 5973{
@@ -6074,6 +6014,10 @@ w32fullscreen_hook (struct frame *f)
6074 SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top, 6014 SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top,
6075 rect.right - rect.left, rect.bottom - rect.top, 6015 rect.right - rect.left, rect.bottom - rect.top,
6076 SWP_NOOWNERZORDER | SWP_FRAMECHANGED); 6016 SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
6017 change_frame_size
6018 (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, rect.right - rect.left),
6019 FRAME_PIXEL_TO_TEXT_HEIGHT (f, rect.bottom - rect.top),
6020 0, 1, 0, 1);
6077 } 6021 }
6078 else 6022 else
6079 { 6023 {
@@ -6082,10 +6026,39 @@ w32fullscreen_hook (struct frame *f)
6082 FRAME_NORMAL_PLACEMENT (f).rcNormalPosition, &rect); 6026 FRAME_NORMAL_PLACEMENT (f).rcNormalPosition, &rect);
6083 SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top, 6027 SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top,
6084 rect.right - rect.left, rect.bottom - rect.top, 0); 6028 rect.right - rect.left, rect.bottom - rect.top, 0);
6029
6030 if (f->want_fullscreen == FULLSCREEN_WIDTH)
6031 {
6032 int border_width = GetSystemMetrics (SM_CXFRAME);
6033
6034 change_frame_size
6035 (f, (FRAME_PIXEL_TO_TEXT_WIDTH
6036 (f, rect.right - rect.left - 2 * border_width)),
6037 0, 0, 1, 0, 1);
6038 }
6039 else
6040 {
6041 int border_height = GetSystemMetrics (SM_CYFRAME);
6042 /* Won't work for wrapped menu bar. */
6043 int menu_bar_height = GetSystemMetrics (SM_CYMENU);
6044 int title_height = GetSystemMetrics (SM_CYCAPTION);
6045
6046 change_frame_size
6047 (f, 0, (FRAME_PIXEL_TO_TEXT_HEIGHT
6048 (f, rect.bottom - rect.top - 2 * border_height
6049 - title_height - menu_bar_height)),
6050 0, 1, 0, 1);
6051 }
6085 } 6052 }
6086 6053
6087 f->want_fullscreen = FULLSCREEN_NONE; 6054 f->want_fullscreen = FULLSCREEN_NONE;
6088 unblock_input (); 6055 unblock_input ();
6056
6057 if (f->want_fullscreen == FULLSCREEN_BOTH
6058 || f->want_fullscreen == FULLSCREEN_WIDTH
6059 || f->want_fullscreen == FULLSCREEN_HEIGHT)
6060 do_pending_window_change (0);
6061
6089 } 6062 }
6090 else 6063 else
6091 f->want_fullscreen |= FULLSCREEN_WAIT; 6064 f->want_fullscreen |= FULLSCREEN_WAIT;
@@ -6101,6 +6074,7 @@ x_set_window_size (struct frame *f, bool change_gravity,
6101 int width, int height, bool pixelwise) 6074 int width, int height, bool pixelwise)
6102{ 6075{
6103 int pixelwidth, pixelheight; 6076 int pixelwidth, pixelheight;
6077 Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
6104 RECT rect; 6078 RECT rect;
6105 6079
6106 block_input (); 6080 block_input ();
@@ -6119,7 +6093,7 @@ x_set_window_size (struct frame *f, bool change_gravity,
6119 if (w32_add_wrapped_menu_bar_lines) 6093 if (w32_add_wrapped_menu_bar_lines)
6120 { 6094 {
6121 /* When the menu bar wraps sending a SetWindowPos shrinks the 6095 /* When the menu bar wraps sending a SetWindowPos shrinks the
6122 height of the frame when the wrapped menu bar lines are not 6096 height of the frame then the wrapped menu bar lines are not
6123 accounted for (Bug#15174 and Bug#18720). Here we add these 6097 accounted for (Bug#15174 and Bug#18720). Here we add these
6124 extra lines to the frame height. */ 6098 extra lines to the frame height. */
6125 MENUBARINFO info; 6099 MENUBARINFO info;
@@ -6143,9 +6117,6 @@ x_set_window_size (struct frame *f, bool change_gravity,
6143 f->win_gravity = NorthWestGravity; 6117 f->win_gravity = NorthWestGravity;
6144 x_wm_set_size_hint (f, (long) 0, false); 6118 x_wm_set_size_hint (f, (long) 0, false);
6145 6119
6146 f->want_fullscreen = FULLSCREEN_NONE;
6147 w32fullscreen_hook (f);
6148
6149 rect.left = rect.top = 0; 6120 rect.left = rect.top = 0;
6150 rect.right = pixelwidth; 6121 rect.right = pixelwidth;
6151 rect.bottom = pixelheight; 6122 rect.bottom = pixelheight;
@@ -6153,45 +6124,45 @@ x_set_window_size (struct frame *f, bool change_gravity,
6153 AdjustWindowRect (&rect, f->output_data.w32->dwStyle, 6124 AdjustWindowRect (&rect, f->output_data.w32->dwStyle,
6154 FRAME_EXTERNAL_MENU_BAR (f)); 6125 FRAME_EXTERNAL_MENU_BAR (f));
6155 6126
6156 my_set_window_pos (FRAME_W32_WINDOW (f), 6127 if (!(f->after_make_frame)
6157 NULL, 6128 && !(f->want_fullscreen & FULLSCREEN_WAIT)
6158 0, 0, 6129 && FRAME_VISIBLE_P (f))
6159 rect.right - rect.left, 6130 {
6160 rect.bottom - rect.top, 6131 RECT window_rect;
6161 SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE); 6132
6162 6133 GetWindowRect (FRAME_W32_WINDOW (f), &window_rect);
6163 /* If w32_enable_frame_resize_hack is non-nil, immediately apply the
6164 new pixel sizes to the frame and its subwindows.
6165
6166 Jason Rumney earlier refused to call change_frame_size right here
6167 with the following argument:
6168
6169 The following mirrors what is done in xterm.c. It appears to be for
6170 informing lisp of the new size immediately, while the actual resize
6171 will happen asynchronously. But on Windows, the menu bar
6172 automatically wraps when the frame is too narrow to contain it, and
6173 that causes any calculations made here to come out wrong. The end
6174 is some nasty buggy behavior, including the potential loss of the
6175 minibuffer.
6176
6177 Disabling this code is either not sufficient to fix the problems
6178 completely, or it causes fresh problems, but at least it removes
6179 the most problematic symptom of the minibuffer becoming unusable.
6180
6181 However, as the discussion about how to handle frame size
6182 parameters on Windows (Bug#1348, Bug#16028) shows, that cure seems
6183 worse than the disease. In particular, menu bar wrapping looks
6184 like a non-issue - maybe so because Windows eventually gets back to
6185 us with the correct client rectangle anyway. But we have to avoid
6186 calling change_frame_size with a delta of less than one canoncial
6187 character size when frame_resize_pixelwise is nil, as explained in
6188 the comment above. */
6189
6190 if (w32_enable_frame_resize_hack)
6191 6134
6135 if (EQ (fullscreen, Qmaximized)
6136 || EQ (fullscreen, Qfullboth)
6137 || EQ (fullscreen, Qfullwidth))
6138 {
6139 rect.left = window_rect.left;
6140 rect.right = window_rect.right;
6141 pixelwidth = 0;
6142 }
6143 if (EQ (fullscreen, Qmaximized)
6144 || EQ (fullscreen, Qfullboth)
6145 || EQ (fullscreen, Qfullheight))
6146 {
6147 rect.top = window_rect.top;
6148 rect.bottom = window_rect.bottom;
6149 pixelheight = 0;
6150 }
6151 }
6152
6153 if (pixelwidth > 0 || pixelheight > 0)
6192 { 6154 {
6193 change_frame_size (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, pixelwidth), 6155 my_set_window_pos (FRAME_W32_WINDOW (f), NULL,
6194 FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixelheight), 6156 0, 0,
6157 rect.right - rect.left,
6158 rect.bottom - rect.top,
6159 SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
6160
6161 change_frame_size (f,
6162 ((pixelwidth == 0)
6163 ? 0 : FRAME_PIXEL_TO_TEXT_WIDTH (f, pixelwidth)),
6164 ((pixelheight == 0)
6165 ? 0 : FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixelheight)),
6195 0, 1, 0, 1); 6166 0, 1, 0, 1);
6196 SET_FRAME_GARBAGED (f); 6167 SET_FRAME_GARBAGED (f);
6197 6168
@@ -7102,7 +7073,7 @@ Windows 8. It is set to nil on Windows 9X. */);
7102 w32_unicode_filenames = 0; 7073 w32_unicode_filenames = 0;
7103 7074
7104 7075
7105 /* FIXME: The following two variables will be (hopefully) removed 7076 /* FIXME: The following variable will be (hopefully) removed
7106 before Emacs 25.1 gets released. */ 7077 before Emacs 25.1 gets released. */
7107 7078
7108 DEFVAR_BOOL ("w32-add-wrapped-menu-bar-lines", 7079 DEFVAR_BOOL ("w32-add-wrapped-menu-bar-lines",
@@ -7116,16 +7087,6 @@ wrapped menu bar lines when sending frame resize requests to the Windows
7116API. */); 7087API. */);
7117 w32_add_wrapped_menu_bar_lines = 1; 7088 w32_add_wrapped_menu_bar_lines = 1;
7118 7089
7119 DEFVAR_BOOL ("w32-enable-frame-resize-hack",
7120 w32_enable_frame_resize_hack,
7121 doc: /* Non-nil means enable hack for frame resizing on Windows.
7122A value of nil means to resize frames by sending a corresponding request
7123to the Windows API and changing the pixel sizes of the frame and its
7124windows after the latter calls back. If this is non-nil, Emacs changes
7125the pixel sizes of the frame and its windows at the time it sends the
7126resize request to the API. */);
7127 w32_enable_frame_resize_hack = 1;
7128
7129 /* Tell Emacs about this window system. */ 7090 /* Tell Emacs about this window system. */
7130 Fprovide (Qw32, Qnil); 7091 Fprovide (Qw32, Qnil);
7131} 7092}
diff --git a/src/widget.c b/src/widget.c
index c4d69407176..acf559f313b 100644
--- a/src/widget.c
+++ b/src/widget.c
@@ -460,7 +460,7 @@ update_wm_hints (EmacsFrame ew)
460 base_width = (wmshell->core.width - ew->core.width 460 base_width = (wmshell->core.width - ew->core.width
461 + (rounded_width - (char_width * cw))); 461 + (rounded_width - (char_width * cw)));
462 base_height = (wmshell->core.height - ew->core.height 462 base_height = (wmshell->core.height - ew->core.height
463 + (rounded_height - (char_height * ch))); 463 + (rounded_height - (char_height * ch)));
464 464
465 /* This is kind of sleazy, but I can't see how else to tell it to 465 /* This is kind of sleazy, but I can't see how else to tell it to
466 make it mark the WM_SIZE_HINTS size as user specified. 466 make it mark the WM_SIZE_HINTS size as user specified.
@@ -573,39 +573,20 @@ EmacsFrameResize (Widget widget)
573{ 573{
574 EmacsFrame ew = (EmacsFrame)widget; 574 EmacsFrame ew = (EmacsFrame)widget;
575 struct frame *f = ew->emacs_frame.frame; 575 struct frame *f = ew->emacs_frame.frame;
576 int width, height;
576 577
577 /* Always process resize requests pixelwise. Frame maximizing 578 pixel_to_text_size (ew, ew->core.width, ew->core.height, &width, &height);
578 should work even when frame_resize_pixelwise is nil. */
579 if (true || frame_resize_pixelwise)
580 {
581 int width, height;
582
583 pixel_to_text_size (ew, ew->core.width, ew->core.height, &width, &height);
584 change_frame_size (f, width, height, 0, 1, 0, 1);
585 579
586 update_wm_hints (ew); 580 frame_size_history_add
587 update_various_frame_slots (ew); 581 (f, QEmacsFrameResize, width, height,
582 list2 (make_number (ew->core.width), make_number (ew->core.height)));
588 583
589 cancel_mouse_face (f); 584 change_frame_size (f, width, height, 0, 1, 0, 1);
590 }
591 else
592 {
593 struct x_output *x = f->output_data.x;
594 int columns, rows;
595 585
596 pixel_to_char_size (ew, ew->core.width, ew->core.height, &columns, &rows); 586 update_wm_hints (ew);
597 if (columns != FRAME_COLS (f) 587 update_various_frame_slots (ew);
598 || rows != FRAME_LINES (f)
599 || ew->core.width != FRAME_PIXEL_WIDTH (f)
600 || ew->core.height + x->menubar_height != FRAME_PIXEL_HEIGHT (f))
601 {
602 change_frame_size (f, columns, rows, 0, 1, 0, 0);
603 update_wm_hints (ew);
604 update_various_frame_slots (ew);
605 588
606 cancel_mouse_face (f); 589 cancel_mouse_face (f);
607 }
608 }
609} 590}
610 591
611static XtGeometryResult 592static XtGeometryResult
diff --git a/src/window.c b/src/window.c
index b4230100150..5cbd58ddde9 100644
--- a/src/window.c
+++ b/src/window.c
@@ -3332,7 +3332,7 @@ run_window_configuration_change_hook (struct frame *f)
3332 3332
3333 if (NILP (Vrun_hooks) 3333 if (NILP (Vrun_hooks)
3334 || !(f->can_x_set_window_size) 3334 || !(f->can_x_set_window_size)
3335 || !(f->can_run_window_configuration_change_hook)) 3335 || !(f->after_make_frame))
3336 return; 3336 return;
3337 3337
3338 /* Use the right buffer. Matters when running the local hooks. */ 3338 /* Use the right buffer. Matters when running the local hooks. */
diff --git a/src/xdisp.c b/src/xdisp.c
index 4459363d3bc..faec93fc6f9 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -9703,7 +9703,7 @@ in_display_vector_p (struct it *it)
9703 && it->dpvec + it->current.dpvec_index != it->dpend); 9703 && it->dpvec + it->current.dpvec_index != it->dpend);
9704} 9704}
9705 9705
9706DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pixel_size, 0, 7, 0, 9706DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pixel_size, 0, 6, 0,
9707 doc: /* Return the size of the text of WINDOW's buffer in pixels. 9707 doc: /* Return the size of the text of WINDOW's buffer in pixels.
9708WINDOW must be a live window and defaults to the selected one. The 9708WINDOW must be a live window and defaults to the selected one. The
9709return value is a cons of the maximum pixel-width of any text line and 9709return value is a cons of the maximum pixel-width of any text line and
@@ -9736,17 +9736,12 @@ Optional argument MODE-AND-HEADER-LINE nil or omitted means do not
9736include the height of the mode- or header-line of WINDOW in the return 9736include the height of the mode- or header-line of WINDOW in the return
9737value. If it is either the symbol `mode-line' or `header-line', include 9737value. If it is either the symbol `mode-line' or `header-line', include
9738only the height of that line, if present, in the return value. If t, 9738only the height of that line, if present, in the return value. If t,
9739include the height of both, if present, in the return value. 9739include the height of both, if present, in the return value. */)
9740
9741Optional argument BUFFER nil means to return the size of the text of
9742WINDOW's buffer. BUFFER t means to return the size of the text of the
9743current buffer as if it were displayed in WINDOW. Else BUFFER has to
9744specify a live buffer and this function returns the size of the text of
9745BUFFER as if it were displayed in WINDOW. */)
9746 (Lisp_Object window, Lisp_Object from, Lisp_Object to, Lisp_Object x_limit, 9740 (Lisp_Object window, Lisp_Object from, Lisp_Object to, Lisp_Object x_limit,
9747 Lisp_Object y_limit, Lisp_Object mode_and_header_line, Lisp_Object buffer) 9741 Lisp_Object y_limit, Lisp_Object mode_and_header_line)
9748{ 9742{
9749 struct window *w = decode_live_window (window); 9743 struct window *w = decode_live_window (window);
9744 Lisp_Object buffer = w->contents;
9750 struct buffer *b; 9745 struct buffer *b;
9751 struct it it; 9746 struct it it;
9752 struct buffer *old_b = NULL; 9747 struct buffer *old_b = NULL;
@@ -9755,23 +9750,13 @@ BUFFER as if it were displayed in WINDOW. */)
9755 void *itdata = NULL; 9750 void *itdata = NULL;
9756 int c, max_y = -1, x = 0, y = 0; 9751 int c, max_y = -1, x = 0, y = 0;
9757 9752
9758 if (EQ (buffer, Qt)) 9753 CHECK_BUFFER (buffer);
9759 b = current_buffer; 9754 b = XBUFFER (buffer);
9760 else
9761 {
9762 if (NILP (buffer))
9763 buffer = w->contents;
9764
9765 CHECK_BUFFER (buffer);
9766 if (!BUFFER_LIVE_P (XBUFFER (buffer)))
9767 error ("Not a live buffer");
9768 9755
9769 b = XBUFFER (buffer); 9756 if (b != current_buffer)
9770 if (b != current_buffer) 9757 {
9771 { 9758 old_b = current_buffer;
9772 old_b = current_buffer; 9759 set_buffer_internal (b);
9773 set_buffer_internal (b);
9774 }
9775 } 9760 }
9776 9761
9777 if (NILP (from)) 9762 if (NILP (from))
@@ -10184,7 +10169,7 @@ message3_nolog (Lisp_Object m)
10184 10169
10185 fwrite (SDATA (s), SBYTES (s), 1, stderr); 10170 fwrite (SDATA (s), SBYTES (s), 1, stderr);
10186 } 10171 }
10187 if (cursor_in_echo_area == 0) 10172 if (!cursor_in_echo_area)
10188 fprintf (stderr, "\n"); 10173 fprintf (stderr, "\n");
10189 fflush (stderr); 10174 fflush (stderr);
10190 } 10175 }
@@ -10326,7 +10311,7 @@ vmessage (const char *m, va_list ap)
10326 putc ('\n', stderr); 10311 putc ('\n', stderr);
10327 noninteractive_need_newline = 0; 10312 noninteractive_need_newline = 0;
10328 vfprintf (stderr, m, ap); 10313 vfprintf (stderr, m, ap);
10329 if (cursor_in_echo_area == 0) 10314 if (!cursor_in_echo_area)
10330 fprintf (stderr, "\n"); 10315 fprintf (stderr, "\n");
10331 fflush (stderr); 10316 fflush (stderr);
10332 } 10317 }
diff --git a/src/xfns.c b/src/xfns.c
index 65eb6b497f2..629ac4b26ff 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -1095,6 +1095,7 @@ x_change_tool_bar_height (struct frame *f, int height)
1095 int unit = FRAME_LINE_HEIGHT (f); 1095 int unit = FRAME_LINE_HEIGHT (f);
1096 int old_height = FRAME_TOOL_BAR_HEIGHT (f); 1096 int old_height = FRAME_TOOL_BAR_HEIGHT (f);
1097 int lines = (height + unit - 1) / unit; 1097 int lines = (height + unit - 1) / unit;
1098 Lisp_Object fullscreen;
1098 1099
1099 /* Make sure we redisplay all windows in this frame. */ 1100 /* Make sure we redisplay all windows in this frame. */
1100 windows_or_buffers_changed = 60; 1101 windows_or_buffers_changed = 60;
@@ -1126,7 +1127,10 @@ x_change_tool_bar_height (struct frame *f, int height)
1126 f->n_tool_bar_rows = 0; 1127 f->n_tool_bar_rows = 0;
1127 1128
1128 adjust_frame_size (f, -1, -1, 1129 adjust_frame_size (f, -1, -1,
1129 (!f->tool_bar_redisplayed_once ? 1 1130 ((!f->tool_bar_redisplayed_once
1131 && (NILP (fullscreen =
1132 get_frame_param (f, Qfullscreen))
1133 || EQ (fullscreen, Qfullwidth))) ? 1
1130 : (old_height == 0 || height == 0) ? 2 1134 : (old_height == 0 || height == 0) ? 2
1131 : 4), 1135 : 4),
1132 false, Qtool_bar_lines); 1136 false, Qtool_bar_lines);
@@ -3180,8 +3184,6 @@ This function is an internal primitive--use `make-frame' instead. */)
3180 "title", "Title", RES_TYPE_STRING); 3184 "title", "Title", RES_TYPE_STRING);
3181 x_default_parameter (f, parms, Qwait_for_wm, Qt, 3185 x_default_parameter (f, parms, Qwait_for_wm, Qt,
3182 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN); 3186 "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN);
3183 x_default_parameter (f, parms, Qfullscreen, Qnil,
3184 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
3185 x_default_parameter (f, parms, Qtool_bar_position, 3187 x_default_parameter (f, parms, Qtool_bar_position,
3186 FRAME_TOOL_BAR_POSITION (f), 0, 0, RES_TYPE_SYMBOL); 3188 FRAME_TOOL_BAR_POSITION (f), 0, 0, RES_TYPE_SYMBOL);
3187 3189
@@ -3259,6 +3261,12 @@ This function is an internal primitive--use `make-frame' instead. */)
3259 x_wm_set_size_hint (f, window_prompting, false); 3261 x_wm_set_size_hint (f, window_prompting, false);
3260 unblock_input (); 3262 unblock_input ();
3261 3263
3264 /* Process fullscreen parameter here in the hope that normalizing a
3265 fullheight/fullwidth frame will produce the size set by the last
3266 adjust_frame_size call. */
3267 x_default_parameter (f, parms, Qfullscreen, Qnil,
3268 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
3269
3262 /* Make the window appear on the frame and enable display, unless 3270 /* Make the window appear on the frame and enable display, unless
3263 the caller says not to. However, with explicit parent, Emacs 3271 the caller says not to. However, with explicit parent, Emacs
3264 cannot control visibility, so don't try. */ 3272 cannot control visibility, so don't try. */
@@ -4318,7 +4326,7 @@ elements (all size values are in pixels).
4318 inner_height -= tool_bar_height; 4326 inner_height -= tool_bar_height;
4319 4327
4320 return 4328 return
4321 listn (CONSTYPE_PURE, 10, 4329 listn (CONSTYPE_HEAP, 10,
4322 Fcons (Qframe_position, 4330 Fcons (Qframe_position,
4323 Fcons (make_number (f->left_pos), make_number (f->top_pos))), 4331 Fcons (make_number (f->left_pos), make_number (f->top_pos))),
4324 Fcons (Qframe_outer_size, 4332 Fcons (Qframe_outer_size,
diff --git a/src/xterm.c b/src/xterm.c
index abceefb1b0e..555af2b536c 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -215,7 +215,7 @@ enum xembed_message
215 }; 215 };
216 216
217static bool x_alloc_nearest_color_1 (Display *, Colormap, XColor *); 217static bool x_alloc_nearest_color_1 (Display *, Colormap, XColor *);
218static void x_set_window_size_1 (struct frame *, bool, int, int, bool); 218static void x_set_window_size_1 (struct frame *, bool, int, int);
219static void x_raise_frame (struct frame *); 219static void x_raise_frame (struct frame *);
220static void x_lower_frame (struct frame *); 220static void x_lower_frame (struct frame *);
221static const XColor *x_color_cells (Display *, int *); 221static const XColor *x_color_cells (Display *, int *);
@@ -6585,6 +6585,10 @@ x_net_wm_state (struct frame *f, Window window)
6585 break; 6585 break;
6586 } 6586 }
6587 6587
6588 frame_size_history_add
6589 (f, Qx_net_wm_state, 0, 0,
6590 list2 (get_frame_param (f, Qfullscreen), lval));
6591
6588 store_frame_param (f, Qfullscreen, lval); 6592 store_frame_param (f, Qfullscreen, lval);
6589/** store_frame_param (f, Qsticky, sticky ? Qt : Qnil); **/ 6593/** store_frame_param (f, Qsticky, sticky ? Qt : Qnil); **/
6590} 6594}
@@ -9242,30 +9246,78 @@ do_ewmh_fullscreen (struct frame *f)
9242 None); 9246 None);
9243 break; 9247 break;
9244 case FULLSCREEN_WIDTH: 9248 case FULLSCREEN_WIDTH:
9245 if (cur == FULLSCREEN_BOTH || cur == FULLSCREEN_HEIGHT 9249 if (x_frame_normalize_before_maximize && cur == FULLSCREEN_MAXIMIZED)
9246 || cur == FULLSCREEN_MAXIMIZED) 9250 {
9247 set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen, 9251 set_wm_state (frame, false,
9248 dpyinfo->Xatom_net_wm_state_maximized_vert); 9252 dpyinfo->Xatom_net_wm_state_maximized_horz,
9249 if (cur != FULLSCREEN_MAXIMIZED) 9253 dpyinfo->Xatom_net_wm_state_maximized_vert);
9250 set_wm_state (frame, true, 9254 set_wm_state (frame, true,
9251 dpyinfo->Xatom_net_wm_state_maximized_horz, None); 9255 dpyinfo->Xatom_net_wm_state_maximized_horz, None);
9256 }
9257 else
9258 {
9259 if (cur == FULLSCREEN_BOTH || cur == FULLSCREEN_HEIGHT
9260 || cur == FULLSCREEN_MAXIMIZED)
9261 set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen,
9262 dpyinfo->Xatom_net_wm_state_maximized_vert);
9263 if (cur != FULLSCREEN_MAXIMIZED || x_frame_normalize_before_maximize)
9264 set_wm_state (frame, true,
9265 dpyinfo->Xatom_net_wm_state_maximized_horz, None);
9266 }
9252 break; 9267 break;
9253 case FULLSCREEN_HEIGHT: 9268 case FULLSCREEN_HEIGHT:
9254 if (cur == FULLSCREEN_BOTH || cur == FULLSCREEN_WIDTH 9269 if (x_frame_normalize_before_maximize && cur == FULLSCREEN_MAXIMIZED)
9255 || cur == FULLSCREEN_MAXIMIZED) 9270 {
9256 set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen, 9271 set_wm_state (frame, false,
9257 dpyinfo->Xatom_net_wm_state_maximized_horz); 9272 dpyinfo->Xatom_net_wm_state_maximized_horz,
9258 if (cur != FULLSCREEN_MAXIMIZED) 9273 dpyinfo->Xatom_net_wm_state_maximized_vert);
9259 set_wm_state (frame, true, 9274 set_wm_state (frame, true,
9260 dpyinfo->Xatom_net_wm_state_maximized_vert, None); 9275 dpyinfo->Xatom_net_wm_state_maximized_vert, None);
9276 }
9277 else
9278 {
9279 if (cur == FULLSCREEN_BOTH || cur == FULLSCREEN_WIDTH
9280 || cur == FULLSCREEN_MAXIMIZED)
9281 set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen,
9282 dpyinfo->Xatom_net_wm_state_maximized_horz);
9283 if (cur != FULLSCREEN_MAXIMIZED || x_frame_normalize_before_maximize)
9284 set_wm_state (frame, true,
9285 dpyinfo->Xatom_net_wm_state_maximized_vert, None);
9286 }
9261 break; 9287 break;
9262 case FULLSCREEN_MAXIMIZED: 9288 case FULLSCREEN_MAXIMIZED:
9263 if (cur == FULLSCREEN_BOTH) 9289 if (x_frame_normalize_before_maximize && cur == FULLSCREEN_WIDTH)
9264 set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen, 9290 {
9265 None); 9291 set_wm_state (frame, false,
9266 set_wm_state (frame, true, 9292 dpyinfo->Xatom_net_wm_state_maximized_horz, None);
9267 dpyinfo->Xatom_net_wm_state_maximized_horz, 9293 set_wm_state (frame, true,
9268 dpyinfo->Xatom_net_wm_state_maximized_vert); 9294 dpyinfo->Xatom_net_wm_state_maximized_horz,
9295 dpyinfo->Xatom_net_wm_state_maximized_vert);
9296 }
9297 else if (x_frame_normalize_before_maximize && cur == FULLSCREEN_HEIGHT)
9298 {
9299 set_wm_state (frame, false,
9300 dpyinfo->Xatom_net_wm_state_maximized_vert, None);
9301 set_wm_state (frame, true,
9302 dpyinfo->Xatom_net_wm_state_maximized_horz,
9303 dpyinfo->Xatom_net_wm_state_maximized_vert);
9304 }
9305 else
9306 {
9307 if (cur == FULLSCREEN_BOTH)
9308 set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen,
9309 None);
9310 else if (cur == FULLSCREEN_HEIGHT)
9311 set_wm_state (frame, true,
9312 dpyinfo->Xatom_net_wm_state_maximized_horz, None);
9313 else if (cur == FULLSCREEN_WIDTH)
9314 set_wm_state (frame, true, None,
9315 dpyinfo->Xatom_net_wm_state_maximized_vert);
9316 else
9317 set_wm_state (frame, true,
9318 dpyinfo->Xatom_net_wm_state_maximized_horz,
9319 dpyinfo->Xatom_net_wm_state_maximized_vert);
9320 }
9269 break; 9321 break;
9270 case FULLSCREEN_NONE: 9322 case FULLSCREEN_NONE:
9271 if (cur == FULLSCREEN_BOTH) 9323 if (cur == FULLSCREEN_BOTH)
@@ -9322,6 +9374,10 @@ x_handle_net_wm_state (struct frame *f, const XPropertyEvent *event)
9322 break; 9374 break;
9323 } 9375 }
9324 9376
9377 frame_size_history_add
9378 (f, Qx_handle_net_wm_state, 0, 0,
9379 list2 (get_frame_param (f, Qfullscreen), lval));
9380
9325 store_frame_param (f, Qfullscreen, lval); 9381 store_frame_param (f, Qfullscreen, lval);
9326 store_frame_param (f, Qsticky, sticky ? Qt : Qnil); 9382 store_frame_param (f, Qsticky, sticky ? Qt : Qnil);
9327 9383
@@ -9358,13 +9414,26 @@ x_check_fullscreen (struct frame *f)
9358 break; 9414 break;
9359 case FULLSCREEN_WIDTH: 9415 case FULLSCREEN_WIDTH:
9360 width = x_display_pixel_width (dpyinfo); 9416 width = x_display_pixel_width (dpyinfo);
9361 break; 9417 height = height + FRAME_MENUBAR_HEIGHT (f);
9418 break;
9362 case FULLSCREEN_HEIGHT: 9419 case FULLSCREEN_HEIGHT:
9363 height = x_display_pixel_height (dpyinfo); 9420 height = x_display_pixel_height (dpyinfo);
9364 } 9421 }
9365 9422
9423 frame_size_history_add
9424 (f, Qx_check_fullscreen, width, height, Qnil);
9425
9366 XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), 9426 XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
9367 width, height); 9427 width, height);
9428
9429 if (FRAME_VISIBLE_P (f))
9430 x_wait_for_event (f, ConfigureNotify);
9431 else
9432 {
9433 change_frame_size (f, width, height - FRAME_MENUBAR_HEIGHT (f),
9434 false, true, false, true);
9435 x_sync (f);
9436 }
9368 } 9437 }
9369} 9438}
9370 9439
@@ -9505,21 +9574,57 @@ x_wait_for_event (struct frame *f, int eventtype)
9505 9574
9506static void 9575static void
9507x_set_window_size_1 (struct frame *f, bool change_gravity, 9576x_set_window_size_1 (struct frame *f, bool change_gravity,
9508 int width, int height, bool pixelwise) 9577 int width, int height)
9509{ 9578{
9510 int pixelwidth, pixelheight; 9579 int pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width);
9511 9580 int pixelheight = FRAME_TEXT_TO_PIXEL_HEIGHT (f, height);
9512 pixelwidth = (pixelwise 9581 int old_width = FRAME_PIXEL_WIDTH (f);
9513 ? FRAME_TEXT_TO_PIXEL_WIDTH (f, width) 9582 int old_height = FRAME_PIXEL_HEIGHT (f);
9514 : FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, width)); 9583 Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
9515 pixelheight = ((pixelwise
9516 ? FRAME_TEXT_TO_PIXEL_HEIGHT (f, height)
9517 : FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height)));
9518 9584
9519 if (change_gravity) f->win_gravity = NorthWestGravity; 9585 if (change_gravity) f->win_gravity = NorthWestGravity;
9520 x_wm_set_size_hint (f, 0, false); 9586 x_wm_set_size_hint (f, 0, false);
9521 XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), 9587
9522 pixelwidth, pixelheight + FRAME_MENUBAR_HEIGHT (f)); 9588 /* When the frame is fullheight and we only want to change the width
9589 or it is fullwidth and we only want to change the height we should
9590 be able to preserve the fullscreen property. However, due to the
9591 fact that we have to send a resize request anyway, the window
9592 manager will abolish it. At least the respective size should
9593 remain unchanged but giving the frame back its normal size will
9594 be broken ... */
9595 if (EQ (fullscreen, Qfullwidth) && width == FRAME_TEXT_WIDTH (f))
9596 {
9597 frame_size_history_add
9598 (f, Qxg_frame_set_char_size_1, width, height,
9599 list2 (make_number (old_height),
9600 make_number (pixelheight + FRAME_MENUBAR_HEIGHT (f))));
9601
9602 XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
9603 old_width, pixelheight + FRAME_MENUBAR_HEIGHT (f));
9604 }
9605 else if (EQ (fullscreen, Qfullheight) && height == FRAME_TEXT_HEIGHT (f))
9606 {
9607 frame_size_history_add
9608 (f, Qxg_frame_set_char_size_2, width, height,
9609 list2 (make_number (old_width), make_number (pixelwidth)));
9610
9611 XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
9612 pixelwidth, old_height);
9613 }
9614
9615 else
9616 {
9617 frame_size_history_add
9618 (f, Qxg_frame_set_char_size_3, width, height,
9619 list2 (make_number (pixelwidth + FRAME_TOOLBAR_WIDTH (f)),
9620 make_number (pixelheight + FRAME_TOOLBAR_HEIGHT (f)
9621 + FRAME_MENUBAR_HEIGHT (f))));
9622
9623 XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
9624 pixelwidth, pixelheight + FRAME_MENUBAR_HEIGHT (f));
9625 fullscreen = Qnil;
9626 }
9627
9523 9628
9524 9629
9525 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to 9630 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
@@ -9546,7 +9651,16 @@ x_set_window_size_1 (struct frame *f, bool change_gravity,
9546 not right if the frame is visible. Instead wait (with timeout) 9651 not right if the frame is visible. Instead wait (with timeout)
9547 for the ConfigureNotify. */ 9652 for the ConfigureNotify. */
9548 if (FRAME_VISIBLE_P (f)) 9653 if (FRAME_VISIBLE_P (f))
9549 x_wait_for_event (f, ConfigureNotify); 9654 {
9655 x_wait_for_event (f, ConfigureNotify);
9656
9657 if (!NILP (fullscreen))
9658 /* Try to restore fullscreen state. */
9659 {
9660 store_frame_param (f, Qfullscreen, fullscreen);
9661 x_set_fullscreen (f, fullscreen, fullscreen);
9662 }
9663 }
9550 else 9664 else
9551 { 9665 {
9552 change_frame_size (f, width, height, false, true, false, true); 9666 change_frame_size (f, width, height, false, true, false, true);
@@ -9593,20 +9707,21 @@ x_set_window_size (struct frame *f, bool change_gravity,
9593 } 9707 }
9594#endif 9708#endif
9595 9709
9710 /* Pixelize width and height, if necessary. */
9711 if (! pixelwise)
9712 {
9713 width = width * FRAME_COLUMN_WIDTH (f);
9714 height = height * FRAME_LINE_HEIGHT (f);
9715 }
9716
9596#ifdef USE_GTK 9717#ifdef USE_GTK
9597 if (FRAME_GTK_WIDGET (f)) 9718 if (FRAME_GTK_WIDGET (f))
9598 if (! pixelwise) 9719 xg_frame_set_char_size (f, width, height);
9599 xg_frame_set_char_size (f, width * FRAME_COLUMN_WIDTH (f),
9600 height * FRAME_LINE_HEIGHT (f));
9601 else
9602 xg_frame_set_char_size (f, width, height);
9603 else 9720 else
9604 x_set_window_size_1 (f, change_gravity, width, height, pixelwise); 9721 x_set_window_size_1 (f, change_gravity, width, height);
9605#else /* not USE_GTK */ 9722#else /* not USE_GTK */
9606 9723 x_set_window_size_1 (f, change_gravity, width, height);
9607 x_set_window_size_1 (f, change_gravity, width, height, pixelwise);
9608 x_clear_under_internal_border (f); 9724 x_clear_under_internal_border (f);
9609
9610#endif /* not USE_GTK */ 9725#endif /* not USE_GTK */
9611 9726
9612 /* If cursor was outside the new size, mark it as off. */ 9727 /* If cursor was outside the new size, mark it as off. */
@@ -11617,4 +11732,15 @@ default is nil, which is the same as `super'. */);
11617 make_float (DEFAULT_REHASH_SIZE), 11732 make_float (DEFAULT_REHASH_SIZE),
11618 make_float (DEFAULT_REHASH_THRESHOLD), 11733 make_float (DEFAULT_REHASH_THRESHOLD),
11619 Qnil); 11734 Qnil);
11735
11736 DEFVAR_BOOL ("x-frame-normalize-before-maximize",
11737 x_frame_normalize_before_maximize,
11738 doc: /* Non-nil means normalize frame before maximizing.
11739If this variable is t, Emacs asks the window manager to give the frame
11740intermediately its normal size whenever changing from a full-height or
11741full-width state to the fully maximized one and vice versa.
11742
11743Set this variable only if your window manager cannot handle the
11744transition between the various maximization states. */);
11745 x_frame_normalize_before_maximize = false;
11620} 11746}
diff --git a/test/ChangeLog b/test/ChangeLog
index 60b3ed352d0..ff02bd6a25d 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,12 +1,40 @@
12015-02-01 Joakim Verona <joakim@verona.se> 12015-02-07 Fabián Ezequiel Gallina <fgallina@gnu.org>
2 Support for testing xwidgets 2
3 * xwidget-test-manual.el: 3 * automated/python-tests.el
4 (python-eldoc--get-symbol-at-point-1)
5 (python-eldoc--get-symbol-at-point-2)
6 (python-eldoc--get-symbol-at-point-3)
7 (python-eldoc--get-symbol-at-point-4): New tests.
8
92015-02-07 Fabián Ezequiel Gallina <fgallina@gnu.org>
10
11 * automated/python-tests.el
12 (python-tests-visible-string): New function.
13 (python-parens-electric-indent-1)
14 (python-triple-quote-pairing): Fix indentation, move require calls.
15 (python-hideshow-hide-levels-1)
16 (python-hideshow-hide-levels-2): New tests.
17
182015-02-07 Dmitry Gutov <dgutov@yandex.ru>
19
20 * automated/vc-tests.el (vc-test--working-revision): Fix
21 `vc-working-revision' checks to be compared against nil, which is
22 what is should return for unregistered files.
23
242015-02-06 Nicolas Petton <nicolas@petton.fr>
25
26 * automated/seq-tests.el: New tests for seq-mapcat, seq-partition
27 and seq-group-by.
28
292015-02-05 Artur Malabarba <bruce.connor.am@gmail.com>
30
31 * automated/package-test.el (package-test-get-deps): Fix typo.
32 (package-test-sort-by-dependence): New test
4 33
52015-02-03 Artur Malabarba <bruce.connor.am@gmail.com> 342015-02-03 Artur Malabarba <bruce.connor.am@gmail.com>
6 35
7 * automated/package-test.el (package-test-get-deps): New test. 36 * automated/package-test.el (package-test-get-deps): New test.
8 37
9
102015-01-31 Stefan Monnier <monnier@iro.umontreal.ca> 382015-01-31 Stefan Monnier <monnier@iro.umontreal.ca>
11 39
12 * automated/eieio-tests.el (eieio-test-23-inheritance-check): Simplify. 40 * automated/eieio-tests.el (eieio-test-23-inheritance-check): Simplify.
diff --git a/test/automated/package-test.el b/test/automated/package-test.el
index 004e2e89895..7d2a343a077 100644
--- a/test/automated/package-test.el
+++ b/test/automated/package-test.el
@@ -498,7 +498,7 @@ Must called from within a `tar-mode' buffer."
498 (list 1 package-x-test--single-archive-entry-1-4)))))) 498 (list 1 package-x-test--single-archive-entry-1-4))))))
499 499
500(ert-deftest package-test-get-deps () 500(ert-deftest package-test-get-deps ()
501 "Test `package-test-get-deps' with complex structures." 501 "Test `package--get-deps' with complex structures."
502 (let ((package-alist 502 (let ((package-alist
503 (mapcar (lambda (p) (list (package-desc-name p) p)) 503 (mapcar (lambda (p) (list (package-desc-name p) p))
504 (list simple-single-desc 504 (list simple-single-desc
@@ -526,6 +526,32 @@ Must called from within a `tar-mode' buffer."
526 (equal (package--get-deps 'simple-depend-2 'direct) 526 (equal (package--get-deps 'simple-depend-2 'direct)
527 '(simple-depend-1 multi-file))))) 527 '(simple-depend-1 multi-file)))))
528 528
529(ert-deftest package-test-sort-by-dependence ()
530 "Test `package--sort-by-dependence' with complex structures."
531 (let ((package-alist
532 (mapcar (lambda (p) (list (package-desc-name p) p))
533 (list simple-single-desc
534 simple-depend-desc
535 multi-file-desc
536 new-pkg-desc
537 simple-depend-desc-1
538 simple-depend-desc-2)))
539 (delete-list
540 (list simple-single-desc
541 simple-depend-desc
542 multi-file-desc
543 new-pkg-desc
544 simple-depend-desc-1
545 simple-depend-desc-2)))
546 (should
547 (equal (package--sort-by-dependence delete-list)
548 (list simple-depend-desc-2 simple-depend-desc-1 new-pkg-desc
549 multi-file-desc simple-depend-desc simple-single-desc)))
550 (should
551 (equal (package--sort-by-dependence (reverse delete-list))
552 (list new-pkg-desc simple-depend-desc-2 simple-depend-desc-1
553 multi-file-desc simple-depend-desc simple-single-desc)))))
554
529(provide 'package-test) 555(provide 'package-test)
530 556
531;;; package-test.el ends here 557;;; package-test.el ends here
diff --git a/test/automated/python-tests.el b/test/automated/python-tests.el
index 672b05c39de..47e2a6e8195 100644
--- a/test/automated/python-tests.el
+++ b/test/automated/python-tests.el
@@ -24,6 +24,11 @@
24(require 'ert) 24(require 'ert)
25(require 'python) 25(require 'python)
26 26
27;; Dependencies for testing:
28(require 'electric)
29(require 'hideshow)
30
31
27(defmacro python-tests-with-temp-buffer (contents &rest body) 32(defmacro python-tests-with-temp-buffer (contents &rest body)
28 "Create a `python-mode' enabled temp buffer with CONTENTS. 33 "Create a `python-mode' enabled temp buffer with CONTENTS.
29BODY is code to be executed within the temp buffer. Point is 34BODY is code to be executed within the temp buffer. Point is
@@ -104,6 +109,28 @@ STRING, it is skipped so the next STRING occurrence is selected."
104 (call-interactively 'self-insert-command))) 109 (call-interactively 'self-insert-command)))
105 chars))) 110 chars)))
106 111
112(defun python-tests-visible-string (&optional min max)
113 "Return the buffer string excluding invisible overlays.
114Argument MIN and MAX delimit the region to be returned and
115default to `point-min' and `point-max' respectively."
116 (let* ((min (or min (point-min)))
117 (max (or max (point-max)))
118 (buffer (current-buffer))
119 (buffer-contents (buffer-substring-no-properties min max))
120 (overlays
121 (sort (overlays-in min max)
122 (lambda (a b)
123 (let ((overlay-end-a (overlay-end a))
124 (overlay-end-b (overlay-end b)))
125 (> overlay-end-a overlay-end-b))))))
126 (with-temp-buffer
127 (insert buffer-contents)
128 (dolist (overlay overlays)
129 (if (overlay-get overlay 'invisible)
130 (delete-region (overlay-start overlay)
131 (overlay-end overlay))))
132 (buffer-substring-no-properties (point-min) (point-max)))))
133
107 134
108;;; Tests for your tests, so you can test while you test. 135;;; Tests for your tests, so you can test while you test.
109 136
@@ -2916,6 +2943,63 @@ class Foo(models.Model):
2916 2943
2917;;; Eldoc 2944;;; Eldoc
2918 2945
2946(ert-deftest python-eldoc--get-symbol-at-point-1 ()
2947 "Test paren handling."
2948 (python-tests-with-temp-buffer
2949 "
2950map(xx
2951map(codecs.open('somefile'
2952"
2953 (python-tests-look-at "ap(xx")
2954 (should (string= (python-eldoc--get-symbol-at-point) "map"))
2955 (goto-char (line-end-position))
2956 (should (string= (python-eldoc--get-symbol-at-point) "map"))
2957 (python-tests-look-at "('somefile'")
2958 (should (string= (python-eldoc--get-symbol-at-point) "map"))
2959 (goto-char (line-end-position))
2960 (should (string= (python-eldoc--get-symbol-at-point) "codecs.open"))))
2961
2962(ert-deftest python-eldoc--get-symbol-at-point-2 ()
2963 "Ensure self is replaced with the class name."
2964 (python-tests-with-temp-buffer
2965 "
2966class TheClass:
2967
2968 def some_method(self, n):
2969 return n
2970
2971 def other(self):
2972 return self.some_method(1234)
2973
2974"
2975 (python-tests-look-at "self.some_method")
2976 (should (string= (python-eldoc--get-symbol-at-point)
2977 "TheClass.some_method"))
2978 (python-tests-look-at "1234)")
2979 (should (string= (python-eldoc--get-symbol-at-point)
2980 "TheClass.some_method"))))
2981
2982(ert-deftest python-eldoc--get-symbol-at-point-3 ()
2983 "Ensure symbol is found when point is at end of buffer."
2984 (python-tests-with-temp-buffer
2985 "
2986some_symbol
2987
2988"
2989 (goto-char (point-max))
2990 (should (string= (python-eldoc--get-symbol-at-point)
2991 "some_symbol"))))
2992
2993(ert-deftest python-eldoc--get-symbol-at-point-4 ()
2994 "Ensure symbol is found when point is at whitespace."
2995 (python-tests-with-temp-buffer
2996 "
2997some_symbol some_other_symbol
2998"
2999 (python-tests-look-at " some_other_symbol")
3000 (should (string= (python-eldoc--get-symbol-at-point)
3001 "some_symbol"))))
3002
2919 3003
2920;;; Imenu 3004;;; Imenu
2921 3005
@@ -4358,12 +4442,11 @@ def foo(a, b, c):
4358;;; Electricity 4442;;; Electricity
4359 4443
4360(ert-deftest python-parens-electric-indent-1 () 4444(ert-deftest python-parens-electric-indent-1 ()
4361 (require 'electric)
4362 (let ((eim electric-indent-mode)) 4445 (let ((eim electric-indent-mode))
4363 (unwind-protect 4446 (unwind-protect
4364 (progn 4447 (progn
4365 (python-tests-with-temp-buffer 4448 (python-tests-with-temp-buffer
4366 " 4449 "
4367from django.conf.urls import patterns, include, url 4450from django.conf.urls import patterns, include, url
4368 4451
4369from django.contrib import admin 4452from django.contrib import admin
@@ -4375,66 +4458,148 @@ urlpatterns = patterns('',
4375 url(r'^$', views.index 4458 url(r'^$', views.index
4376) 4459)
4377" 4460"
4378 (electric-indent-mode 1) 4461 (electric-indent-mode 1)
4379 (python-tests-look-at "views.index") 4462 (python-tests-look-at "views.index")
4380 (end-of-line) 4463 (end-of-line)
4381 4464
4382 ;; Inserting commas within the same line should leave 4465 ;; Inserting commas within the same line should leave
4383 ;; indentation unchanged. 4466 ;; indentation unchanged.
4384 (python-tests-self-insert ",") 4467 (python-tests-self-insert ",")
4385 (should (= (current-indentation) 4)) 4468 (should (= (current-indentation) 4))
4386 4469
4387 ;; As well as any other input happening within the same 4470 ;; As well as any other input happening within the same
4388 ;; set of parens. 4471 ;; set of parens.
4389 (python-tests-self-insert " name='index')") 4472 (python-tests-self-insert " name='index')")
4390 (should (= (current-indentation) 4)) 4473 (should (= (current-indentation) 4))
4391 4474
4392 ;; But a comma outside it, should trigger indentation. 4475 ;; But a comma outside it, should trigger indentation.
4393 (python-tests-self-insert ",") 4476 (python-tests-self-insert ",")
4394 (should (= (current-indentation) 23)) 4477 (should (= (current-indentation) 23))
4395 4478
4396 ;; Newline indents to the first argument column 4479 ;; Newline indents to the first argument column
4397 (python-tests-self-insert "\n") 4480 (python-tests-self-insert "\n")
4398 (should (= (current-indentation) 23)) 4481 (should (= (current-indentation) 23))
4399 4482
4400 ;; All this input must not change indentation 4483 ;; All this input must not change indentation
4401 (indent-line-to 4) 4484 (indent-line-to 4)
4402 (python-tests-self-insert "url(r'^/login$', views.login)") 4485 (python-tests-self-insert "url(r'^/login$', views.login)")
4403 (should (= (current-indentation) 4)) 4486 (should (= (current-indentation) 4))
4404 4487
4405 ;; But this comma does 4488 ;; But this comma does
4406 (python-tests-self-insert ",") 4489 (python-tests-self-insert ",")
4407 (should (= (current-indentation) 23)))) 4490 (should (= (current-indentation) 23))))
4408 (or eim (electric-indent-mode -1))))) 4491 (or eim (electric-indent-mode -1)))))
4409 4492
4410(ert-deftest python-triple-quote-pairing () 4493(ert-deftest python-triple-quote-pairing ()
4411 (require 'electric)
4412 (let ((epm electric-pair-mode)) 4494 (let ((epm electric-pair-mode))
4413 (unwind-protect 4495 (unwind-protect
4414 (progn 4496 (progn
4415 (python-tests-with-temp-buffer 4497 (python-tests-with-temp-buffer
4416 "\"\"\n" 4498 "\"\"\n"
4417 (or epm (electric-pair-mode 1)) 4499 (or epm (electric-pair-mode 1))
4418 (goto-char (1- (point-max))) 4500 (goto-char (1- (point-max)))
4419 (python-tests-self-insert ?\") 4501 (python-tests-self-insert ?\")
4420 (should (string= (buffer-string) 4502 (should (string= (buffer-string)
4421 "\"\"\"\"\"\"\n")) 4503 "\"\"\"\"\"\"\n"))
4422 (should (= (point) 4))) 4504 (should (= (point) 4)))
4423 (python-tests-with-temp-buffer 4505 (python-tests-with-temp-buffer
4424 "\n" 4506 "\n"
4425 (python-tests-self-insert (list ?\" ?\" ?\")) 4507 (python-tests-self-insert (list ?\" ?\" ?\"))
4426 (should (string= (buffer-string) 4508 (should (string= (buffer-string)
4427 "\"\"\"\"\"\"\n")) 4509 "\"\"\"\"\"\"\n"))
4428 (should (= (point) 4))) 4510 (should (= (point) 4)))
4429 (python-tests-with-temp-buffer 4511 (python-tests-with-temp-buffer
4430 "\"\n\"\"\n" 4512 "\"\n\"\"\n"
4431 (goto-char (1- (point-max))) 4513 (goto-char (1- (point-max)))
4432 (python-tests-self-insert ?\") 4514 (python-tests-self-insert ?\")
4433 (should (= (point) (1- (point-max)))) 4515 (should (= (point) (1- (point-max))))
4434 (should (string= (buffer-string) 4516 (should (string= (buffer-string)
4435 "\"\n\"\"\"\n")))) 4517 "\"\n\"\"\"\n"))))
4436 (or epm (electric-pair-mode -1))))) 4518 (or epm (electric-pair-mode -1)))))
4437 4519
4520
4521;;; Hideshow support
4522
4523(ert-deftest python-hideshow-hide-levels-1 ()
4524 "Should hide all methods when called after class start."
4525 (let ((enabled hs-minor-mode))
4526 (unwind-protect
4527 (progn
4528 (python-tests-with-temp-buffer
4529 "
4530class SomeClass:
4531
4532 def __init__(self, arg, kwarg=1):
4533 self.arg = arg
4534 self.kwarg = kwarg
4535
4536 def filter(self, nums):
4537 def fn(item):
4538 return item in [self.arg, self.kwarg]
4539 return filter(fn, nums)
4540
4541 def __str__(self):
4542 return '%s-%s' % (self.arg, self.kwarg)
4543"
4544 (hs-minor-mode 1)
4545 (python-tests-look-at "class SomeClass:")
4546 (forward-line)
4547 (hs-hide-level 1)
4548 (should
4549 (string=
4550 (python-tests-visible-string)
4551 "
4552class SomeClass:
4553
4554 def __init__(self, arg, kwarg=1):
4555 def filter(self, nums):
4556 def __str__(self):"))))
4557 (or enabled (hs-minor-mode -1)))))
4558
4559(ert-deftest python-hideshow-hide-levels-2 ()
4560 "Should hide nested methods and parens at end of defun."
4561 (let ((enabled hs-minor-mode))
4562 (unwind-protect
4563 (progn
4564 (python-tests-with-temp-buffer
4565 "
4566class SomeClass:
4567
4568 def __init__(self, arg, kwarg=1):
4569 self.arg = arg
4570 self.kwarg = kwarg
4571
4572 def filter(self, nums):
4573 def fn(item):
4574 return item in [self.arg, self.kwarg]
4575 return filter(fn, nums)
4576
4577 def __str__(self):
4578 return '%s-%s' % (self.arg, self.kwarg)
4579"
4580 (hs-minor-mode 1)
4581 (python-tests-look-at "def fn(item):")
4582 (hs-hide-block)
4583 (should
4584 (string=
4585 (python-tests-visible-string)
4586 "
4587class SomeClass:
4588
4589 def __init__(self, arg, kwarg=1):
4590 self.arg = arg
4591 self.kwarg = kwarg
4592
4593 def filter(self, nums):
4594 def fn(item):
4595 return filter(fn, nums)
4596
4597 def __str__(self):
4598 return '%s-%s' % (self.arg, self.kwarg)
4599"))))
4600 (or enabled (hs-minor-mode -1)))))
4601
4602
4438 4603
4439(provide 'python-tests) 4604(provide 'python-tests)
4440 4605
diff --git a/test/automated/seq-tests.el b/test/automated/seq-tests.el
index 23989799306..ecbc0043210 100644
--- a/test/automated/seq-tests.el
+++ b/test/automated/seq-tests.el
@@ -2,7 +2,7 @@
2 2
3;; Copyright (C) 2014-2015 Free Software Foundation, Inc. 3;; Copyright (C) 2014-2015 Free Software Foundation, Inc.
4 4
5;; Author: Nicolas Petton <petton.nicolas@gmail.com> 5;; Author: Nicolas Petton <nicolas@petton.fr>
6;; Maintainer: emacs-devel@gnu.org 6;; Maintainer: emacs-devel@gnu.org
7 7
8;; This file is part of GNU Emacs. 8;; This file is part of GNU Emacs.
@@ -197,5 +197,29 @@ Evaluate BODY for each created sequence.
197 (should (equal (seq-concatenate 'vector nil '(8 10)) [8 10])) 197 (should (equal (seq-concatenate 'vector nil '(8 10)) [8 10]))
198 (should (equal (seq-concatenate 'vector seq nil) [2 4 6])))) 198 (should (equal (seq-concatenate 'vector seq nil) [2 4 6]))))
199 199
200(ert-deftest test-seq-mapcat ()
201 (should (equal (seq-mapcat #'seq-reverse '((3 2 1) (6 5 4)))
202 '(1 2 3 4 5 6)))
203 (should (equal (seq-mapcat #'seq-reverse '[(3 2 1) (6 5 4)])
204 '(1 2 3 4 5 6)))
205 (should (equal (seq-mapcat #'seq-reverse '((3 2 1) (6 5 4)) 'vector)
206 '[1 2 3 4 5 6])))
207
208(ert-deftest test-seq-partition ()
209 (should (same-contents-p (seq-partition '(0 1 2 3 4 5 6 7) 3)
210 '((0 1 2) (3 4 5) (6 7))))
211 (should (same-contents-p (seq-partition '[0 1 2 3 4 5 6 7] 3)
212 '([0 1 2] [3 4 5] [6 7])))
213 (should (same-contents-p (seq-partition "Hello world" 2)
214 '("He" "ll" "o " "wo" "rl" "d")))
215 (should (equal (seq-partition '() 2) '()))
216 (should (equal (seq-partition '(1 2 3) -1) '())))
217
218(ert-deftest test-seq-group-by ()
219 (should (equal (seq-group-by #'test-sequences-oddp [1 2 3 4])
220 '((t 3 1) (nil 4 2))))
221 (should (equal (seq-group-by #'car '((a 1) (b 3) (c 4) (a 2)))
222 '((a (a 2) (a 1)) (b (b 3)) (c (c 4))))))
223
200(provide 'seq-tests) 224(provide 'seq-tests)
201;;; seq-tests.el ends here 225;;; seq-tests.el ends here
diff --git a/test/automated/vc-tests.el b/test/automated/vc-tests.el
index 5b7b3cce039..e83eb85c0fe 100644
--- a/test/automated/vc-tests.el
+++ b/test/automated/vc-tests.el
@@ -330,18 +330,20 @@ For backends which dont support it, `vc-not-supported' is signalled."
330 (vc-working-revision default-directory backend) '("0" "master"))) 330 (vc-working-revision default-directory backend) '("0" "master")))
331 331
332 (let ((tmp-name (expand-file-name "foo" default-directory))) 332 (let ((tmp-name (expand-file-name "foo" default-directory)))
333 ;; Check for initial state. 333 ;; Check for initial state, should be nil until it's registered.
334 (should 334 ;; Don't pass the backend explictly, otherwise some implementations
335 (member (vc-working-revision tmp-name backend) '("0" "master"))) 335 ;; return non-nil.
336 (should (null (vc-working-revision tmp-name)))
336 337
337 ;; Write a new file. Check for state. 338 ;; Write a new file. Check state.
338 (write-region "foo" nil tmp-name nil 'nomessage) 339 (write-region "foo" nil tmp-name nil 'nomessage)
339 (should 340 (should (null (vc-working-revision tmp-name)))
340 (member (vc-working-revision tmp-name backend) '("0" "master")))
341 341
342 ;; Register a file. Check for state. 342 ;; Register a file. Check for state.
343 (vc-register 343 (vc-register
344 (list backend (list (file-name-nondirectory tmp-name)))) 344 (list backend (list (file-name-nondirectory tmp-name))))
345 ;; FIXME: Don't pass the backend. Emacs should be able to
346 ;; figure it out.
345 (should 347 (should
346 (member (vc-working-revision tmp-name backend) '("0" "master"))) 348 (member (vc-working-revision tmp-name backend) '("0" "master")))
347 349