summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/emacs/ChangeLog27
-rw-r--r--doc/emacs/cal-xtra.texi94
-rw-r--r--doc/emacs/calendar.texi88
-rw-r--r--doc/emacs/custom.texi5
-rw-r--r--doc/emacs/emacs.texi4
-rw-r--r--doc/emacs/macos.texi7
-rw-r--r--doc/emacs/maintaining.texi22
-rw-r--r--doc/emacs/mule.texi102
-rw-r--r--doc/emacs/rmail.texi11
-rw-r--r--doc/lispintro/ChangeLog4
-rw-r--r--doc/lispintro/emacs-lisp-intro.texi15
-rw-r--r--doc/lispref/ChangeLog17
-rw-r--r--doc/lispref/display.texi1
-rw-r--r--doc/lispref/elisp.texi1
-rw-r--r--doc/lispref/functions.texi1
-rw-r--r--doc/lispref/nonascii.texi51
-rw-r--r--doc/lispref/variables.texi1
-rw-r--r--doc/misc/ChangeLog5
-rw-r--r--doc/misc/gnus.texi39
-rw-r--r--etc/ChangeLog24
-rw-r--r--etc/DEVEL.HUMOR8
-rw-r--r--etc/NEWS25
-rw-r--r--etc/TODO9
-rw-r--r--etc/tutorials/TUTORIAL29
-rw-r--r--etc/tutorials/TUTORIAL.cn423
-rw-r--r--etc/tutorials/TUTORIAL.es4
-rw-r--r--etc/tutorials/TUTORIAL.translators2
-rw-r--r--lisp/ChangeLog197
-rw-r--r--lisp/autorevert.el12
-rw-r--r--lisp/custom.el85
-rw-r--r--lisp/desktop.el630
-rw-r--r--lisp/emacs-lisp/advice.el1
-rw-r--r--lisp/emacs-lisp/easy-mmode.el12
-rw-r--r--lisp/emacs-lisp/lisp-mode.el7
-rw-r--r--lisp/emacs-lisp/package.el2
-rw-r--r--lisp/emacs-lisp/re-builder.el2
-rw-r--r--lisp/files.el206
-rw-r--r--lisp/frameset.el693
-rw-r--r--lisp/gnus/ChangeLog71
-rw-r--r--lisp/gnus/gnus-delay.el2
-rw-r--r--lisp/gnus/gnus-group.el15
-rw-r--r--lisp/gnus/gnus-icalendar.el837
-rw-r--r--lisp/gnus/gnus-int.el4
-rw-r--r--lisp/gnus/gnus-score.el13
-rw-r--r--lisp/gnus/gnus-start.el6
-rw-r--r--lisp/gnus/gnus-sum.el3
-rw-r--r--lisp/gnus/gnus-util.el15
-rw-r--r--lisp/gnus/gnus-uu.el4
-rw-r--r--lisp/gnus/message.el2
-rw-r--r--lisp/gnus/mm-decode.el21
-rw-r--r--lisp/gnus/mml2015.el24
-rw-r--r--lisp/gnus/nnmbox.el53
-rw-r--r--lisp/gnus/nnrss.el36
-rw-r--r--lisp/gnus/rfc2047.el161
-rw-r--r--lisp/ibuf-ext.el2
-rw-r--r--lisp/ibuffer.el24
-rw-r--r--lisp/mh-e/mh-e.el1
-rw-r--r--lisp/minibuffer.el11
-rw-r--r--lisp/net/browse-url.el4
-rw-r--r--lisp/net/eww.el2
-rw-r--r--lisp/net/network-stream.el6
-rw-r--r--lisp/net/shr.el9
-rw-r--r--lisp/net/tramp-adb.el86
-rw-r--r--lisp/net/tramp-gvfs.el136
-rw-r--r--lisp/net/tramp-sh.el137
-rw-r--r--lisp/net/tramp-smb.el19
-rw-r--r--lisp/net/tramp.el88
-rw-r--r--lisp/server.el2
-rw-r--r--lisp/speedbar.el2
-rw-r--r--lisp/textmodes/reftex-toc.el4
-rw-r--r--lisp/url/ChangeLog5
-rw-r--r--lisp/url/url-handlers.el10
-rw-r--r--lisp/vc/log-view.el43
-rw-r--r--lisp/vc/vc-dir.el2
-rw-r--r--lisp/vc/vc-hooks.el4
-rw-r--r--lisp/whitespace.el13
-rw-r--r--src/ChangeLog196
-rw-r--r--src/callproc.c5
-rw-r--r--src/coding.c2
-rw-r--r--src/composite.c30
-rw-r--r--src/composite.h88
-rw-r--r--src/data.c4
-rw-r--r--src/eval.c124
-rw-r--r--src/fileio.c2
-rw-r--r--src/fns.c2
-rw-r--r--src/font.c107
-rw-r--r--src/font.h59
-rw-r--r--src/fontset.c21
-rw-r--r--src/fontset.h6
-rw-r--r--src/frame.c74
-rw-r--r--src/frame.h25
-rw-r--r--src/ftfont.c24
-rw-r--r--src/ftxfont.c22
-rw-r--r--src/gtkutil.c126
-rw-r--r--src/gtkutil.h46
-rw-r--r--src/image.c14
-rw-r--r--src/insdel.c22
-rw-r--r--src/keyboard.c12
-rw-r--r--src/lisp.h1
-rw-r--r--src/menu.c9
-rw-r--r--src/menu.h10
-rw-r--r--src/msdos.c18
-rw-r--r--src/msdos.h2
-rw-r--r--src/nsfns.m27
-rw-r--r--src/nsfont.m28
-rw-r--r--src/nsmenu.m6
-rw-r--r--src/nsterm.h13
-rw-r--r--src/nsterm.m58
-rw-r--r--src/scroll.c12
-rw-r--r--src/term.c28
-rw-r--r--src/terminal.c4
-rw-r--r--src/w32fns.c42
-rw-r--r--src/w32font.c41
-rw-r--r--src/w32font.h10
-rw-r--r--src/w32inevt.c12
-rw-r--r--src/w32inevt.h2
-rw-r--r--src/w32menu.c32
-rw-r--r--src/w32notify.c2
-rw-r--r--src/w32term.c59
-rw-r--r--src/w32term.h4
-rw-r--r--src/w32uniscribe.c23
-rw-r--r--src/w32xfns.c8
-rw-r--r--src/widget.c36
-rw-r--r--src/window.c4
-rw-r--r--src/xdisp.c10
-rw-r--r--src/xfaces.c13
-rw-r--r--src/xfns.c55
-rw-r--r--src/xfont.c35
-rw-r--r--src/xftfont.c28
-rw-r--r--src/xmenu.c89
-rw-r--r--src/xselect.c4
-rw-r--r--src/xterm.c103
-rw-r--r--src/xterm.h6
-rw-r--r--test/ChangeLog27
-rw-r--r--test/automated/core-elisp-tests.el40
-rw-r--r--test/automated/file-notify-tests.el14
-rw-r--r--test/automated/icalendar-tests.el76
-rw-r--r--test/automated/undo-tests.el4
138 files changed, 4262 insertions, 2487 deletions
diff --git a/doc/emacs/ChangeLog b/doc/emacs/ChangeLog
index eaae7ec5c9f..ad411e44ba6 100644
--- a/doc/emacs/ChangeLog
+++ b/doc/emacs/ChangeLog
@@ -1,3 +1,30 @@
+2013-07-31 Eli Zaretskii <eliz@gnu.org>
+
+ * emacs.texi (Top): Remove menu item for the removed "Disabling
+ Multibyte" node.
+
+2013-07-31 Xue Fuqiao <xfq.free@gmail.com>
+
+ * rmail.texi (Rmail Coding): Move here from mule.texi.
+
+ * custom.texi (Specifying File Variables): Fix cross-references.
+
+ * mule.texi (Unibyte Mode): Fix cross-references.
+ (Disabling Multibyte): Remove.
+
+ * macos.texi (Mac / GNUstep Basics): Mention `ns-alternate-modifier'.
+
+ * cal-xtra.texi (Advanced Calendar/Diary Usage): Update menu.
+ (Mayan Calendar): Move here from calendar.texi.
+ * emacs.texi (Top): Update menu.
+
+2013-07-30 Xue Fuqiao <xfq.free@gmail.com>
+
+ * emacs.texi (Top): Add menu entry.
+
+ * maintaining.texi (VC Ignore): New node. Document vc-ignore.
+ (VC Directory Commands): Add vc-dir-ignore.
+
2013-07-28 Xue Fuqiao <xfq.free@gmail.com>
* glossary.texi (Glossary): Add some entries.
diff --git a/doc/emacs/cal-xtra.texi b/doc/emacs/cal-xtra.texi
index 1b182327d33..5c964bbb369 100644
--- a/doc/emacs/cal-xtra.texi
+++ b/doc/emacs/cal-xtra.texi
@@ -17,6 +17,7 @@ your personal tastes.
@menu
* Calendar Customizing:: Calendar layout and hooks.
* Holiday Customizing:: Defining your own holidays.
+* Mayan Calendar:: Moving to a date specified in a Mayan calendar.
* Date Display Format:: Changing the format.
* Time Display Format:: Changing the format.
* Diary Customizing:: Defaults you can set.
@@ -260,6 +261,99 @@ visible in the calendar window, with descriptive strings, like this:
(((6 4 2012) "Lunar Eclipse") ((11 13 2012) "Solar Eclipse") ... )
@end smallexample
+@node Mayan Calendar
+@subsection Converting from the Mayan Calendar
+@cindex Mayan calendar
+
+ Here are the commands to select dates based on the Mayan calendar:
+
+@table @kbd
+@item g m l
+Move to a date specified by the long count calendar
+(@code{calendar-mayan-goto-long-count-date}).
+@item g m n t
+Move to the next occurrence of a place in the
+tzolkin calendar (@code{calendar-mayan-next-tzolkin-date}).
+@item g m p t
+Move to the previous occurrence of a place in the
+tzolkin calendar (@code{calendar-mayan-previous-tzolkin-date}).
+@item g m n h
+Move to the next occurrence of a place in the
+haab calendar (@code{calendar-mayan-next-haab-date}).
+@item g m p h
+Move to the previous occurrence of a place in the
+haab calendar (@code{calendar-mayan-previous-haab-date}).
+@item g m n c
+Move to the next occurrence of a place in the
+calendar round (@code{calendar-mayan-next-calendar-round-date}).
+@item g m p c
+Move to the previous occurrence of a place in the
+calendar round (@code{calendar-mayan-previous-calendar-round-date}).
+@end table
+
+@cindex Mayan long count
+ To understand these commands, you need to understand the Mayan calendars.
+The @dfn{long count} is a counting of days with these units:
+
+@display
+1 kin = 1 day@ @ @ 1 uinal = 20 kin@ @ @ 1 tun = 18 uinal
+1 katun = 20 tun@ @ @ 1 baktun = 20 katun
+@end display
+
+@kindex g m @r{(Calendar mode)}
+@findex calendar-mayan-goto-long-count-date
+@noindent
+Thus, the long count date 12.16.11.16.6 means 12 baktun, 16 katun, 11
+tun, 16 uinal, and 6 kin. The Emacs calendar can handle Mayan long
+count dates as early as 7.17.18.13.3, but no earlier. When you use the
+@kbd{g m l} command, type the Mayan long count date with the baktun,
+katun, tun, uinal, and kin separated by periods.
+
+@findex calendar-mayan-previous-tzolkin-date
+@findex calendar-mayan-next-tzolkin-date
+@cindex Mayan tzolkin calendar
+ The Mayan tzolkin calendar is a cycle of 260 days formed by a pair of
+independent cycles of 13 and 20 days. Since this cycle repeats
+endlessly, Emacs provides commands to move backward and forward to the
+previous or next point in the cycle. Type @kbd{g m p t} to go to the
+previous tzolkin date; Emacs asks you for a tzolkin date and moves point
+to the previous occurrence of that date. Similarly, type @kbd{g m n t}
+to go to the next occurrence of a tzolkin date.
+
+@findex calendar-mayan-previous-haab-date
+@findex calendar-mayan-next-haab-date
+@cindex Mayan haab calendar
+ The Mayan haab calendar is a cycle of 365 days arranged as 18 months
+of 20 days each, followed by a 5-day monthless period. Like the tzolkin
+cycle, this cycle repeats endlessly, and there are commands to move
+backward and forward to the previous or next point in the cycle. Type
+@kbd{g m p h} to go to the previous haab date; Emacs asks you for a haab
+date and moves point to the previous occurrence of that date.
+Similarly, type @kbd{g m n h} to go to the next occurrence of a haab
+date.
+
+@c This is omitted because it is too long for smallbook format.
+@c @findex calendar-mayan-previous-calendar-round-date
+@findex calendar-mayan-next-calendar-round-date
+@cindex Mayan calendar round
+ The Maya also used the combination of the tzolkin date and the haab
+date. This combination is a cycle of about 52 years called a
+@emph{calendar round}. If you type @kbd{g m p c}, Emacs asks you for
+both a haab and a tzolkin date and then moves point to the previous
+occurrence of that combination. Use @kbd{g m n c} to move point to the
+next occurrence of a combination. These commands signal an error if the
+haab/tzolkin date combination you have typed is impossible.
+
+ Emacs uses strict completion
+@iftex
+(@pxref{Completion Exit,,, emacs, the Emacs Manual})
+@end iftex
+@ifnottex
+(@pxref{Completion Exit})
+@end ifnottex
+whenever it asks you to type a Mayan name, so you don't have to worry
+about spelling.
+
@node Date Display Format
@subsection Date Display Format
@vindex calendar-date-display-form
diff --git a/doc/emacs/calendar.texi b/doc/emacs/calendar.texi
index 075d753ae7a..88f46984207 100644
--- a/doc/emacs/calendar.texi
+++ b/doc/emacs/calendar.texi
@@ -678,7 +678,6 @@ and from several other calendars.
(aside from Gregorian).
* To Other Calendar:: Converting the selected date to various calendars.
* From Other Calendar:: Moving to a date specified in another calendar.
-* Mayan Calendar:: Moving to a date specified in a Mayan calendar.
@end menu
@c FIXME perhaps most of the details should be moved to cal-xtra.
@@ -913,93 +912,6 @@ years for the date given by point. If you are not in the calendar,
this command first asks you for the date of death and the range of
years, and then displays the list of yahrzeit dates.
-@c FIXME move to emacs-xtra.
-@node Mayan Calendar
-@subsection Converting from the Mayan Calendar
-
- Here are the commands to select dates based on the Mayan calendar:
-
-@table @kbd
-@item g m l
-Move to a date specified by the long count calendar
-(@code{calendar-mayan-goto-long-count-date}).
-@item g m n t
-Move to the next occurrence of a place in the
-tzolkin calendar (@code{calendar-mayan-next-tzolkin-date}).
-@item g m p t
-Move to the previous occurrence of a place in the
-tzolkin calendar (@code{calendar-mayan-previous-tzolkin-date}).
-@item g m n h
-Move to the next occurrence of a place in the
-haab calendar (@code{calendar-mayan-next-haab-date}).
-@item g m p h
-Move to the previous occurrence of a place in the
-haab calendar (@code{calendar-mayan-previous-haab-date}).
-@item g m n c
-Move to the next occurrence of a place in the
-calendar round (@code{calendar-mayan-next-calendar-round-date}).
-@item g m p c
-Move to the previous occurrence of a place in the
-calendar round (@code{calendar-mayan-previous-calendar-round-date}).
-@end table
-
-@cindex Mayan long count
- To understand these commands, you need to understand the Mayan calendars.
-The @dfn{long count} is a counting of days with these units:
-
-@display
-1 kin = 1 day@ @ @ 1 uinal = 20 kin@ @ @ 1 tun = 18 uinal
-1 katun = 20 tun@ @ @ 1 baktun = 20 katun
-@end display
-
-@kindex g m @r{(Calendar mode)}
-@findex calendar-mayan-goto-long-count-date
-@noindent
-Thus, the long count date 12.16.11.16.6 means 12 baktun, 16 katun, 11
-tun, 16 uinal, and 6 kin. The Emacs calendar can handle Mayan long
-count dates as early as 7.17.18.13.3, but no earlier. When you use the
-@kbd{g m l} command, type the Mayan long count date with the baktun,
-katun, tun, uinal, and kin separated by periods.
-
-@findex calendar-mayan-previous-tzolkin-date
-@findex calendar-mayan-next-tzolkin-date
-@cindex Mayan tzolkin calendar
- The Mayan tzolkin calendar is a cycle of 260 days formed by a pair of
-independent cycles of 13 and 20 days. Since this cycle repeats
-endlessly, Emacs provides commands to move backward and forward to the
-previous or next point in the cycle. Type @kbd{g m p t} to go to the
-previous tzolkin date; Emacs asks you for a tzolkin date and moves point
-to the previous occurrence of that date. Similarly, type @kbd{g m n t}
-to go to the next occurrence of a tzolkin date.
-
-@findex calendar-mayan-previous-haab-date
-@findex calendar-mayan-next-haab-date
-@cindex Mayan haab calendar
- The Mayan haab calendar is a cycle of 365 days arranged as 18 months
-of 20 days each, followed by a 5-day monthless period. Like the tzolkin
-cycle, this cycle repeats endlessly, and there are commands to move
-backward and forward to the previous or next point in the cycle. Type
-@kbd{g m p h} to go to the previous haab date; Emacs asks you for a haab
-date and moves point to the previous occurrence of that date.
-Similarly, type @kbd{g m n h} to go to the next occurrence of a haab
-date.
-
-@c This is omitted because it is too long for smallbook format.
-@c @findex calendar-mayan-previous-calendar-round-date
-@findex calendar-mayan-next-calendar-round-date
-@cindex Mayan calendar round
- The Maya also used the combination of the tzolkin date and the haab
-date. This combination is a cycle of about 52 years called a
-@emph{calendar round}. If you type @kbd{g m p c}, Emacs asks you for
-both a haab and a tzolkin date and then moves point to the previous
-occurrence of that combination. Use @kbd{g m n c} to move point to the
-next occurrence of a combination. These commands signal an error if the
-haab/tzolkin date combination you have typed is impossible.
-
- Emacs uses strict completion (@pxref{Completion Exit}) whenever it
-asks you to type a Mayan name, so you don't have to worry about
-spelling.
-
@node Diary
@section The Diary
@cindex diary
diff --git a/doc/emacs/custom.texi b/doc/emacs/custom.texi
index 45fa45191f3..f3e07fd8ba0 100644
--- a/doc/emacs/custom.texi
+++ b/doc/emacs/custom.texi
@@ -1166,7 +1166,10 @@ conversion of this file. @xref{Coding Systems}.
@item
@code{unibyte} says to load or compile a file of Emacs Lisp in unibyte
-mode, if the value is @code{t}. @xref{Disabling Multibyte}.
+mode, if the value is @code{t}. @xref{Disabling Multibyte, ,
+Disabling Multibyte Characters, elisp, GNU Emacs Lisp Reference
+Manual}.
+
@end itemize
@noindent
diff --git a/doc/emacs/emacs.texi b/doc/emacs/emacs.texi
index e2d0b0eebf6..8a518b82abb 100644
--- a/doc/emacs/emacs.texi
+++ b/doc/emacs/emacs.texi
@@ -544,7 +544,6 @@ Frames and Graphical Displays
International Character Set Support
* International Chars:: Basic concepts of multibyte characters.
-* Disabling Multibyte:: Controlling whether to use multibyte characters.
* Language Environments:: Setting things up for the language you use.
* Input Methods:: Entering text characters not on your keyboard.
* Select Input Method:: Specifying your choice of input methods.
@@ -798,6 +797,7 @@ Version Control
* Old Revisions:: Examining and comparing old versions.
* VC Change Log:: Viewing the VC Change Log.
* VC Undo:: Canceling changes before or after committing.
+* VC Ignore:: Ignore files under version control system.
* VC Directory Mode:: Listing files managed by version control.
* Branches:: Multiple lines of development.
@ifnottex
@@ -956,7 +956,6 @@ Conversion To and From Other Calendars
(aside from Gregorian).
* To Other Calendar:: Converting the selected date to various calendars.
* From Other Calendar:: Moving to a date specified in another calendar.
-* Mayan Calendar:: Moving to a date specified in a Mayan calendar.
The Diary
@@ -971,6 +970,7 @@ More advanced features of the Calendar and Diary
* Calendar Customizing:: Calendar layout and hooks.
* Holiday Customizing:: Defining your own holidays.
+* Mayan Calendar:: Moving to a date specified in a Mayan calendar.
* Date Display Format:: Changing the format.
* Time Display Format:: Changing the format.
* Diary Customizing:: Defaults you can set.
diff --git a/doc/emacs/macos.texi b/doc/emacs/macos.texi
index 4483c91802d..61c056ceb4b 100644
--- a/doc/emacs/macos.texi
+++ b/doc/emacs/macos.texi
@@ -40,13 +40,16 @@ Emacs provides a set of key bindings using this modifier key that mimic
other Mac / GNUstep applications (@pxref{Mac / GNUstep Events}). You
can change these bindings in the usual way (@pxref{Key Bindings}).
-@c FIXME mention ns-alternate-modifier?
+@vindex ns-alternate-modifier
+@vindex ns-right-alternate-modifier
The variable @code{ns-right-alternate-modifier} controls the
behavior of the right @key{alt} and @key{option} keys. These keys
behave like the left-hand keys if the value is @code{left} (the
default). A value of @code{control}, @code{meta}, @code{alt},
@code{super}, or @code{hyper} makes them behave like the corresponding
-modifier keys; a value of @code{none} tells Emacs to ignore them.
+modifier keys; a value to @code{left} means be the same key as
+@code{ns-alternate-modifier}; a value of @code{none} tells Emacs to
+ignore them.
@kbd{S-Mouse-1} adjusts the region to the click position,
just like @kbd{Mouse-3} (@code{mouse-save-then-kill}); it does not pop
diff --git a/doc/emacs/maintaining.texi b/doc/emacs/maintaining.texi
index 6184684fbb0..553375442d5 100644
--- a/doc/emacs/maintaining.texi
+++ b/doc/emacs/maintaining.texi
@@ -1,4 +1,4 @@
-@c This is part of the Emacs manual.
+@c This is part of the Emacs manual., Abbrevs, This is part of the Emacs manual., Top
@c Copyright (C) 1985-1987, 1993-1995, 1997, 1999-2013 Free Software
@c Foundation, Inc.
@c See file emacs.texi for copying conditions.
@@ -56,6 +56,7 @@ variable @code{vc-handled-backends} to @code{nil}
* Old Revisions:: Examining and comparing old versions.
* VC Change Log:: Viewing the VC Change Log.
* VC Undo:: Canceling changes before or after committing.
+* VC Ignore:: Ignore files under version control system.
* VC Directory Mode:: Listing files managed by version control.
* Branches:: Multiple lines of development.
@ifnottex
@@ -1032,6 +1033,23 @@ unlocked; you must lock again to resume editing. You can also use
@kbd{C-x v u} to unlock a file if you lock it and then decide not to
change it.
+@node VC Ignore
+@subsection Ignore Version Control Files
+
+@table @kbd
+@item C-x v G
+Ignore a file under current version control system. (@code{vc-ignore}).
+@end table
+
+@kindex C-x v G
+@findex vc-ignore
+ Many source trees contain some files that do not need to be versioned,
+such as editor backups, object or bytecode files, and built programs.
+You can simply not add them, but then they’ll always crop up as
+unknown files. You can also tell the version control system to ignore
+these files by adding them to the ignore file at the top of the tree.
+@kbd{C-x v G} (@code{vc-ignore}) can help you do this.
+
@node VC Directory Mode
@subsection VC Directory Mode
@@ -1222,7 +1240,7 @@ Revisions}), and @w{@kbd{C-x v u}} (@pxref{VC Undo}).
The VC Directory buffer also defines some single-key shortcuts for
VC commands with the @kbd{C-x v} prefix: @kbd{=}, @kbd{+}, @kbd{l},
-@kbd{i}, @kbd{D}, @kbd{L} and @kbd{v}.
+@kbd{i}, @kbd{D}, @kbd{L}, @kbd{G} and @kbd{v}.
For example, you can commit a set of edited files by opening a VC
Directory buffer, where the files are listed with the @samp{edited}
diff --git a/doc/emacs/mule.texi b/doc/emacs/mule.texi
index c8bd5027fa0..ebddc46be94 100644
--- a/doc/emacs/mule.texi
+++ b/doc/emacs/mule.texi
@@ -90,7 +90,6 @@ value to make sure Emacs interprets keyboard input correctly; see
@menu
* International Chars:: Basic concepts of multibyte characters.
-* Disabling Multibyte:: Controlling whether to use multibyte characters.
* Language Environments:: Setting things up for the language you use.
* Input Methods:: Entering text characters not on your keyboard.
* Select Input Method:: Specifying your choice of input methods.
@@ -244,79 +243,6 @@ Character code properties: customize what to show
decomposition: (65 768) ('A' '`')
@end smallexample
-@c FIXME? Does this section even belong in the user manual?
-@c Seems more appropriate to the lispref?
-@node Disabling Multibyte
-@section Disabling Multibyte Characters
-
- By default, Emacs starts in multibyte mode: it stores the contents
-of buffers and strings using an internal encoding that represents
-non-@acronym{ASCII} characters using multi-byte sequences. Multibyte
-mode allows you to use all the supported languages and scripts without
-limitations.
-
-@cindex turn multibyte support on or off
- Under very special circumstances, you may want to disable multibyte
-character support, for a specific buffer.
-When multibyte characters are disabled in a buffer, we call
-that @dfn{unibyte mode}. In unibyte mode, each character in the
-buffer has a character code ranging from 0 through 255 (0377 octal); 0
-through 127 (0177 octal) represent @acronym{ASCII} characters, and 128
-(0200 octal) through 255 (0377 octal) represent non-@acronym{ASCII}
-characters.
-
- To edit a particular file in unibyte representation, visit it using
-@code{find-file-literally}. @xref{Visiting}. You can convert a
-multibyte buffer to unibyte by saving it to a file, killing the
-buffer, and visiting the file again with @code{find-file-literally}.
-Alternatively, you can use @kbd{C-x @key{RET} c}
-(@code{universal-coding-system-argument}) and specify @samp{raw-text}
-as the coding system with which to visit or save a file. @xref{Text
-Coding}. Unlike @code{find-file-literally}, finding a file as
-@samp{raw-text} doesn't disable format conversion, uncompression, or
-auto mode selection.
-
-@c Not a single file in Emacs uses this feature. Is it really worth
-@c mentioning in the _user_ manual? Also, this duplicates somewhat
-@c "Loading Non-ASCII" from the lispref.
-@cindex Lisp files, and multibyte operation
-@cindex multibyte operation, and Lisp files
-@cindex unibyte operation, and Lisp files
-@cindex init file, and non-@acronym{ASCII} characters
- Emacs normally loads Lisp files as multibyte.
-This includes the Emacs initialization
-file, @file{.emacs}, and the initialization files of packages
-such as Gnus. However, you can specify unibyte loading for a
-particular Lisp file, by adding an entry @samp{coding: raw-text} in a file
-local variables section. @xref{Specify Coding}.
-Then that file is always loaded as unibyte text.
-@ignore
-@c I don't see the point of this statement:
-The motivation for these conventions is that it is more reliable to
-always load any particular Lisp file in the same way.
-@end ignore
-You can also load a Lisp file as unibyte, on any one occasion, by
-typing @kbd{C-x @key{RET} c raw-text @key{RET}} immediately before
-loading it.
-
-@c See http://debbugs.gnu.org/11226 for lack of unibyte tooltip.
-@vindex enable-multibyte-characters
-The buffer-local variable @code{enable-multibyte-characters} is
-non-@code{nil} in multibyte buffers, and @code{nil} in unibyte ones.
-The mode line also indicates whether a buffer is multibyte or not.
-@xref{Mode Line}. With a graphical display, in a multibyte buffer,
-the portion of the mode line that indicates the character set has a
-tooltip that (amongst other things) says that the buffer is multibyte.
-In a unibyte buffer, the character set indicator is absent. Thus, in
-a unibyte buffer (when using a graphical display) there is normally
-nothing before the indication of the visited file's end-of-line
-convention (colon, backslash, etc.), unless you are using an input
-method.
-
-@findex toggle-enable-multibyte-characters
-You can turn off multibyte support in a specific buffer by invoking the
-command @code{toggle-enable-multibyte-characters} in that buffer.
-
@node Language Environments
@section Language Environments
@cindex language environments
@@ -919,18 +845,6 @@ pattern, are decoded correctly.
Unlike the previous two, this variable does not override any
@samp{-*-coding:-*-} tag.
-@c FIXME? This seems somewhat out of place. Move to the Rmail section?
-@vindex rmail-file-coding-system
- When you get new mail in Rmail, each message is translated
-automatically from the coding system it is written in, as if it were a
-separate file. This uses the priority list of coding systems that you
-have specified. If a MIME message specifies a character set, Rmail
-obeys that specification. For reading and saving Rmail files
-themselves, Emacs uses the coding system specified by the variable
-@code{rmail-file-coding-system}. The default value is @code{nil},
-which means that Rmail files are not translated (they are read and
-written in the Emacs internal character code).
-
@node Specify Coding
@section Specifying a File's Coding System
@@ -1591,15 +1505,13 @@ the range 0240 to 0377 octal (160 to 255 decimal) to handle the
accented letters and punctuation needed by various European languages
(and some non-European ones). Note that Emacs considers bytes with
codes in this range as raw bytes, not as characters, even in a unibyte
-buffer, i.e., if you disable multibyte characters. However, Emacs
-can still handle these character codes as if they belonged to
-@emph{one} of the single-byte character sets at a time. To specify
-@emph{which} of these codes to use, invoke @kbd{M-x
-set-language-environment} and specify a suitable language environment
-such as @samp{Latin-@var{n}}.
-
- For more information about unibyte operation, see
-@ref{Disabling Multibyte}.
+buffer, i.e., if you disable multibyte characters. However, Emacs can
+still handle these character codes as if they belonged to @emph{one}
+of the single-byte character sets at a time. To specify @emph{which}
+of these codes to use, invoke @kbd{M-x set-language-environment} and
+specify a suitable language environment such as @samp{Latin-@var{n}}.
+@xref{Disabling Multibyte, , Disabling Multibyte Characters, elisp,
+GNU Emacs Lisp Reference Manual}.
@vindex unibyte-display-via-language-environment
Emacs can also display bytes in the range 160 to 255 as readable
diff --git a/doc/emacs/rmail.texi b/doc/emacs/rmail.texi
index 62f35b2ee83..67afc29a277 100644
--- a/doc/emacs/rmail.texi
+++ b/doc/emacs/rmail.texi
@@ -1274,6 +1274,17 @@ It reads the name of a coding system, and then redecodes the message
using the coding system you specified. If you specified the right
coding system, the result should be readable.
+@vindex rmail-file-coding-system
+ When you get new mail in Rmail, each message is translated
+automatically from the coding system it is written in, as if it were a
+separate file. This uses the priority list of coding systems that you
+have specified. If a MIME message specifies a character set, Rmail
+obeys that specification. For reading and saving Rmail files
+themselves, Emacs uses the coding system specified by the variable
+@code{rmail-file-coding-system}. The default value is @code{nil},
+which means that Rmail files are not translated (they are read and
+written in the Emacs internal character code).
+
@node Rmail Editing
@section Editing Within a Message
diff --git a/doc/lispintro/ChangeLog b/doc/lispintro/ChangeLog
index 4182b6a3184..481eb0c9db8 100644
--- a/doc/lispintro/ChangeLog
+++ b/doc/lispintro/ChangeLog
@@ -1,3 +1,7 @@
+2013-08-02 Xue Fuqiao <xfq.free@gmail.com>
+
+ * emacs-lisp-intro.texi (zap-to-char): Remove obsolete stuff.
+
2013-07-06 Glenn Morris <rgm@gnu.org>
* emacs-lisp-intro.texi (Top):
diff --git a/doc/lispintro/emacs-lisp-intro.texi b/doc/lispintro/emacs-lisp-intro.texi
index dafee51a020..f0d9ab63935 100644
--- a/doc/lispintro/emacs-lisp-intro.texi
+++ b/doc/lispintro/emacs-lisp-intro.texi
@@ -7537,20 +7537,7 @@ retrieved. @xref{Yanking, , Yanking Text Back}.
@section @code{zap-to-char}
@findex zap-to-char
-@c FIXME remove obsolete stuff
-The @code{zap-to-char} function changed little between GNU Emacs
-version 19 and GNU Emacs version 22. However, @code{zap-to-char}
-calls another function, @code{kill-region}, which enjoyed a major
-rewrite.
-
-The @code{kill-region} function in Emacs 19 is complex, but does not
-use code that is important at this time. We will skip it.
-
-The @code{kill-region} function in Emacs 22 is easier to read than the
-same function in Emacs 19 and introduces a very important concept,
-that of error handling. We will walk through the function.
-
-But first, let us look at the interactive @code{zap-to-char} function.
+Let us look at the interactive @code{zap-to-char} function.
@menu
* Complete zap-to-char:: The complete implementation.
diff --git a/doc/lispref/ChangeLog b/doc/lispref/ChangeLog
index 38262f05355..d77ede29da1 100644
--- a/doc/lispref/ChangeLog
+++ b/doc/lispref/ChangeLog
@@ -1,3 +1,20 @@
+2013-08-02 Xue Fuqiao <xfq.free@gmail.com>
+
+ * display.texi (Face Functions): Add an index.
+
+ * variables.texi (Variable Aliases): Add an index.
+
+ * functions.texi (Defining Functions): Add an index.
+
+ * nonascii.texi (Coding System Basics): Add an index.
+
+2013-07-31 Xue Fuqiao <xfq.free@gmail.com>
+
+ * nonascii.texi (Non-ASCII Characters): Update menu.
+ (Disabling Multibyte): Move here from doc/emacs/mule.texi. Fix cross-references.
+
+ * elisp.texi (Top): Update menu.
+
2013-07-30 Xue Fuqiao <xfq.free@gmail.com>
* windows.texi (Window History): Mention the default value of
diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index 44fbc66a60e..c5068425c66 100644
--- a/doc/lispref/display.texi
+++ b/doc/lispref/display.texi
@@ -2738,6 +2738,7 @@ differently from the default face.
@end defun
@cindex face alias
+@cindex alias, for faces
A @dfn{face alias} provides an equivalent name for a face. You can
define a face alias by giving the alias symbol the @code{face-alias}
property, with a value of the target face name. The following example
diff --git a/doc/lispref/elisp.texi b/doc/lispref/elisp.texi
index 4b8cc36b4ea..230da1867dd 100644
--- a/doc/lispref/elisp.texi
+++ b/doc/lispref/elisp.texi
@@ -1194,6 +1194,7 @@ Text Properties
Non-@acronym{ASCII} Characters
* Text Representations:: How Emacs represents text.
+* Disabling Multibyte:: Controlling whether to use multibyte characters.
* Converting Representations:: Converting unibyte to multibyte and vice versa.
* Selecting a Representation:: Treating a byte sequence as unibyte or multi.
* Character Codes:: How unibyte and multibyte relate to
diff --git a/doc/lispref/functions.texi b/doc/lispref/functions.texi
index fcd345ef83b..39a9ff6b62c 100644
--- a/doc/lispref/functions.texi
+++ b/doc/lispref/functions.texi
@@ -580,6 +580,7 @@ redefinition from unintentional redefinition.
@end defmac
@cindex function aliases
+@cindex alias, for functions
@defun defalias name definition &optional doc
@anchor{Definition of defalias}
This function defines the symbol @var{name} as a function, with
diff --git a/doc/lispref/nonascii.texi b/doc/lispref/nonascii.texi
index b8b62325bb4..090310c5545 100644
--- a/doc/lispref/nonascii.texi
+++ b/doc/lispref/nonascii.texi
@@ -13,6 +13,7 @@ how they are stored in strings and buffers.
@menu
* Text Representations:: How Emacs represents text.
+* Disabling Multibyte:: Controlling whether to use multibyte characters.
* Converting Representations:: Converting unibyte to multibyte and vice versa.
* Selecting a Representation:: Treating a byte sequence as unibyte or multi.
* Character Codes:: How unibyte and multibyte relate to
@@ -140,6 +141,55 @@ This function concatenates all its argument @var{bytes} and makes the
result a unibyte string.
@end defun
+@node Disabling Multibyte
+@section Disabling Multibyte Characters
+@cindex disabling multibyte
+
+ By default, Emacs starts in multibyte mode: it stores the contents
+of buffers and strings using an internal encoding that represents
+non-@acronym{ASCII} characters using multi-byte sequences. Multibyte
+mode allows you to use all the supported languages and scripts without
+limitations.
+
+@cindex turn multibyte support on or off
+ Under very special circumstances, you may want to disable multibyte
+character support, for a specific buffer.
+When multibyte characters are disabled in a buffer, we call
+that @dfn{unibyte mode}. In unibyte mode, each character in the
+buffer has a character code ranging from 0 through 255 (0377 octal); 0
+through 127 (0177 octal) represent @acronym{ASCII} characters, and 128
+(0200 octal) through 255 (0377 octal) represent non-@acronym{ASCII}
+characters.
+
+ To edit a particular file in unibyte representation, visit it using
+@code{find-file-literally}. @xref{Visiting Functions}. You can
+convert a multibyte buffer to unibyte by saving it to a file, killing
+the buffer, and visiting the file again with
+@code{find-file-literally}. Alternatively, you can use @kbd{C-x
+@key{RET} c} (@code{universal-coding-system-argument}) and specify
+@samp{raw-text} as the coding system with which to visit or save a
+file. @xref{Text Coding, , Specifying a Coding System for File Text,
+emacs, GNU Emacs Manual}. Unlike @code{find-file-literally}, finding
+a file as @samp{raw-text} doesn't disable format conversion,
+uncompression, or auto mode selection.
+
+@c See http://debbugs.gnu.org/11226 for lack of unibyte tooltip.
+@vindex enable-multibyte-characters
+The buffer-local variable @code{enable-multibyte-characters} is
+non-@code{nil} in multibyte buffers, and @code{nil} in unibyte ones.
+The mode line also indicates whether a buffer is multibyte or not.
+With a graphical display, in a multibyte buffer, the portion of the
+mode line that indicates the character set has a tooltip that (amongst
+other things) says that the buffer is multibyte. In a unibyte buffer,
+the character set indicator is absent. Thus, in a unibyte buffer
+(when using a graphical display) there is normally nothing before the
+indication of the visited file's end-of-line convention (colon,
+backslash, etc.), unless you are using an input method.
+
+@findex toggle-enable-multibyte-characters
+You can turn off multibyte support in a specific buffer by invoking the
+command @code{toggle-enable-multibyte-characters} in that buffer.
+
@node Converting Representations
@section Converting Text Representations
@@ -962,6 +1012,7 @@ The value of the @code{:mime-charset} property is also defined
as an alias for the coding system.
@end defun
+@cindex alias, for coding systems
@defun coding-system-aliases coding-system
This function returns the list of aliases of @var{coding-system}.
@end defun
diff --git a/doc/lispref/variables.texi b/doc/lispref/variables.texi
index 4a38fa9ccd5..557add738ba 100644
--- a/doc/lispref/variables.texi
+++ b/doc/lispref/variables.texi
@@ -1838,6 +1838,7 @@ updates this list.
@node Variable Aliases
@section Variable Aliases
@cindex variable aliases
+@cindex alias, for variables
It is sometimes useful to make two variables synonyms, so that both
variables always have the same value, and changing either one also
diff --git a/doc/misc/ChangeLog b/doc/misc/ChangeLog
index 9b45ac06f4c..7f5c70e07e3 100644
--- a/doc/misc/ChangeLog
+++ b/doc/misc/ChangeLog
@@ -1,3 +1,8 @@
+2013-08-01 Lars Magne Ingebrigtsen <larsi@gnus.org>
+
+ * gnus.texi (Basic Usage): Mention that warp means jump here.
+ (The notmuch Engine): Mention notmuch.
+
2013-07-30 Tassilo Horn <tsdh@gnu.org>
* gnus.texi (Sorting the Summary Buffer): Document new defcustom
diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi
index 808bd2b114b..4edc1d62f1a 100644
--- a/doc/misc/gnus.texi
+++ b/doc/misc/gnus.texi
@@ -21109,17 +21109,17 @@ the articles that match this query, and takes you to a summary buffer
showing these articles. Articles may then be read, moved and deleted
using the usual commands.
-The @code{nnir} group made in this way is an @code{ephemeral} group, and
-some changes are not permanent: aside from reading, moving, and
+The @code{nnir} group made in this way is an @code{ephemeral} group,
+and some changes are not permanent: aside from reading, moving, and
deleting, you can't act on the original article. But there is an
-alternative: you can @emph{warp} to the original group for the article
-on the current line with @kbd{A W}, aka
+alternative: you can @emph{warp} (i.e., jump) to the original group
+for the article on the current line with @kbd{A W}, aka
@code{gnus-warp-to-article}. Even better, the function
-@code{gnus-summary-refer-thread}, bound by default in summary buffers to
-@kbd{A T}, will first warp to the original group before it works its
-magic and includes all the articles in the thread. From here you can
-read, move and delete articles, but also copy them, alter article marks,
-whatever. Go nuts.
+@code{gnus-summary-refer-thread}, bound by default in summary buffers
+to @kbd{A T}, will first warp to the original group before it works
+its magic and includes all the articles in the thread. From here you
+can read, move and delete articles, but also copy them, alter article
+marks, whatever. Go nuts.
You say you want to search more than just the group on the current line?
No problem: just process-mark the groups you want to search. You want
@@ -21161,6 +21161,7 @@ query language anyway.
* The swish++ Engine:: Swish++ configuration and usage.
* The swish-e Engine:: Swish-e configuration and usage.
* The namazu Engine:: Namazu configuration and usage.
+* The notmuch Engine:: Notmuch configuration and usage.
* The hyrex Engine:: Hyrex configuration and usage.
* Customizations:: User customizable settings.
@end menu
@@ -21390,6 +21391,26 @@ mknmz --mailnews ~/Mail/archive/ ~/Mail/mail/ ~/Mail/lists/
For maximum searching efficiency you might want to have a cron job run
this command periodically, say every four hours.
+
+@node The notmuch Engine
+@subsubsection The notmuch Engine
+
+@table @code
+@item nnir-notmuch-program
+The name of the notmuch search executable. Defaults to
+@samp{notmuch}.
+
+@item nnir-notmuch-additional-switches
+A list of strings, to be given as additional arguments to notmuch.
+
+@item nnir-notmuch-remove-prefix
+The prefix to remove from each file name returned by notmuch in order
+to get a group name (albeit with @samp{/} instead of @samp{.}). This
+is a regular expression.
+
+@end table
+
+
@node The hyrex Engine
@subsubsection The hyrex Engine
This engine is obsolete.
diff --git a/etc/ChangeLog b/etc/ChangeLog
index c201772cd93..4c0535d07a0 100644
--- a/etc/ChangeLog
+++ b/etc/ChangeLog
@@ -1,3 +1,27 @@
+2013-08-03 Juanma Barranquero <lekktu@gmail.com>
+
+ * NEWS: Document new package frameset.el.
+
+2013-08-03 Xue Fuqiao <xfq.free@gmail.com>
+
+ * TODO: Adjust entry about bug reporting.
+
+2013-08-02 Bastien Guerry <bzg@gnu.org>
+
+ * DEVEL.HUMOR: New entry.
+
+2013-08-02 Xue Fuqiao <xfq.free@gmail.com>
+
+ * tutorials/TUTORIAL: Remove a redundant sentence about yanking.
+
+ * tutorials/TUTORIAL.cn: Update; synchronize with TUTORIAL.
+
+ * tutorials/TUTORIAL.translators (Maintainer): Update the maintainer.
+
+2013-08-02 Juanma Barranquero <lekktu@gmail.com>
+
+ * tutorials/TUTORIAL.es: Fix typos (bug#15000).
+
2013-07-26 Micah Anderson <micah@riseup.net> (tiny change)
* spook.lines: Additions. (Bug#14658)
diff --git a/etc/DEVEL.HUMOR b/etc/DEVEL.HUMOR
index 091c267579b..7521f7950b1 100644
--- a/etc/DEVEL.HUMOR
+++ b/etc/DEVEL.HUMOR
@@ -194,3 +194,11 @@ drivers?"
depression or loneliness when it is left out of the picture, so I
wouldn't worry about it too much."
-- Lennart Borgman and Jason Rumney
+
+----------------------------------------------------------------------
+
+ "... a non-CS-educated guy like me ..."
+
+ "Kind of late, but thanks for letting us know. I've just revoked your
+ write access to the repository for the obvious safety reasons,"
+ -- Bastien Guerry and Stefan Monnier
diff --git a/etc/NEWS b/etc/NEWS
index 1cd444e6455..60a846b459f 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -233,11 +233,16 @@ The default separator is changed to allow surrounding spaces around the comma.
*** New variable `diary-from-outlook-function', used by the command
`diary-from-outlook'.
-** VC Directory Mode
+** VC and related modes
+
+*** In VC directory mode, `D' displays diffs between VC-controlled
+whole tree revisions.
+
+*** In VC directory mode, `L' lists the change log for the current VC
+controlled tree in a window.
-*** `D' displays diffs between VC-controlled whole tree revisions.
-*** `L' lists the change log for the current VC controlled tree in a window.
-*** `I' ignores the file under current version control system.
+*** `C-x v G' (globally) and `G' (in VC directory mode) ignores a
+file under current version control system.
** cl-lib
@@ -269,8 +274,8 @@ auto-saves of the desktop.
*** `desktop-restore-frames', enabled by default, allows saving and
restoring the window/frame configuration. Additional options
-`desktop-restore-in-current-display' and
-`desktop-restoring-reuses-frames' allow further customization.
+`desktop-restore-in-current-display', `desktop-restore-reuses-frames'
+and `desktop-restore-forces-onscreen' allow further customization.
** Dired
@@ -511,6 +516,12 @@ It is layered as:
- advice-add/advice-remove to add/remove a piece of advice on a named function,
much like `defadvice' does.
+** New frameset.el package.
+It provides a set of operations to save a frameset (the state of all
+or a subset of the existing frames and windows, somewhat similar to a
+frame configuration), both in-session and persistently, and restore it
+at some point in the future.
+
+++
** The package filenotify.el provides an interface for file system
notifications. It requires, that Emacs is compiled with one of the
@@ -519,6 +530,8 @@ low-level libraries gfilenotify.c, inotify.c or w32notify.c.
* Incompatible Lisp Changes in Emacs 24.4
+** `defvar' and `defcustom' in a let-binding affect the "external" default.
+
** The syntax of ?» and ?« is now punctuation instead of matched parens.
Some languages match those as »...« and others as «...» so better stay neutral.
diff --git a/etc/TODO b/etc/TODO
index faa9fc4c98d..305722dfe7b 100644
--- a/etc/TODO
+++ b/etc/TODO
@@ -176,6 +176,15 @@ where <device> is the network device found under the first key.
** Check for any included packages that define obsolete bug-reporting commands.
Change them to use report-emacs-bug.
+*** Related functions:
+**** gnus-bug
+**** report-calc-bug
+**** org-submit-bug-report
+**** lm-report-bug
+**** tramp-bug
+**** c-submit-bug-report
+**** ffap-bug and ffap-submit-bug (obsoleted)
+[Do all of them need changing?]
** Allow fringe indicators to display a tooltip (provide a help-echo property?)
diff --git a/etc/tutorials/TUTORIAL b/etc/tutorials/TUTORIAL
index 91962fd722c..91b3731fd0d 100644
--- a/etc/tutorials/TUTORIAL
+++ b/etc/tutorials/TUTORIAL
@@ -372,13 +372,15 @@ the text between the two positions.
The difference between "killing" and "deleting" is that "killed" text
can be reinserted (at any position), whereas "deleted" things cannot
-be reinserted in this way (you can, however, undo a deletion--see below).
-Reinsertion of killed text is called "yanking". Generally, the
-commands that can remove a lot of text kill the text (they are set up so
-that you can yank the text), while the commands that remove just one
-character, or only remove blank lines and spaces, do deletion (so you
-cannot yank that text). <DEL> and C-d do deletion in the simplest
-case, with no argument. When given an argument, they kill instead.
+be reinserted in this way (you can, however, undo a deletion--see
+below). Reinsertion of killed text is called "yanking". (Think of it
+as yanking back, or pulling back, some text that was taken away.)
+Generally, the commands that can remove a lot of text kill the text
+(they are set up so that you can yank the text), while the commands
+that remove just one character, or only remove blank lines and spaces,
+do deletion (so you cannot yank that text). <DEL> and C-d do deletion
+in the simplest case, with no argument. When given an argument, they
+kill instead.
>> Move the cursor to the beginning of a line which is not empty.
Then type C-k to kill the text on that line.
@@ -391,13 +393,12 @@ treats a numeric argument specially: it kills that many lines AND
their contents. This is not mere repetition. C-u 2 C-k kills two
lines and their newlines; typing C-k twice would not do that.
-Reinserting killed text is called "yanking". (Think of it as yanking
-back, or pulling back, some text that was taken away.) You can yank
-the killed text either at the same place where it was killed, or at
-some other place in the text you are editing, or even in a different
-file. You can yank the same text several times; that makes multiple
-copies of it. Some other editors call killing and yanking "cutting"
-and "pasting" (see the Glossary in the Emacs manual).
+You can yank the killed text either at the same place where it was
+killed, or at some other place in the text you are editing, or even in
+a different file. You can yank the same text several times; that
+makes multiple copies of it. Some other editors call killing and
+yanking "cutting" and "pasting" (see the Glossary in the Emacs
+manual).
The command for yanking is C-y. It reinserts the last killed text,
at the current cursor position.
diff --git a/etc/tutorials/TUTORIAL.cn b/etc/tutorials/TUTORIAL.cn
index 7c02d06defa..faf049b0af3 100644
--- a/etc/tutorials/TUTORIAL.cn
+++ b/etc/tutorials/TUTORIAL.cn
@@ -14,8 +14,9 @@ META 键(有时候用 EDIT 或 ALT æ¥æ ‡ç¤ºï¼‰ã€‚为了é¿å…æ¯æ¬¡éƒ½è¦å†™å
先按一下 ESC é”®ç„¶åŽæ”¾å¼€ï¼Œå†è¾“å…¥ <chr>。我们用 <ESC> æ¥è¡¨ç¤º
ESC 键。
-é‡è¦æç¤ºï¼šè¦é€€å‡º Emacs,请用 C-x C-c(两个连续的组åˆé”®ï¼‰ã€‚下文中左边顶
-行的“>>â€å­—æ ·ç”¨æ¥æç¤ºä½ å°è¯•键盘命令。比如:
+é‡è¦æç¤ºï¼šè¦é€€å‡º Emacs,请用 C-x C-c(两个连续的组åˆé”®ï¼‰ã€‚
+è¦é€€å‡ºä¸€ä¸ªæ­£åœ¨è¿è¡Œä¸­çš„命令,请用 C-g。
+下文中左边顶行的“>>â€å­—æ ·ç”¨æ¥æç¤ºä½ å°è¯•键盘命令。比如:
<<Blank lines inserted around following line by help-with-tutorial>>
[本页当中特æ„留出一些空白是出于教学目的,请继续往åŽé˜…读]
>> 现在输入 C-v ï¼ˆæŸ¥çœ‹ä¸‹ä¸€å±æ–‡å­—)移动到下一å±ã€‚
@@ -43,7 +44,9 @@ METAã€EDIT 或 ALT 键那么就先按 <ESC> 冿Œ‰ v)。
ï¼ˆæ³¨æ„æ˜¯ CONTROL-Lï¼Œä¸æ˜¯ CONTROL-1)
>> 找到光标,留æ„其附近的文字,然åŽè¾“å…¥ C-l。
- 找找光标在哪里,你会å‘现其附近的文字并没有å˜åŒ–。
+ 找找光标在哪里,你会å‘现其附近的文字与之å‰ç›¸åŒï¼Œä½ç½®å´å˜ä¸ºå±å¹•的中心。
+ å¦‚æžœä½ å†æ¬¡è¾“å…¥ C-l ,附近的文字将移动到å±å¹•çš„é¡¶ç«¯ã€‚å†æ¬¡è¾“å…¥ C-l ,
+ 文字将移动到底端。
如果你的键盘上有 PageUp å’Œ PageDn,也å¯ä»¥ç”¨è¿™ä¸¤ä¸ªé”®æ¥æ»šå±ã€‚ä¸è¿‡ä½¿ç”¨
C-v å’Œ M-v çš„æ•ˆçŽ‡è¦æ›´é«˜ä¸€äº›ã€‚
@@ -78,8 +81,8 @@ P 代表 previous(上一行),N 代表 next(下一行),B 代表 backw
>> 用 C-f 把光标移动到这一行,然åŽå†ç”¨ C-p 往上挪。
注æ„观察当光标在一行的中央时 C-p 命令的行为。
-æ¯è¡Œæ–‡å­—都以一个“æ¢è¡Œç¬¦â€ç»“æŸï¼Œâ€œæ¢è¡Œç¬¦â€æŠŠè¡Œä¸Žè¡ŒåŒºåˆ†å¼€æ¥ã€‚文件的最åŽ
-一行也应该也有一个æ¢è¡Œç¬¦ï¼ˆä¸è¿‡ Emacs å¹¶ä¸å¼ºåˆ¶è¦æ±‚这一点)。
+æ¯è¡Œæ–‡å­—都以一个“æ¢è¡Œç¬¦â€ç»“æŸï¼Œâ€œæ¢è¡Œç¬¦â€æŠŠè¡Œä¸Žè¡ŒåŒºåˆ†å¼€æ¥ã€‚(通常情况下,
+一个文件的最åŽä¸€è¡Œä¼šæœ‰ä¸€ä¸ªæ¢è¡Œç¬¦ï¼Œä½†æ˜¯ Emacs ä¸å¼ºåˆ¶è¦æ±‚这一点。)
>> 在一行的行头输入 C-b。
光标应该会移动到å‰ä¸€è¡Œçš„行尾,因为光标在回退过程中越过了æ¢è¡Œç¬¦ã€‚
@@ -179,27 +182,20 @@ EDIT 或 ALT)键,那么还有å¦ä¸€ç§åŠžæ³•ï¼šæŒ‰ä½ META 键䏿”¾ï¼Œç„¶å
标志――åªè¦ç»™å‡ºæœ‰ä¸€ä¸ªå‰ç¼€å‚数,ä¸ç®¡å…¶å€¼ä¸ºä½•,它都会改å˜å‘½ä»¤çš„功能。
而 C-v å’Œ M-v 则属于å¦ä¸€ç§ç±»åž‹çš„ä¾‹å¤–ã€‚å½“ç»™å®šä¸€ä¸ªå‚æ•°æ—¶ï¼Œå®ƒä»¬å°†æ»šåŠ¨ä½ æŒ‡
-定的“行数â€ï¼Œè€Œä¸æ˜¯â€œå±æ•°â€ã€‚举例æ¥è¯´ï¼ŒC-u 8 C-v å°†å±å¹•å‘下滚动 8 行,
-è€Œä¸æ˜¯ 8 å±ã€‚
+定的“行数â€ï¼Œè€Œä¸æ˜¯â€œå±æ•°â€ã€‚举例æ¥è¯´ï¼ŒC-u 8 C-v 将文本å‘下滚动 8 行。
>> 现在试试看,输入 C-u 8 C-v。
这个命令应该已ç»å°†æ–‡å­—å‘上滚动了 8 è¡Œã€‚å¦‚æžœä½ æƒ³å°†å®ƒå†æ¬¡åœ°å‘下滚动,你å¯
ä»¥ç»™å®šä¸€ä¸ªå‚æ•°ç„¶åŽæ‰§è¡Œ M-v。
-如果你正在使用一个窗å£ç³»ç»Ÿï¼Œæ¯”如 X11 或者微软的 Windows,那么在 Emacs
-窗å£çš„边缘应该有一个长方形的区域å«â€œæ»šåЍæ¡â€ï¼Œä½ å¯ä»¥ç”¨é¼ æ ‡æ“çºµæ»šåŠ¨æ¡æ¥
-滚动文字。
+如果你正在使用图形界é¢ï¼Œæ¯”如 X 或者微软的 Windows,那么在 Emacs窗
+å£çš„一边应该有一个长方形的区域å«â€œæ»šåЍæ¡â€ã€‚ä½ å¯ä»¥ç”¨é¼ æ ‡æ“çºµæ»šåŠ¨æ¡æ¥æ»šåЍ
+文字。
->> 试ç€åœ¨â€œæ»šåЍæ¡å†…çš„å白区域â€ä¸ŠæŒ‰ä¸€ä¸‹é¼ æ ‡ä¸­é”®ã€‚
- 文字应该会滚动到鼠标所指示的ä½ç½®ã€‚
+如果你的鼠标有滚轮的è¯ï¼Œä½ ä¹Ÿå¯ä»¥ä½¿ç”¨æ»šè½®æ¥æ»šåŠ¨ã€‚
->> 当按ä½ä¸­é”®æ—¶ï¼Œè¯•ç€å°†é¼ æ ‡ä¸Šä¸‹ç§»åŠ¨ã€‚
- 你会看到文字éšç€é¼ æ ‡çš„移动而上下滚动。
- ã€Windows ç‰ˆæœ¬ç¬¦åˆ Windows 程åºçš„传统æ“作习惯,上述æ“作ä¸é€‚用。】
-
-
-* 在 EMACS 失去å“应的时候(WHEN EMACS IS HUNG)
+* 如果 EMACS 失去å“应(IF EMACS STOPS RESPONDING)
-----------------------------------------------
如果 Emacs 对你的命令失去å“应,你å¯ä»¥ç”¨ C-g æ¥å®‰å…¨åœ°ç»ˆæ­¢è¿™æ¡å‘½ä»¤ã€‚C-g
@@ -234,7 +230,7 @@ C-g 还å¯ä»¥å–æ¶ˆæ•°å­—å‚æ•°å’Œåªè¾“入到一åŠçš„命令。
* 窗格(WINDOWS)
-----------------
-Emacs å¯ä»¥æœ‰å¤šä¸ªçª—格,æ¯ä¸ªçª—格显示ä¸åŒçš„æ–‡å­—。åŽé¢ä¼šä»‹ç»æ€Žä¹ˆå¯¹ä»˜å¤šä¸ªçª—
+Emacs å¯ä»¥æœ‰å¤šä¸ªâ€œçª—æ ¼â€ï¼Œæ¯ä¸ªçª—格显示ä¸åŒçš„æ–‡å­—。åŽé¢ä¼šä»‹ç»æ€Žä¹ˆå¯¹ä»˜å¤šä¸ªçª—
格,现在我们先学会如何关掉多余的窗格。其实也很简å•:
C-x 1 åªä¿ç•™ä¸€ä¸ªçª—格(也就是关掉其它所有窗格)。
@@ -244,49 +240,46 @@ Emacs å¯ä»¥æœ‰å¤šä¸ªçª—格,æ¯ä¸ªçª—格显示ä¸åŒçš„æ–‡å­—。åŽé¢ä¼šä»‹ç»
>> 把光标移到本行然åŽè¾“å…¥ C-u 0 C-l。
->> 输入 CONTROL-h k CONTROL-f。观察当一个新窗格出现时当å‰çª—æ ¼ï¼ˆç”¨æ¥æ˜¾ç¤º
- CONTROL-f 命令的文档)是如何缩å°çš„。
+>> 输入 C-h k C-f。观察当一个新窗格出现时当å‰çª—æ ¼ï¼ˆç”¨æ¥æ˜¾ç¤º
+ C-f 命令的文档)是如何缩å°çš„。
>> 输入 C-x 1 关掉文档窗格。
-这个命令跟先å‰å­¦è¿‡çš„命令ä¸å¤ªä¸€æ ·ï¼Œå› ä¸ºå®ƒåŒ…å«äº†ä¸¤ä¸ªå­—符,以 CONTROL-x å¼€
-始。有一系列命令都是以 CONTROL-x å¼€å§‹çš„ï¼Œè¿™äº›å‘½ä»¤è®¸å¤šéƒ½è·Ÿâ€œçª—æ ¼ã€æ–‡ä»¶ã€
-缓冲区ã€ç¼“冲区(bufferï¼‰ä¼šåœ¨åŽæ–‡è¯¦ç»†ä»‹ç»ã€‘â€ç­‰ç­‰è¯¸å¦‚此类的东西有关,其
-中有些命令å¯èƒ½åŒ…å«äº† 2 个ã€3 个或者 4 个字符。
+有一系列命令是以 CONTROL-x å¼€å§‹çš„ï¼Œè¿™äº›å‘½ä»¤è®¸å¤šéƒ½è·Ÿâ€œçª—æ ¼ã€æ–‡ä»¶ã€ç¼“冲区
+ã€ç¼“冲区(bufferï¼‰ä¼šåœ¨åŽæ–‡è¯¦ç»†ä»‹ç»ã€‘â€ç­‰ç­‰è¯¸å¦‚此类的东西有关,其中有些
+命令å¯èƒ½åŒ…å«äº† 2 个ã€3 个或者 4 个字符。
* æ’入与删除(INSERTING AND DELETING)
--------------------------------------
-æ’入文字很简å•,直接敲键盘就å¯ä»¥äº†ã€‚你能看到的字符,比如 Aã€7ã€* 等等,
-都被 Emacs 视为文字并且å¯ä»¥ç›´æŽ¥æ’入。敲 <Return>(回车键)会æ’入一个æ¢
-行符。
-
-ä½ å¯ä»¥ç”¨ <Delback> æ¥åˆ é™¤æœ€åŽè¾“入的一个字符,这个跟你在 Emacs 之外的用
-法应该一样。一般æ¥è¯´ <Delback> 就是ä½äºŽ <Return> 键上方æŸå¤„的一个大å—头
-的键,通常被标示为“Deleteâ€ã€â€œDelâ€æˆ–者“Backspaceâ€ã€‚
+æ’入文字很简å•,直接敲键盘就å¯ä»¥äº†ã€‚普通的字符,比如 Aã€7ã€* 等等,会
+éšç€ä½ çš„输入而æ’å…¥ã€‚è¦æ’入一个æ¢è¡Œç¬¦ï¼Œè¾“å…¥ <Return>(这个键在键盘上有
+时会被标注æˆâ€œEnterâ€ï¼‰ã€‚
-如果你找到了“Backspaceâ€é”®ï¼Œé‚£ä¹ˆå®ƒåº”该就是 <Delback>;这时哪怕你åˆåœ¨åˆ«
-的地方找到了一个“Delâ€é”®ï¼Œé‚£ä¹ˆå®ƒä¹Ÿåº”è¯¥ä¸æ˜¯ <Delback>。
+ä½ å¯ä»¥ç”¨ <DEL> æ¥åˆ é™¤å…‰æ ‡å·¦è¾¹çš„字符,这个键通常被标注为“Backspaceâ€â€•―跟
+你在 Emacs 之外的用法应该一样,删除最åŽä¸€ä¸ªè¾“入的字符。
-ä¸€ç§æ›´é€šç”¨çš„说法是,<Delback> 将删除ä½äºŽå…‰æ ‡å‰çš„一个字符。
+你的键盘上å¯èƒ½æœ‰å¦å¤–ä¸€ä¸ªé”®ï¼Œæ ‡æ³¨ç€ <Delete>ï¼Œä½†é‚£ä¸ªä¸æ˜¯æˆ‘们所说的 <DEL>。
->> 现在就æ¥è¯•è¯•â€•â€•æ•²ç‚¹å­—ï¼Œç„¶åŽæŒ‰å‡ ä¸‹ <Delback> 删除它们。
+>> 现在就æ¥è¯•è¯•â€•â€•æ•²ç‚¹å­—ï¼Œç„¶åŽæŒ‰å‡ ä¸‹ <DEL> 删除它们。
ä¸ç”¨æ‹…心文件被修改,你åšä»€ä¹ˆéƒ½æ²¡å…³ç³»ï¼Œè¿™é‡Œå°±æ˜¯ä¸“给你练习用的。
如果一行文字很长ã€è¶…出了窗格的宽度,显示ä¸ä¸‹çš„部分会在紧邻的下一行继续
-æ˜¾ç¤ºã€‚è¿™æ—¶ä¼šæœ‰ä¸€ä¸ªåæ–œçº¿ï¼ˆåœ¨æŽ§åˆ¶å°ä¸‹æ˜¯å斜线,如果你用图形窗å£ç³»ç»Ÿï¼Œåˆ™
-应该是一个å°å°çš„转弯箭头)显示在å³è¾¹æ²¿ï¼Œè¡¨æ˜Žè¿™æ˜¯æŸä¸€è¡Œçš„æŽ¥ç»­æ˜¾ç¤ºã€‚
+显示。如果你使用的是图形界é¢ï¼Œæ–‡æœ¬åŒºåŸŸä¸¤è¾¹çš„狭窄区域(左å³â€œè¾¹ç¼˜â€ï¼‰ä¼šå‡º
+现å°å°çš„转弯箭头,表明这是æŸä¸€è¡Œçš„æŽ¥ç»­æ˜¾ç¤ºã€‚如果你使用的是文本终端,接
+续显示由å±å¹•最å³è¾¹ä¸€åˆ—çš„ä¸€ä¸ªåæ–œçº¿æ¥è¡¨ç¤ºã€‚
->> 输入文字,一直到å±å¹•çš„å³è¾¹ç•Œï¼Œç„¶åŽç»§ç»­ï¼Œä½ ä¼šçœ‹åˆ°ä¸€ä¸ªæŽ¥ç»­è¡Œå‡ºçŽ°ã€‚
+>> 输入文字,一直到å±å¹•çš„å³è¾¹ç•Œï¼Œç„¶åŽç»§ç»­ã€‚
+你会看到一个接续行出现。
->> 用 <Delback> 删掉一些文字,直到此行长度å°äºŽçª—格宽度,接续行就消失了。
+>> 用 <DEL> 删掉一些文字,直到此行长度å°äºŽçª—格宽度,接续行就消失了。
æ¢è¡Œç¬¦è·Ÿå…¶å®ƒå­—符一样å¯ä»¥è¢«åˆ é™¤ã€‚两行中间的æ¢è¡Œç¬¦è¢«åˆ é™¤åŽï¼Œè¿™ä¸¤è¡Œå°†ä¼šåˆ
å¹¶æˆä¸€è¡Œã€‚如果åˆå¹¶åŽçš„这一行太长,超出了窗格宽度,它就会以一个接续行æ¥
显示。
->> 移动光标到æŸè¡Œçš„开头并输入 <Delback>。
+>> 移动光标到æŸè¡Œçš„开头并输入 <DEL>。
这时该行将与其å‰ä¸€è¡Œä¸€èµ·è¢«åˆå¹¶ä¸ºä¸€è¡Œã€‚
>> 输入 <Return> 釿–°æ’入你刚æ‰åˆ é™¤çš„æ¢è¡Œç¬¦ã€‚
@@ -299,10 +292,10 @@ Emacs å¯ä»¥æœ‰å¤šä¸ªçª—格,æ¯ä¸ªçª—格显示ä¸åŒçš„æ–‡å­—。åŽé¢ä¼šä»‹ç»
å¥½ï¼ŒçŽ°åœ¨ä½ åº”è¯¥å·²ç»æŽŒæ¡äº†æœ€åŸºæœ¬çš„的文本æ’入和修改功能,其实删除还å¯ä»¥
“以è¯ä¸ºå•ä½â€è¿›è¡Œï¼Œä¸‹é¢æ˜¯ä¸€ä¸ªå…³äºŽâ€œåˆ é™¤â€æ“作的å°ç»“:
- <Delback> 删除光标å‰çš„一个字符
+ <DEL> 删除光标å‰çš„一个字符
C-d 删除光标åŽçš„一个字符
- M-<Delback> 移除光标å‰çš„一个è¯
+ M-<DEL> 移除光标å‰çš„一个è¯
M-d 移除光标åŽçš„一个è¯
C-k 移除从光标到“行尾â€é—´çš„字符
@@ -311,29 +304,31 @@ Emacs å¯ä»¥æœ‰å¤šä¸ªçª—格,æ¯ä¸ªçª—格显示ä¸åŒçš„æ–‡å­—。åŽé¢ä¼šä»‹ç»
ã€å¯èƒ½ä½ å·²ç»æ³¨æ„到了“删除(delete)â€å’Œâ€œç§»é™¤ï¼ˆkill)â€çš„用è¯åŒºåˆ«ï¼ŒåŽ
文会有详细说明。】
-注æ„“<Delback> å’Œ C-dâ€è¿˜æœ‰â€œM-<Delback> å’Œ M-dâ€æ˜¯æ ¹æ®å‰è¿°æƒ¯ä¾‹ä»Ž C-f
-å’Œ M-f è¡ç”Ÿå‡ºæ¥çš„(其实<Delback>䏿˜¯æŽ§åˆ¶å­—符,我们先忽略这一点)。C-k
-å’Œ M-k 的关系在æŸç§ç¨‹åº¦ä¸Šä¸Ž C-e å’Œ M-e 一样――如果把“一行â€å’Œâ€œä¸€å¥â€
-作一个类比的è¯ã€‚
+注æ„“<DEL> å’Œ C-dâ€è¿˜æœ‰â€œM-<DEL> å’Œ M-dâ€æ˜¯æ ¹æ®å‰è¿°æƒ¯ä¾‹ä»Ž C-få’Œ M-f è¡ç”Ÿ
+出æ¥çš„(其实<DEL>䏿˜¯æŽ§åˆ¶å­—符,我们先忽略这一点)。C-kå’Œ M-k 的关系在
+æŸç§ç¨‹åº¦ä¸Šä¸Ž C-e å’Œ M-e 一样――如果把“一行â€å’Œâ€œä¸€å¥â€ä½œä¸€ä¸ªç±»æ¯”çš„è¯ã€‚
你也å¯ä»¥ç”¨ä¸€ç§é€šç”¨çš„办法æ¥ç§»é™¤ç¼“冲区里的任何一部分:首先把光标移动到你
-想è¦ç§»é™¤çš„åŒºåŸŸçš„ä¸€ç«¯ï¼Œç„¶åŽæŒ‰ C-@ 或 C-SPC(任一å³å¯ï¼ŒSPCæŒ‡ç©ºæ ¼ï¼‰ã€æ³¨æ„,
-C-SPC 往往被中文用户设定æˆè¾“入法热键,如果这样,C-SPC 就被系统拦截而无
-法传递给 Emacs 了,因此这里还是推è使用C-@。】,然åŽå°†å…‰æ ‡ç§»åŠ¨åˆ°å¦ä¸€ç«¯ï¼Œ
-冿Œ‰ C-w å°±å¯ä»¥æŠŠä½äºŽè¿™ä¸¤ç‚¹ä¹‹é—´çš„æ‰€æœ‰æ–‡å­—移除了。
+想è¦ç§»é™¤çš„åŒºåŸŸçš„ä¸€ç«¯ï¼Œç„¶åŽæŒ‰ C-<SPC>(<SPC>æŒ‡ç©ºæ ¼ï¼‰ã€æ³¨æ„,C-<SPC> å¾€
+往被中文用户设定æˆè¾“入法热键,如果这样,C-<SPC> 就被系统拦截而无法传递
+ç»™ Emacs äº†ï¼Œåœ¨è¿™ç§æƒ…况下å¯ä»¥ä½¿ç”¨C-@。】,然åŽå°†å…‰æ ‡ç§»åŠ¨åˆ°ä½ å‡†å¤‡ç§»é™¤çš„
+文字的å¦ä¸€ç«¯ã€‚这个时候, Emacs 会高亮光标和你按下 C-<SPC> 之间的文本。
+最åŽï¼ŒæŒ‰ä¸‹ C-w 。这样就å¯ä»¥æŠŠä½äºŽè¿™ä¸¤ç‚¹ä¹‹é—´çš„æ‰€æœ‰æ–‡å­—移除了。
>> 移动光标到上一段开头的“你â€å­—。
->> 输入 C-@ 。Emacs 应该会在å±å¹•的下方显示一个“Mark setâ€çš„æ¶ˆæ¯ã€‚
+>> 输入 C-<SPC> 。Emacs 应该会在å±å¹•的下方显示一个“Mark setâ€çš„æ¶ˆæ¯ã€‚
>> 移动光标到第二行中的“端â€å­—。
>> 输入 C-w,从“你â€å¼€å§‹åˆ°â€œç«¯â€ä¹‹å‰çš„æ–‡å­—被全部移除。
-注æ„,“移除(kill)â€å’Œâ€œåˆ é™¤ï¼ˆdelete)â€çš„ä¸åŒåœ¨äºŽè¢«ç§»é™¤çš„东西å¯ä»¥æ‰¾å›ž
-æ¥ï¼Œè€Œè¢«åˆ é™¤çš„å°±ä¸è¡Œäº†ã€‚ã€å®žé™…上,移除掉的东西虽然看起æ¥â€œæ¶ˆå¤±â€äº†ï¼Œä½†
-实际上被 Emacs 记录了下æ¥ï¼Œå› æ­¤è¿˜å¯ä»¥æ‰¾å›žæ¥ï¼›è€Œåˆ é™¤æŽ‰çš„东西虽然也å¯èƒ½è¿˜
-在内存里,但是已ç»è¢« Emacs“抛弃â€äº†ï¼Œæ‰€ä»¥å°±æ‰¾ä¸å›žæ¥äº†ã€‚ã€‘é‡æ–°æ’入被移
-除的文字称为“å¬å›žï¼ˆyank)â€ã€‚一般而言,那些å¯èƒ½æ¶ˆé™¤å¾ˆå¤šæ–‡å­—的命令会把
-消除掉的文字记录下æ¥ï¼ˆå®ƒä»¬è¢«è®¾å®šæˆäº†â€œå¯å¬å›žâ€ï¼‰ï¼Œè€Œé‚£äº›åªæ¶ˆé™¤ä¸€ä¸ªå­—符
-æˆ–è€…åªæ¶ˆé™¤ç©ºç™½çš„命令就ä¸ä¼šè®°å½•被消除的内容(自然你也就无法å¬å›žäº†ï¼‰ã€‚
+注æ„,“移除(kill)â€å’Œâ€œåˆ é™¤ï¼ˆdelete)â€çš„ä¸åŒåœ¨äºŽè¢«ç§»é™¤çš„东西å¯ä»¥è¢«é‡æ–°
+æ’入(在任何ä½ç½®ï¼‰ï¼Œè€Œè¢«åˆ é™¤çš„å°±ä¸èƒ½ä½¿ç”¨ç›¸åŒçš„æ–¹æ³•釿–°æ’入了(ä¸è¿‡å¯ä»¥
+通过撤销一个删除命令æ¥åšåˆ°ï¼ŒåŽæ–‡ä¼šæåˆ°ï¼‰ã€‚ã€å®žé™…上,移除掉的东西虽然看
+èµ·æ¥â€œæ¶ˆå¤±â€äº†ï¼Œä½†å®žé™…上被 Emacs 记录了下æ¥ï¼Œå› æ­¤è¿˜å¯ä»¥æ‰¾å›žæ¥ï¼›è€Œåˆ é™¤æŽ‰
+的东西虽然也å¯èƒ½è¿˜åœ¨å†…存里,但是已ç»è¢« Emacs“抛弃â€äº†ï¼Œæ‰€ä»¥å°±æ‰¾ä¸å›žæ¥
+äº†ã€‚ã€‘é‡æ–°æ’入被移除的文字称为“å¬å›žï¼ˆyank)â€ã€‚一般而言,那些å¯èƒ½æ¶ˆé™¤å¾ˆ
+多文字的命令会把消除掉的文字记录下æ¥ï¼ˆå®ƒä»¬è¢«è®¾å®šæˆäº†â€œå¯å¬å›žâ€ï¼‰ï¼Œè€Œé‚£äº›
+åªæ¶ˆé™¤ä¸€ä¸ªå­—ç¬¦æˆ–è€…åªæ¶ˆé™¤ç©ºç™½çš„命令就ä¸ä¼šè®°å½•被消除的内容(自然你也就无
+法å¬å›žäº†ï¼‰ã€‚
>> 移动光标到一éžç©ºç™½è¡Œçš„行头,然åŽè¾“å…¥ C-k 移除那一行上的文字。
@@ -345,9 +340,10 @@ C-SPC 往往被中文用户设定æˆè¾“入法热键,如果这样,C-SPC å°±è¢
C-k 会把两行以åŠå®ƒä»¬çš„æ¢è¡Œç¬¦ç§»é™¤ï¼›è€Œå¦‚æžœåªæ˜¯è¾“å…¥ C-k ä¸¤æ¬¡æ˜¾ç„¶ä¸æ˜¯è¿™ä¸ªç»“
果。
-将被移除的文字æ¢å¤çš„动作称为“å¬å›žï¼ˆyanking)â€ã€‚ï¼ˆå°±å¥½åƒæŠŠåˆ«äººä»Žä½ èº«è¾¹
+釿–°æ’入被移除的文字æ¢å¤çš„动作称为“å¬å›žï¼ˆyanking)â€ã€‚ï¼ˆå°±å¥½åƒæŠŠåˆ«äººä»Žä½ èº«è¾¹
移走的东西åˆçŒ›åŠ›åœ°æ‹‰å›žæ¥ã€‚)你å¯ä»¥åœ¨ä½ åˆ é™¤æ–‡å­—的地方å¬å›žï¼Œä¹Ÿå¯ä»¥åœ¨åˆ«çš„
-地方å¬å›žï¼Œè¿˜å¯ä»¥å¤šæ¬¡å¬å›žåŒæ ·çš„æ–‡å­—以得到它的多个拷è´ã€‚
+地方å¬å›žï¼Œè¿˜å¯ä»¥å¤šæ¬¡å¬å›žåŒæ ·çš„æ–‡å­—以得到它的多个拷è´ã€‚很多其它的编辑器
+把移除和å¬å›žå«åšâ€œå‰ªåˆ‡â€å’Œâ€œç²˜è´´â€ (详情å¯è§ Emacs 使用手册里的术语表)。
å¬å›žçš„命令是 C-y。它会在光标所在处æ’入你最åŽç§»é™¤çš„æ–‡å­—。
@@ -383,24 +379,23 @@ C-y å¯ä»¥å¬å›žæœ€è¿‘一次移除的内容,那如何å¬å›žå‰å‡ æ¬¡ç§»é™¤çš„å
* 撤销(UNDO)
--------------
-如果你修改了一段文字,åˆè§‰å¾—改得ä¸å¥½ï¼Œå¯ä»¥ç”¨ undo 命令进行撤销:
-C-x u。
+如果你修改了一段文字,åˆè§‰å¾—改得ä¸å¥½ï¼Œå¯ä»¥ç”¨ undo 命令进行撤销:C-/。
-通常 C-x u 会消除一个命令所造æˆçš„æ‰€æœ‰æ”¹å˜ï¼›å¦‚果你在一行中连续多次地使用
-C-x u,你会把以å‰çš„å‘½ä»¤ä¹Ÿä¾æ¬¡æ’¤é”€ã€‚
+通常 C-/ 会消除一个命令所造æˆçš„æ‰€æœ‰æ”¹å˜ï¼›å¦‚果你在一行中连续多次地使用
+C-/,你会把以å‰çš„å‘½ä»¤ä¹Ÿä¾æ¬¡æ’¤é”€ã€‚
但是有两个例外:
1) æ²¡æœ‰æ”¹å˜æ–‡å­—的命令ä¸ç®—(包括光标移动命令和滚动命令)
-2) 从键盘输入的字符以组为å•ä½â€•―æ¯ç»„ 20 个字符――æ¥è¿›è¡Œå¤„ç†ã€‚
- (这是为了å‡å°‘你在撤销“æ’入文字â€åŠ¨ä½œæ—¶éœ€è¦è¾“å…¥ C-x u 的次数)
+2) 从键盘输入的字符以组为å•ä½â€•―æ¯ç»„最多 20 个字符――æ¥è¿›è¡Œå¤„ç†ã€‚
+ (这是为了å‡å°‘你在撤销“æ’入文字â€åŠ¨ä½œæ—¶éœ€è¦è¾“å…¥ C-/ 的次数)
->> 用 C-k 将这一行移除,然åŽè¾“å…¥ C-x u ï¼Œå®ƒä¼šå†æ¬¡å‡ºçŽ°ã€‚
+>> 用 C-k 将这一行移除,然åŽè¾“å…¥ C-/ ï¼Œå®ƒä¼šå†æ¬¡å‡ºçŽ°ã€‚
-C-_ 也是撤销命令;它的作用跟 C-x u 一样,但是它比较容易多次输入。C-_ 的
-缺点是在æŸäº›é”®ç›˜ä¸Šå¯èƒ½ä¸å¤ªå®¹æ˜“æŒ‰ï¼Œè¿™ä¹Ÿæ­£æ˜¯æˆ‘ä»¬åŒæ—¶æä¾› C-x u 的原因。在
-æŸäº›ç»ˆç«¯ä¸Šï¼Œä½ å¯ä»¥æŒ‰ä½ CONTROL 冿Œ‰â€œ/â€æ¥è¾“å…¥ C-_。
+C-_ 也是撤销命令;它的作用跟 C-/ 一样,但是它比较容易多次输入。在
+æŸäº›ç»ˆç«¯ä¸Šï¼Œè¾“å…¥ C-/ å®žé™…ä¸Šå‘ Emacs å‘é€çš„æ˜¯ C-_ 。
+å¦å¤–, C-x u å’Œ C-/ å®Œå…¨ä¸€æ ·ï¼Œä½†æ˜¯æŒ‰èµ·æ¥æœ‰äº›éº»çƒ¦ã€‚
-æ•°å­—å‚æ•°å¯¹äºŽ C-_ å’Œ C-x u çš„æ„义是执行撤销的é‡å¤æ¬¡æ•°ã€‚
+æ•°å­—å‚æ•°å¯¹äºŽ C-/ 〠C-_ å’Œ C-x u çš„æ„义是执行撤销的é‡å¤æ¬¡æ•°ã€‚
* 文件(FILE)
@@ -416,14 +411,13 @@ C-_ 也是撤销命令;它的作用跟 C-x u 一样,但是它比较容易多
文件也ä¿å­˜åˆ°è®¡ç®—机上。在存盘的时候,Emacs 会把存盘å‰çš„æ–‡ä»¶é‡å‘½åä¿å­˜ï¼Œ
以防你改完之åŽåˆæƒ³å悔。
-在å±å¹•的下方,你应该能够看到头尾都是短线“-â€çš„一行,行首通常是一些诸如
-“--:-- TUTORIAL.cnâ€çš„æ–‡å­—ï¼Œè¿™äº›æ–‡å­—ä»£è¡¨äº†ä½ å½“å‰æ­£åœ¨è®¿é—®çš„æ–‡ä»¶ã€‚比如你
-现在正在访问的文件å«â€œTUTORIAL.cnâ€ï¼Œå®ƒåªæ˜¯ä¸€ä¸ªç»™ä½ ä¸´æ—¶ä½¿ç”¨çš„æ‹·è´ã€‚æ¯å½“
-Emacs 寻找到一个文件,文件å就会出现在这个ä½ç½®ã€‚
+在å±å¹•的下方,你应该能够看到头部有短线“-â€çš„一行,行首通常是一些诸如“
+-:--- TUTORIAL.cnâ€çš„æ–‡å­—ï¼Œè¿™äº›æ–‡å­—ä»£è¡¨äº†ä½ å½“å‰æ­£åœ¨è®¿é—®çš„æ–‡ä»¶ã€‚比如你现
+在正在访问的文件是对 Emacs 快速指å—的一份临时拷è´ï¼Œå«åšâ€œTUTORIAL.cnâ€ã€‚
+æ¯å½“Emacs 寻找到一个文件,文件å就会出现在这个ä½ç½®ã€‚
-寻找文件的命令有一个特点,那就是你必须给出文件å。我们称这个命令“从终
-ç«¯è¯»å…¥äº†ä¸€ä¸ªå‚æ•°â€ï¼ˆåœ¨è¿™é‡Œï¼Œè¿™ä¸ªå‚数显然就是文件å)。在你输入这æ¡å‘½ä»¤
-之åŽï¼š
+寻找文件的命令有一个特点,那就是你必须给出文件å。我们称这个命令“读入
+äº†ä¸€ä¸ªå‚æ•°â€ï¼ˆåœ¨è¿™é‡Œï¼Œè¿™ä¸ªå‚数显然就是文件å)。在你输入这æ¡å‘½ä»¤ä¹‹åŽï¼š
C-x C-f 寻找一个文件
@@ -437,10 +431,10 @@ Emacs 会æç¤ºä½ è¾“入文件å。你输入的文件å会出现在å±å¹•最åº
这会关掉å°ç¼“å†²ï¼ŒåŒæ—¶ä¹Ÿä¼šå–消使用å°ç¼“冲的 C-x C-f 命令。
当然了,你也没有找任何文件。
-用 <Return> ç»“æŸæ–‡ä»¶åçš„è¾“å…¥ã€‚è¿™ä¹‹åŽ C-x C-f 命令开始工作并找到你指定的
-文件。å°ç¼“冲在 C-x C-f 命令结æŸä¹‹åŽä¹Ÿä¼šæ¶ˆå¤±ã€‚
+用 <Return> ç»“æŸæ–‡ä»¶å的输入。之åŽï¼Œå°ç¼“冲会消失,C-x C-f 将会去寻找你
+指定的文件。å°ç¼“冲在 C-x C-f 命令结æŸä¹‹åŽä¹Ÿä¼šæ¶ˆå¤±ã€‚
-眨眼间文件就被显示在å±å¹•上,你å¯ä»¥å¼€å§‹ç¼–辑了。存盘用这æ¡å‘½ä»¤ï¼š
+文件被显示在了å±å¹•上,你å¯ä»¥å¼€å§‹ç¼–辑了。存盘用这æ¡å‘½ä»¤ï¼š
C-x C-s 储存这个文件
@@ -450,15 +444,16 @@ Emacs 会æç¤ºä½ è¾“入文件å。你输入的文件å会出现在å±å¹•最åº
M-x customize-variable <Return> make-backup-files <Return>】
存盘结æŸåŽï¼ŒEmacs 会显示写入文件的文件å。你最好养æˆç»å¸¸å­˜ç›˜çš„习惯,这
-å¯ä»¥å‡å°‘系统崩溃和死机给你带æ¥çš„æŸå¤±ã€‚
+å¯ä»¥å‡å°‘系统崩溃和死机给你带æ¥çš„æŸå¤±ï¼ˆä¹Ÿå¯å‚è§ä¸‹é¢çš„“自动ä¿å­˜â€ä¸€èŠ‚ï¼‰ã€‚
->> 输入 C-x C-s 把本快速指å—存下æ¥ã€‚
- 你会在å±å¹•çš„ä¸‹æ–¹çœ‹åˆ°ä¸€æ¡æ¶ˆæ¯ï¼šâ€œWrote ...TUTORIAL.cnâ€ã€‚
+>> 输入 C-x C-s TUTORIAL.cn <Return> 。
+ 这将会把该指å—ä¿å­˜ä¸ºä¸€ä¸ªå为 TUTORIAL.cn 的文件,并且在å±å¹•的下方显
+ ç¤ºä¸€æ¡æ¶ˆæ¯ï¼šâ€œWrote ...TUTORIAL.cnâ€ã€‚
ä½ ä¸ä½†å¯ä»¥å¯»æ‰¾ä¸€ä¸ªå·²æœ‰çš„æ–‡ä»¶æ¥æŸ¥çœ‹æˆ–编辑,还å¯ä»¥å¯»æ‰¾ä¸€ä¸ªä¸å­˜åœ¨çš„æ–‡ä»¶ã€‚
-实际上这正是 Emacs 创建新文件的方法:找到ä¸å­˜åœ¨çš„æ–°æ–‡ä»¶ã€‚åªæœ‰åœ¨å­˜ç›˜çš„æ—¶
-候,Emacs æ‰ä¼šçœŸæ­£åˆ›å»ºè¿™ä¸ªæ–‡ä»¶ã€‚而在这之åŽçš„一切就跟编辑一个已有文件没
-有区别了。
+实际上这正是 Emacs 创建新文件的方法:找到ä¸å­˜åœ¨çš„æ–°æ–‡ä»¶ã€‚äº‹å®žä¸Šï¼Œåªæœ‰
+在存盘的时候,Emacs æ‰ä¼šçœŸæ­£åˆ›å»ºè¿™ä¸ªæ–‡ä»¶ã€‚而在这之åŽçš„一切就跟编辑一个
+已有文件没有区别了。
* 缓冲区(BUFFER)
@@ -468,10 +463,6 @@ Emacs 会æç¤ºä½ è¾“入文件å。你输入的文件å会出现在å±å¹•最åº
切回第一个文件,一ç§åŠžæ³•æ˜¯å†ç”¨ä¸€æ¬¡ C-x C-f。这样,你就å¯ä»¥åœ¨ Emacs 中åŒ
时打开多个文件。
->> 用 C-x C-f foo <Return> 的方å¼å»ºç«‹ä¸€ä¸ªå为“fooâ€çš„æ–‡ä»¶ã€‚
- 输入一些文字,å†ç”¨ C-x C-s ä¿å­˜æ–‡ä»¶â€œfooâ€ã€‚
- 最åŽï¼Œè¾“å…¥ C-x C-f TUTORIAL.cn <Return> 回到这里。
-
Emacs 把æ¯ä¸ªç¼–辑中的文件都放在一个称为“缓冲区(buffer)â€çš„地方。æ¯å¯»
找到一个文件,Emacs 就在其内部开辟一个缓冲区。用下é¢çš„命令å¯ä»¥åˆ—出当å‰
所有的缓冲区:
@@ -490,24 +481,28 @@ Emacs 把æ¯ä¸ªç¼–辑中的文件都放在一个称为“缓冲区(buffer)â€
C-x C-f 是一ç§åŠžæ³•ã€‚ä¸è¿‡è¿˜æœ‰ä¸€ä¸ªæ›´ç®€å•的办法,那就是用 C-x b。用这æ¡å‘½
令,你必须输入缓冲区的å称。
->> 输入 C-x b foo <Return> 以回到文件“fooâ€çš„缓冲区。
+>> 通过输入 C-x C-f foo <Return> 创建一个å为“fooâ€çš„æ–‡ä»¶ã€‚
ç„¶åŽè¾“å…¥ C-x b TUTORIAL.cn <Return> 回到这里。
大多数情况下,缓冲区与跟其对应的文件是åŒå的(ä¸åŒ…括目录å),ä¸è¿‡è¿™ä¹Ÿ
䏿˜¯ç»å¯¹çš„。用 C-x C-b 得到的缓冲区列表总是显示缓冲区å。
-你在 Emacs çª—æ ¼é‡Œçœ‹åˆ°çš„â€œä»»ä½•â€æ–‡å­—都一定属于æŸä¸ªç¼“冲区。然而,缓冲区未
-å¿…æœ‰å¯¹åº”æ–‡ä»¶ï¼šæ¯”å¦‚æ˜¾ç¤ºç¼“å†²åŒºåˆ—è¡¨çš„ç¼“å†²åŒºå°±æ˜¯è¿™æ ·ã€‚å†æ¯”如“*Messages*â€
-缓冲区也没有对应文件,这个缓冲区里存放的都是在 Emacs 底部出现的消æ¯ã€‚
+缓冲区未必有对应文件。显示缓冲区列表的缓冲区(å«åšâ€œ*Buffer List*â€ï¼‰å°±
+是这样。这个 TUTORIAL.cn ç¼“å†²åŒºèµ·åˆæ²¡æœ‰å¯¹åº”的文件,但是现在有了,因为
+在å‰ä¸€èŠ‚ä½ è¾“å…¥äº† C-x C-s , 将它ä¿å­˜æˆäº†ä¸€ä¸ªæ–‡ä»¶ã€‚
+
+“*Messages*â€ç¼“冲区也没有对应文件,这个缓冲区里存放的都是在 Emacs 底部
+出现的消æ¯ã€‚
>> 输入 C-x b *Messages* <Return> 瞅瞅消æ¯ç¼“冲区里都有什么东西。
ç„¶åŽå†è¾“å…¥ C-x b TUTORIAL.cn <Return> 回到这里。
如果你对æŸä¸ªæ–‡ä»¶åšäº†äº›ä¿®æ”¹ï¼Œç„¶åŽåˆ‡æ¢åˆ°å¦ä¸€ä¸ªæ–‡ä»¶ï¼Œè¿™ä¸ªåŠ¨ä½œå¹¶ä¸ä¼šå¸®ä½ æŠŠ
-å‰ä¸€ä¸ªæ–‡ä»¶å­˜ç›˜ã€‚对第一个文件的修改ä»ç„¶ä»…存在于 Emacs 中,也就是在它对应
-的缓冲区里。并且,对第二个文件的修改也ä¸ä¼šå½±å“到第一个文件。这很有用,
-但是也挺麻烦:因为如果你想è¦å­˜å‚¨ç¬¬ä¸€ä¸ªæ–‡ä»¶ï¼Œè¿˜éœ€è¦å…ˆ C-x C-f 切æ¢å›žåŽ»å†
-用 C-x C-s 存盘。你需è¦ä¸€ä¸ªæ›´ç®€ä¾¿çš„æ–¹æ³•,而 Emacs å·²ç»ä¸ºä½ å‡†å¤‡å¥½äº†ï¼š
+å‰ä¸€ä¸ªæ–‡ä»¶å­˜ç›˜ã€‚对第一个文件的修改ä»ç„¶ä»…存在于 Emacs 中,也就是在它对
+应的缓冲区里。并且,对第二个文件的修改也ä¸ä¼šå½±å“到第一个文件。这很有用,
+但也æ„味ç€ä½ éœ€è¦ä¸€ä¸ªç®€ä¾¿çš„办法æ¥ä¿å­˜ç¬¬ä¸€ä¸ªæ–‡ä»¶çš„缓冲区。先切æ¢å›žé‚£ä¸ªç¼“
+冲区,å†ç”¨ C-x C-s 存盘,太麻烦了。你需è¦ä¸€ä¸ªæ›´ç®€ä¾¿çš„æ–¹æ³•,而 Emacs å·²
+ç»ä¸ºä½ å‡†å¤‡å¥½äº†ï¼š
C-x s ä¿å­˜å¤šä¸ªç¼“冲区
@@ -532,21 +527,18 @@ Emacs 的命令就åƒå¤©ä¸Šçš„æ˜Ÿæ˜Ÿï¼Œæ•°ä¹Ÿæ•°ä¸æ¸…。把它们都对应到 C
很多扩展命令都相当有用,虽然与你已ç»å­¦è¿‡çš„命令比起æ¥ï¼Œä»–们å¯èƒ½ä¸é‚£ä¹ˆå¸¸
用。我们早已ç»è§è¿‡ä¸€äº›æ‰©å±•命令了,比如用 C-x C-f 寻找文件和用 C-x C-s
ä¿å­˜æ–‡ä»¶ï¼›é€€å‡º Emacs 用的 C-x C-c 也是扩展命令。(ä¸ç”¨æ‹…心退出 Emacs 会
-给你带æ¥ä»€ä¹ˆæŸå¤±ï¼ŒEmacs ä¼šåœ¨é€€å‡ºä¹‹å‰æé†’ä½ å­˜ç›˜çš„ï¼‰
+给你带æ¥ä»€ä¹ˆæŸå¤±ï¼ŒEmacs ä¼šåœ¨é€€å‡ºä¹‹å‰æé†’ä½ å­˜ç›˜çš„ã€‚ï¼‰
-在控制å°ä¸‹ï¼ŒC-z å¯ä»¥æš‚时离开 Emacs――当然,你还å¯ä»¥å†å›žæ¥ã€‚
+如果你使用图形界é¢ï¼Œä½ ä¸éœ€è¦ä»»ä½•特殊的命令æ¥åˆ‡æ¢ Emacs 和其他应用程åºã€‚
+ä½ å¯ä»¥ä½¿ç”¨é¼ æ ‡æˆ–者窗å£ç®¡ç†å™¨çš„命令。然而,如果你使用åªèƒ½åŒæ—¶æ˜¾ç¤ºä¸€ä¸ªåº”
+用程åºçš„æ–‡æœ¬ç»ˆç«¯ï¼Œä½ éœ€è¦â€œæŒ‚起†Emacs ,以切æ¢åˆ°å…¶ä»–的应用程åºã€‚
-在å…许 C-z 的系统中,C-z 会把 Emacs“挂起â€ï¼Œä¹Ÿå°±æ˜¯è¯´ï¼Œå®ƒä¼šå›žåˆ° shell
-但ä¸é€€å‡º Emacs。在常用的 shell 中,通常å¯ä»¥ç”¨â€œfgâ€æˆ–者“%emacsâ€å‘½ä»¤å†
-次回到 Emacs 中。
+C-z å¯ä»¥æš‚时离开 Emacs――当然,你还å¯ä»¥å†å›žæ¥ã€‚在å…许 C-z 的系统中,C-z
+会把 Emacs“挂起â€ï¼Œä¹Ÿå°±æ˜¯è¯´ï¼Œå®ƒä¼šå›žåˆ° shell但䏿€æ­» Emacs 的进程。在常
+用的 shell 中,通常å¯ä»¥ç”¨â€œfgâ€æˆ–者“%emacsâ€å‘½ä»¤å†æ¬¡å›žåˆ° Emacs 中。
-在没有æä¾›æŒ‚起功能的系统中,C-z 会在 Emacs ä¹‹ä¸‹åˆ›å»ºä¸€ä¸ªå­ shell æ¥è®©ä½ 
-è¿è¡Œå…¶å®ƒç¨‹åºï¼Œå¹¶ä¸”冿¬¡â€œå›žåˆ°â€Emacs 中――虽然我们并没有真正离开过。这
-ç§æƒ…况下,通常用 shell 命令“exitâ€ä»Žå­ shell 回到 Emacs。
-
-你最好在打算退出登陆的时候å†ç”¨ C-x C-c。在 Emacs 被诸如邮件处ç†ç¨‹åºä¹‹ç±»
-的外部程åºè°ƒç”¨ä¹‹åŽï¼Œä¹Ÿå¯ä»¥ç”¨ C-x C-c 退出。ä¸è¿‡ä¸€èˆ¬æ¥è®²ï¼Œå¦‚æžœä½ ä¸æƒ³é€€å‡º
-登录,最好还是把 Emacs æŒ‚èµ·è€Œä¸æ˜¯é€€å‡ºã€‚
+你最好在打算退出登陆的时候å†ç”¨ C-x C-c。在把 Emacs 当åšä¸€ä¸ªä¸´æ—¶çš„编辑
+器的时候(比如被一个邮件处ç†ç¨‹åºè°ƒç”¨ï¼‰ï¼Œä¹Ÿå¯ä»¥ç”¨ C-x C-c 退出。
C-x 的扩展命令有很多,下é¢åˆ—出的是你已ç»å­¦è¿‡çš„:
@@ -557,11 +549,11 @@ C-x 的扩展命令有很多,下é¢åˆ—出的是你已ç»å­¦è¿‡çš„:
C-x 1 关掉其它所有窗格,åªä¿ç•™ä¸€ä¸ªã€‚
C-x u 撤销。
-ç”¨å‘½ä»¤åæ‰©å±•的命令通常并ä¸å¸¸ç”¨ï¼Œæˆ–åªç”¨åœ¨éƒ¨åˆ†æ¨¡å¼ä¸‹ã€‚比如 replace-string
-(字符串替æ¢ï¼‰è¿™ä¸ªå‘½ä»¤ï¼Œå®ƒä¼šåœ¨å…¨æ–‡èŒƒå›´å†…æŠŠä¸€ä¸ªå­—ç¬¦ä¸²æ›¿æ¢æˆå¦ä¸€ä¸ªã€‚在输
-å…¥ M-x 之åŽï¼ŒEmacs 会在å±å¹•底端å‘你询问并等待你输入命令å。如果你想输入
-“replace-stringâ€ï¼Œå…¶å®žåªéœ€è¦æ•²â€œrepl s<TAB>â€å°±è¡Œäº†ï¼ŒEmacs 会帮你自动
-è¡¥é½ã€‚è¾“å…¥å®Œä¹‹åŽæŒ‰ <Return> 。
+ç”¨å‘½ä»¤åæ‰©å±•的命令通常并ä¸å¸¸ç”¨ï¼Œæˆ–åªç”¨åœ¨éƒ¨åˆ†æ¨¡å¼ä¸‹ã€‚比如
+replace-string(字符串替æ¢ï¼‰è¿™ä¸ªå‘½ä»¤ï¼Œå®ƒä¼šæŠŠä¸€ä¸ªå­—ç¬¦ä¸²æ›¿æ¢æˆå¦ä¸€ä¸ªã€‚在
+输入 M-x 之åŽï¼ŒEmacs 会在å±å¹•底端å‘你询问并等待你输入命令å。如果你想
+输入“replace-stringâ€ï¼Œå…¶å®žåªéœ€è¦æ•²â€œrepl s<TAB>â€å°±è¡Œäº†ï¼ŒEmacs 会帮你自
+动补é½ã€‚è¾“å…¥å®Œä¹‹åŽæŒ‰ <Return> æäº¤ã€‚
字符串替æ¢å‘½ä»¤éœ€è¦ä¸¤ä¸ªå‚数――被替æ¢çš„å­—ç¬¦ä¸²å’Œç”¨æ¥æ›¿æ¢å®ƒçš„字符串。æ¯ä¸ª
傿•°çš„输入都以æ¢è¡Œç¬¦æ¥ç»“æŸã€‚
@@ -586,8 +578,8 @@ C-x 的扩展命令有很多,下é¢åˆ—出的是你已ç»å­¦è¿‡çš„:
“#hello.c#â€ã€‚这个文件会在正常存盘之åŽè¢« Emacs 删除。
所以,å‡å¦‚ä¸å¹¸çœŸçš„å‘生了,你大å¯ä»¥ä»Žå®¹åœ°æ‰“开原æ¥çš„æ–‡ä»¶ï¼ˆæ³¨æ„䏿˜¯è‡ªåЍä¿
-存文件)然åŽè¾“å…¥ M-x recover file<Return> æ¥æ¢å¤ä½ çš„自动ä¿å­˜æ–‡ä»¶ã€‚在æ
-示确认的时候,输入 yes<Return>。
+存文件)然åŽè¾“å…¥ M-x recover file <Return> æ¥æ¢å¤ä½ çš„自动ä¿å­˜æ–‡ä»¶ã€‚在
+æç¤ºç¡®è®¤çš„æ—¶å€™ï¼Œè¾“å…¥ yes<Return>。
* 回显区(ECHO AREA)
@@ -602,7 +594,7 @@ C-x 的扩展命令有很多,下é¢åˆ—出的是你已ç»å­¦è¿‡çš„:
ä½äºŽå›žæ˜¾åŒºæ­£ä¸Šæ–¹çš„ä¸€è¡Œè¢«ç§°ä¸ºâ€œçŠ¶æ€æ â€ã€‚çŠ¶æ€æ ä¸Šä¼šæ˜¾ç¤ºä¸€äº›ä¿¡æ¯ï¼Œæ¯”如:
---:** TUTORIAL.cn (Fundamental)--L670--54%----------------
+ -:**- TUTORIAL.cn 63% L749 (Fundamental)
çŠ¶æ€æ æ˜¾ç¤ºäº† Emacs 的状æ€å’Œä½ æ­£åœ¨ç¼–辑的文字的一些信æ¯ã€‚
@@ -631,7 +623,7 @@ Emacs çš„ä¸»æ¨¡å¼æž—林总总。有用æ¥ç¼–辑程åºä»£ç çš„――比如 Lisp
编辑自然语言文本――比如现在――应该用 Text 模å¼ã€‚
->> 输入 M-x text mode<Return>。
+>> 输入 M-x text-mode <Return>。
别担心,什么都没å˜ã€‚ä¸è¿‡ç»†å¿ƒä¸€äº›å¯ä»¥å‘现,M-f å’Œ M-b 现在把å•引å·ï¼ˆ')
视为è¯çš„一部分了。而在先å‰çš„ Fundamental 模å¼ä¸­ï¼ŒM-f å’Œ M-b 都将å•引å·
@@ -643,7 +635,8 @@ Emacs 里得到了很好的体现】
用 C-h m å¯ä»¥æŸ¥çœ‹å½“å‰ä¸»æ¨¡å¼çš„æ–‡æ¡£ã€‚
->> 用 C-u C-v 将本行带到å±å¹•的最上方。
+>> 把光标移动到下一行。
+>> 用 C-l C-l 将本行带到å±å¹•的最上方。
>> 输入 C-h m,看看 Text 模å¼ä¸Ž Fundamental æ¨¡å¼æœ‰å“ªäº›ä¸åŒã€‚
>> 输入 C-x 1 关掉文档窗格。
@@ -655,12 +648,12 @@ mode)存在。辅模å¼å¹¶ä¸èƒ½æ›¿ä»£ä¸»æ¨¡å¼ï¼Œè€Œæ˜¯æä¾›ä¸€äº›è¾…助的å
有一个å«åšè‡ªåŠ¨æŠ˜è¡Œï¼ˆAuto Fill)的辅模å¼å¾ˆæœ‰ç”¨ï¼Œç‰¹åˆ«æ˜¯åœ¨ç¼–辑自然语言文本
的时候。å¯ç”¨è‡ªåŠ¨æŠ˜è¡ŒåŽï¼ŒEmacs 会在你打字超出一行边界时自动替你æ¢è¡Œã€‚
-用 M-x auto fill mode<Return> å¯åŠ¨è‡ªåŠ¨æŠ˜è¡Œæ¨¡å¼ã€‚å†ç”¨ä¸€æ¬¡è¿™æ¡å‘½ä»¤ï¼Œè‡ªåЍ
-折行模å¼ä¼šè¢«å…³é—­ã€‚ä¹Ÿå°±æ˜¯è¯´ï¼Œå¦‚æžœè‡ªåŠ¨æŠ˜è¡Œæ¨¡å¼æ²¡æœ‰è¢«å¼€å¯ï¼Œè¿™ä¸ªå‘½ä»¤ä¼šå¼€å¯
-它;如果已ç»å¼€å¯äº†ï¼Œè¿™ä¸ªå‘½ä»¤ä¼šå…³é—­å®ƒã€‚所以我们说,这个命令å¯ä»¥ç”¨æ¥â€œå¼€
-关(toggleï¼‰â€æ¨¡å¼ã€‚
+用 M-x auto-fill-mode <Return> å¯åŠ¨è‡ªåŠ¨æŠ˜è¡Œæ¨¡å¼ã€‚å†ç”¨ä¸€æ¬¡è¿™æ¡å‘½ä»¤ï¼Œè‡ª
+动折行模å¼ä¼šè¢«å…³é—­ã€‚ä¹Ÿå°±æ˜¯è¯´ï¼Œå¦‚æžœè‡ªåŠ¨æŠ˜è¡Œæ¨¡å¼æ²¡æœ‰è¢«å¼€å¯ï¼Œè¿™ä¸ªå‘½ä»¤ä¼šå¼€
+å¯å®ƒï¼›å¦‚果已ç»å¼€å¯äº†ï¼Œè¿™ä¸ªå‘½ä»¤ä¼šå…³é—­å®ƒã€‚所以我们说,这个命令å¯ä»¥ç”¨æ¥
+“开关(toggleï¼‰â€æ¨¡å¼ã€‚
->> 现在输入 M-x auto fill mode<Return>。然åŽéšä¾¿æ•²ç‚¹ä»€ä¹ˆï¼Œç›´åˆ°ä½ çœ‹åˆ°å®ƒ
+>> 现在输入 M-x auto-fill-mode <Return>。然åŽéšä¾¿æ•²ç‚¹ä»€ä¹ˆï¼Œç›´åˆ°ä½ çœ‹åˆ°å®ƒ
分æˆä¸¤è¡Œã€‚你必须敲一些空格,因为 Auto Fill åªåœ¨ç©ºç™½å¤„进行断行。
ã€è¾“入空格对英文æ¥è¯´æ˜¯å¿…须的,而对中文则ä¸å¿…。】
@@ -680,12 +673,11 @@ mode)存在。辅模å¼å¹¶ä¸èƒ½æ›¿ä»£ä¸»æ¨¡å¼ï¼Œè€Œæ˜¯æä¾›ä¸€äº›è¾…助的å
* æœç´¢ï¼ˆSEARCHING)
-------------------
-Emacs å¯ä»¥å‘剿ˆ–å‘åŽæœç´¢å­—符串。æœç´¢å‘½ä»¤æ˜¯ä¸€ä¸ªç§»åŠ¨å…‰æ ‡çš„å‘½ä»¤ï¼šæœç´¢æˆåŠŸ
-åŽï¼Œå…‰æ ‡ä¼šåœç•™åœ¨æœç´¢ç›®æ ‡å‡ºçŽ°çš„åœ°æ–¹ã€‚
+Emacs å¯ä»¥å‘剿ˆ–å‘åŽæœç´¢å­—ç¬¦ä¸²ï¼ˆâ€œå­—ç¬¦ä¸²â€æŒ‡çš„æ˜¯ä¸€ç»„连续的字符)。æœç´¢å‘½
+令是一个移动光标的命令:æœç´¢æˆåŠŸåŽï¼Œå…‰æ ‡ä¼šåœç•™åœ¨æœç´¢ç›®æ ‡å‡ºçŽ°çš„åœ°æ–¹ã€‚
-Emacs çš„æœç´¢å‘½ä»¤çš„独特之处在于,它是“æ¸è¿›çš„(incremental)â€ã€‚æ„æ€æ˜¯æœ
-ç´¢ä¸Žè¾“å…¥åŒæ—¶è¿›è¡Œï¼šä½ åœ¨é”®ç›˜ä¸Šä¸€å­—一å¥åœ°è¾“å…¥æœç´¢è¯çš„过程中,Emacs 就已ç»
-开始替你æœç´¢äº†ã€‚
+Emacs çš„æœç´¢å‘½ä»¤æ˜¯â€œæ¸è¿›çš„(incremental)â€ã€‚æ„æ€æ˜¯æœç´¢ä¸Žè¾“å…¥åŒæ—¶è¿›è¡Œï¼š
+你在键盘上一字一å¥åœ°è¾“å…¥æœç´¢è¯çš„过程中,Emacs 就已ç»å¼€å§‹æ›¿ä½ æœç´¢äº†ã€‚
C-s 是å‘剿œç´¢ï¼ŒC-r 是å‘åŽæœç´¢ã€‚ä¸è¿‡æ‰‹åˆ«è¿™ä¹ˆå¿«ï¼åˆ«ç€æ€¥è¯•。
@@ -696,7 +688,7 @@ C-s 是å‘剿œç´¢ï¼ŒC-r 是å‘åŽæœç´¢ã€‚ä¸è¿‡æ‰‹åˆ«è¿™ä¹ˆå¿«ï¼åˆ«ç€æ€¥è¯•
慢慢输入“cursorâ€è¿™ä¸ªè¯ï¼Œæ¯æ•²ä¸€ä¸ªå­—都åœé¡¿ä¸€ä¸‹å¹¶è§‚察光标。
çŽ°åœ¨ä½ åº”è¯¥å·²æ›¾ç»æ‰¾åˆ°â€œcursorâ€è¿™ä¸ªè¯äº†ã€‚
>> 冿Œ‰ä¸€æ¬¡ C-s,æœç´¢ä¸‹ä¸€ä¸ªâ€œcursorâ€å‡ºçŽ°çš„ä½ç½®ã€‚
->> 现在按四次退格键,看看光标是如何移动的。
+>> 现在按四次 <DEL> ,看看光标是如何移动的。
>> 敲 <Return> ç»“æŸæœç´¢ã€‚
看仔细了么?在一次æ¸è¿›å¼æœç´¢ä¸­ï¼ŒEmacs 会å°è¯•跳到æœç´¢ç›®æ ‡å‡ºçŽ°çš„ä½ç½®ã€‚è¦
@@ -705,19 +697,14 @@ C-s 是å‘剿œç´¢ï¼ŒC-r 是å‘åŽæœç´¢ã€‚ä¸è¿‡æ‰‹åˆ«è¿™ä¹ˆå¿«ï¼åˆ«ç€æ€¥è¯•
现 C-g 会让光标回到æœç´¢å¼€å§‹çš„ä½ç½®ï¼Œè€Œ <Return> 则让光标留在æœç´¢ç»“果上,
这是很有用的功能。】
-注æ„:在æŸäº›ç»ˆç«¯ä¸‹ï¼Œè¾“å…¥ C-x C-s 会冻结å±å¹•ã€å±å¹•没有任何输出】,使你看
-ä¸åˆ° Emacs 的任何å˜åŒ–。其原因是æ“作系统的“æµé‡æŽ§åˆ¶â€åŠŸèƒ½æ‹¦æˆªäº† C-s å¹¶
-冻结了å±å¹•。用 C-q å¯ä»¥è§£é™¤å±å¹•冻结。è¦è§£å†³è¿™ä¸ªé—®é¢˜ï¼Œè¯·å‚考 Emacs 手册
-里的“Spontaneous Entry to Incremental Searchâ€ä¸€èŠ‚ã€Emacs 手册å¯èƒ½è¿˜æ²¡
-有中文翻译】,那里æä¾›äº†ä¸€äº›æœ‰ç”¨çš„建议。
-
-在æ¸è¿›å¼æœç´¢ä¸­ï¼ŒæŒ‰é€€æ ¼é”®ä¼šåˆ é™¤ç›®æ ‡å­—符串的最åŽä¸€ä¸ªå­—符,并且光标会回到
-最近一次æœç´¢çš„命中ä½ç½®ã€‚比如你已ç»è¾“入了“câ€ï¼Œå…‰æ ‡å°±åœåœ¨â€œcâ€ç¬¬ä¸€æ¬¡å‡º
-现的ä½ç½®ï¼Œå†è¾“入“uâ€ï¼Œå…‰æ ‡åœåœ¨â€œcuâ€ç¬¬ä¸€æ¬¡å‡ºçŽ°çš„ä½ç½®ï¼Œè¿™æ—¶å†æŒ‰é€€æ ¼é”®ï¼Œ
-“uâ€å°±ä»Žæœç´¢å­—串中消失了,然åŽå…‰æ ‡ä¼šå›žåˆ°â€œcâ€ç¬¬ä¸€æ¬¡å‡ºçŽ°çš„ä½ç½®ã€‚
+在æ¸è¿›å¼æœç´¢ä¸­ï¼ŒæŒ‰ <DEL> 会“撤回â€åˆ°æœ€è¿‘一次æœç´¢çš„命中ä½ç½®ã€‚å¦‚æžœä¹‹å‰æ²¡
+有一个命中, <DEL> 会抹去æœç´¢å­—符串中的最åŽä¸€ä¸ªå­—符。比如你已ç»è¾“入了
+“câ€ï¼Œå…‰æ ‡å°±åœåœ¨â€œcâ€ç¬¬ä¸€æ¬¡å‡ºçŽ°çš„ä½ç½®ï¼Œå†è¾“入“uâ€ï¼Œå…‰æ ‡åœåœ¨â€œcuâ€ç¬¬ä¸€æ¬¡å‡ºçް
+çš„ä½ç½®ï¼Œè¿™æ—¶å†æŒ‰ <DEL> ,“uâ€å°±ä»Žæœç´¢å­—串中消失了,然åŽå…‰æ ‡ä¼šå›žåˆ°â€œcâ€ç¬¬
+一次出现的ä½ç½®ã€‚
-å¦å¤–,如果你在æœç´¢çš„æ—¶å€™è¾“入了 CONTROL 或者 META 组åˆé”®çš„è¯ï¼Œæœç´¢å¯èƒ½ä¼š
-结æŸã€‚(也有例外,比如 C-s å’Œ M-r 这些用于æœç´¢çš„命令。)
+å¦å¤–,如果你在æœç´¢çš„æ—¶å€™è¾“入了 control 或者 meta 组åˆé”®çš„è¯ï¼Œæœç´¢å¯èƒ½ä¼š
+结æŸã€‚(也有例外,比如 C-s å’Œ C-r 这些用于æœç´¢çš„命令。)
å‰é¢è¯´çš„都是“å‘ä¸‹â€æœç´¢ï¼Œå¦‚果想“å‘ä¸Šâ€æœç´¢ï¼Œå¯ä»¥ç”¨ C-r。C-r 与 C-s
相比除了æœç´¢æ–¹å‘相å之外,其余的æ“作都一样。
@@ -728,7 +715,7 @@ C-s 是å‘剿œç´¢ï¼ŒC-r 是å‘åŽæœç´¢ã€‚ä¸è¿‡æ‰‹åˆ«è¿™ä¹ˆå¿«ï¼åˆ«ç€æ€¥è¯•
Emacs 的迷人之处很多,能够在å±å¹•ä¸ŠåŒæ—¶æ˜¾ç¤ºå¤šä¸ªçª—格就是其中之一。
->> 移动光标到这一行,然åŽè¾“å…¥ C-u 0 C-l。
+>> 移动光标到这一行,然åŽè¾“å…¥ C-l C-l。
>> 现在输入 C-x 2,它会将å±å¹•划分æˆä¸¤ä¸ªçª—格。
这两个窗格里显示的都是本篇快速指å—,而光标则åœç•™åœ¨ä¸Šæ–¹çš„窗格里。
@@ -746,18 +733,17 @@ Emacs 的迷人之处很多,能够在å±å¹•ä¸ŠåŒæ—¶æ˜¾ç¤ºå¤šä¸ªçª—格就是å…
>> å†è¾“å…¥ C-x o 将光标移回到上方的窗格里。
光标会回到它在上方窗格中原本所在的ä½ç½®ã€‚
-连续使用 C-x o å¯ä»¥é历所有窗格。æ¯ä¸€ä¸ªçª—格都有它自己的光标ä½ç½®ï¼Œä½†æ˜¯åª
-有一个窗格会真正显示这个光标。ã€å…¶å®ƒçª—格在控制å°ä¸‹ä¸ä¼šæ˜¾ç¤ºå…‰æ ‡ï¼Œåœ¨å›¾å½¢
-窗å£ä¸‹ç¼ºçœæ˜¾ç¤ºä¸ºé•‚空光标。】一般所有的编辑命令都作用于这个光标所在的窗
-格,我们称这个窗格为“被选中的窗格â€ã€‚
+连续使用 C-x o å¯ä»¥é历所有窗格。“被选中的窗格â€ï¼Œä¹Ÿå°±æ˜¯ç»å¤§å¤šæ•°çš„编辑
+æ“作所å‘ç”Ÿçš„åœ°æ–¹ï¼Œæ˜¯åœ¨ä½ ä¸æ‰“å­—æ—¶é—ªçƒå…‰æ ‡çš„那个窗格。其他的窗格有它们自
+己的光标ä½ç½®ï¼› 如果你在图形界é¢ä¸‹è¿è¡Œ Emacs ,这些光标是镂空的长方形。
当你在一个窗格中编辑,但用å¦ä¸€ä¸ªçª—格作为å‚考的时候,C-M-v 是很有用的命
-令。你å¯ä»¥å§‹ç»ˆå¤„于编辑窗格中,然åŽç”¨ C-M-v 命令滚动å¦å¤–ä¸€ä¸ªçª—æ ¼ã€‚ã€æ¯”如
-翻译和校对就很适åˆç”¨è¿™ç§æ–¹å¼è¿›è¡Œã€‚】
+令。无需离开被选中的窗格,你就å¯ä»¥ç”¨ C-M-v 命令滚动å¦å¤–一个窗格中的文
+å­—ã€‚ã€æ¯”如翻译和校对就很适åˆç”¨è¿™ç§æ–¹å¼è¿›è¡Œã€‚】
-C-M-v 是一个 CONTROL-META 组åˆé”®ã€‚如果你有 META 键的è¯ï¼Œå¯ä»¥åŒæ—¶æŒ‰ä½
-CONTROL å’Œ META 键并输入 v。CONTROL å’Œ META 键先按哪个都å¯ä»¥ï¼Œå› ä¸ºå®ƒä»¬
-åªæ˜¯ç”¨æ¥â€œä¿®é¥°ï¼ˆmodify)â€ä½ è¾“入的字符的。
+C-M-v 是一个 CONTROL-META 组åˆé”®ã€‚如果你有 META (或 Alt)键的è¯ï¼Œå¯ä»¥
+åŒæ—¶æŒ‰ä½CONTROL å’Œ META 键并输入 v。CONTROL å’Œ META 键先按哪个都å¯ä»¥ï¼Œ
+å› ä¸ºå®ƒä»¬åªæ˜¯ç”¨æ¥â€œä¿®é¥°ï¼ˆmodify)â€ä½ è¾“入的字符的。
如果你并没有 META 键,你也å¯ä»¥ç”¨ ESC æ¥ä»£æ›¿ï¼Œä¸è¿‡è¿™æ ·çš„è¯å°±è¦æ³¨æ„按键顺
åºäº†ï¼šä½ å¿…须先输入 ESC ,然åŽå†è¾“å…¥ CONTROL-v。CONTROL-ESC v 是没用的,
@@ -779,6 +765,26 @@ CONTROL å’Œ META 键并输入 v。CONTROL å’Œ META 键先按哪个都å¯ä»¥ï¼Œå›
>> 输入 C-x o 回到上方的窗格,然åŽå†ç”¨ C-x 1 关掉下方窗格。
+* 多窗å£ï¼ˆMULTIPLE FRAMES)
+------------------
+
+Emacs å¯ä»¥åˆ›å»ºå¤šä¸ªçª—å£ã€‚窗å£ç”±è®¸å¤šçª—格以åŠèœå•ã€æ»šåЍæ¡ã€å›žæ˜¾åŒºç­‰ç»„æˆã€‚
+在图形界é¢ä¸‹ï¼Œå¤šä¸ªçª—å£å¯ä»¥åŒæ—¶æ˜¾ç¤ºå‡ºæ¥ã€‚在文本终端中,åªèƒ½åŒæ—¶æ˜¾ç¤ºä¸€ä¸ª
+窗å£ã€‚
+
+>> 输入 M-x make-frame <Return>。
+ å¯ä»¥çœ‹åˆ°ä¸€ä¸ªæ–°çš„窗å£å‡ºçŽ°åœ¨äº†ä½ çš„å±å¹•上。
+
+ä½ å¯ä»¥åœ¨æ–°çš„窗å£é‡Œåšæœ€åˆçš„窗å£é‡Œå¯ä»¥åšçš„ä»»ä½•äº‹æƒ…ã€‚ç¬¬ä¸€ä¸ªçª—å£æ²¡æœ‰ä»€ä¹ˆç‰¹
+别的。
+
+>> 输入 M-x delete-frame <Return>.
+ 这个命令将会关闭选中的窗å£ã€‚
+
+你也å¯ä»¥é€šè¿‡å›¾å½¢ç³»ç»Ÿæ¥å…³é—­æŸä¸ªçª—å£ï¼ˆé€šå¸¸æ˜¯åœ¨çª—å£ä¸Šé¢çš„æŸä¸ªè§’è½é‡Œçš„一个
+“Xâ€æŒ‰é’®ï¼‰ã€‚如果你关闭的是 Emacs 进程的最åŽä¸€ä¸ªçª—å£ï¼Œ Emacs 将会退出。
+
+
* 递归编辑(RECURSIVE EDITING LEVELS)
--------------------------------------
@@ -810,9 +816,7 @@ CONTROL å’Œ META 键并输入 v。CONTROL å’Œ META 键先按哪个都å¯ä»¥ï¼Œå›
么帮助。如果你连自己到底需è¦ä»€ä¹ˆå¸®åŠ©éƒ½ä¸çŸ¥é“,那么就输入 C-h ?,Emacs
会告诉你它能æä¾›äº†å“ªäº›å¸®åŠ©ã€‚å¦‚æžœä½ æŒ‰äº† C-h åˆæƒ³å悔,å¯ä»¥ç”¨ C-g å–æ¶ˆã€‚
-(有些主机改å˜äº† C-h çš„æ„义,这ç§ä»¥å·±åº¦äººå¤–åŠ ä¸€åˆ€åˆ‡çš„åšæ³•确实ä¸å¤ªå¥½ï¼Œä¸
-过倒是让你å¯ä»¥ä¹‰æ­£è¾žä¸¥åœ°æŠ±æ€¨ä»–们的系统管ç†å‘˜ã€‚è¯è¯´å›žæ¥ï¼Œå¦‚果你按 C-h 之
-åŽæ²¡æœ‰ä»»ä½•å¸®åŠ©ä¿¡æ¯æ˜¾ç¤ºå‡ºæ¥ï¼Œé‚£ä¹ˆè¯•试 F1 键或者 M-x help <Return> 。)
+(如果你按 C-h ä¹‹åŽæ²¡æœ‰ä»»ä½•å¸®åŠ©ä¿¡æ¯æ˜¾ç¤ºå‡ºæ¥ï¼Œé‚£ä¹ˆè¯•试 F1 键或者 M-x help <Return> 。)
最基本的帮助功能是 C-h c。输入 C-h c 之åŽå†è¾“入一个组åˆé”®ï¼ŒEmacs 会给出
这个命令的简è¦è¯´æ˜Žã€‚
@@ -823,9 +827,9 @@ CONTROL å’Œ META 键并输入 v。CONTROL å’Œ META 键先按哪个都å¯ä»¥ï¼Œå›
C-p runs the command previous-line
-è¿™æ¡æ¶ˆæ¯æ˜¾ç¤ºäº† C-p 命令对应的函数å,函数å主è¦ç”¨æ¥å®šåˆ¶å’Œæ‰©å±• Emacs。命
-令的功能由函数完æˆï¼Œæ‰€ä»¥å‡½æ•°å本身也å¯ä»¥è¢«çœ‹æˆæ˜¯æœ€ç®€å•的文档――至少对
-于你已ç»å­¦è¿‡çš„命令æ¥è¯´ï¼Œå®ƒä»¬çš„函数å足以解释它们的功能了。
+è¿™æ¡æ¶ˆæ¯æ˜¾ç¤ºäº† C-p 命令对应的函数å。命令的功能由函数完æˆï¼Œæ‰€ä»¥å‡½æ•°å
+本身也å¯ä»¥è¢«çœ‹æˆæ˜¯æœ€ç®€å•的文档――至少对于你已ç»å­¦è¿‡çš„命令æ¥è¯´ï¼Œå®ƒä»¬çš„函
+æ•°å足以解释它们的功能了。
多字符命令一样å¯ä»¥ç”¨ C-h c æ¥æŸ¥çœ‹ã€‚
@@ -841,7 +845,7 @@ CONTROL å’Œ META 键并输入 v。CONTROL å’Œ META 键先按哪个都å¯ä»¥ï¼Œå›
C-h f 解释一个函数。需è¦è¾“入函数å。
->> 试试看,输入 C-h f previous-line<Return>。
+>> 试试看,输入 C-h f previous-line <Return>。
Emacs 会给出它所知é“的所有有关“实现 C-p 命令功能的函数â€çš„ä¿¡æ¯ã€‚
C-h v ç”¨æ¥æ˜¾ç¤º Emacs å˜é‡çš„æ–‡æ¡£ã€‚Emacs å˜é‡å¯ä»¥è¢«ç”¨æ¥â€œå®šåˆ¶ Emacs 的行
@@ -852,7 +856,7 @@ C-h v ç”¨æ¥æ˜¾ç¤º Emacs å˜é‡çš„æ–‡æ¡£ã€‚Emacs å˜é‡å¯ä»¥è¢«ç”¨æ¥â€œå®šåˆ¶
的命令。这些命令全都å¯ä»¥ç”¨ M-x æ¥å¯åŠ¨ã€‚å¯¹äºŽæŸäº›å‘½ä»¤æ¥è¯´ï¼Œ
相关命令æœç´¢è¿˜ä¼šåˆ—出一两个组åˆé”®ã€‚
->> 输入 C-h a file<Return>。
+>> 输入 C-h a file <Return>。
Emacs 会在å¦ä¸€ä¸ªçª—格里显示一个 M-x 命令列表,这个列表包å«äº†æ‰€æœ‰å称中å«
有“fileâ€çš„命令。你å¯ä»¥çœ‹åˆ°åƒâ€œC-x C-fâ€è¿™æ ·çš„组åˆé”®æ˜¾ç¤ºåœ¨â€œfind-fileâ€
@@ -862,7 +866,7 @@ Emacs 会在å¦ä¸€ä¸ªçª—格里显示一个 M-x 命令列表,这个列表包å«
>> 输入 C-x 1 æ¥åˆ é™¤ help 窗格。
- C-h i é˜…è¯»è”æœºæ‰‹å†Œï¼ˆä¹Ÿå°±æ˜¯é€šå¸¸è®²çš„ Info)。
+ C-h i 阅读手册(也就是通常讲的 Info)。
这个命令会打开一个称为“*info*â€çš„特殊缓冲区,在那里,
ä½ å¯ä»¥é˜…读安装在系统里的软件包使用手册。è¦è¯» Emacs 的使
用手册,按 m emacs <Return> å°±å¯ä»¥äº†ã€‚如果你之å‰ä»Žæ²¡ç”¨
@@ -875,18 +879,19 @@ Emacs 会在å¦ä¸€ä¸ªçª—格里显示一个 M-x 命令列表,这个列表包å«
---------------------------
想学习更多的使用技巧,Emacs 使用手册(manual)值得一读。你å¯ä»¥è¯»çº¸ç‰ˆçš„
-书,也å¯ä»¥çœ‹ç”µå­ç‰ˆçš„è”æœºæ‰‹å†Œï¼ˆå¯ä»¥ä»Ž Help èœå•进入或者按 F10 h r)。æ
-两个你å¯èƒ½ä¼šå¾ˆæ„Ÿå…´è¶£çš„功能å§ï¼Œä¸€ä¸ªæ˜¯å¯ä»¥å¸®ä½ å°‘敲键盘的 completion(自动
-补全),å¦ä¸€ä¸ªæ˜¯æ–¹ä¾¿æ–‡ä»¶å¤„ç†çš„ dired(目录编辑)。
+书,也å¯ä»¥åœ¨ Emacs 中读(å¯ä»¥ä»Ž Help èœå•进入或者按 C-h r)。æä¸¤ä¸ªä½ 
+å¯èƒ½ä¼šå¾ˆæ„Ÿå…´è¶£çš„功能å§ï¼Œä¸€ä¸ªæ˜¯å¯ä»¥å¸®ä½ å°‘敲键盘的 completion(自动补全),
+å¦ä¸€ä¸ªæ˜¯æ–¹ä¾¿æ–‡ä»¶å¤„ç†çš„ dired(目录编辑)。
Completion å¯ä»¥æ›¿ä½ èŠ‚çœä¸å¿…è¦çš„键盘输入。比如说你想切æ¢åˆ° *Message* 缓
冲区,你就å¯ä»¥ç”¨ C-x b *M<Tab> æ¥å®Œæˆã€‚åªè¦ Emacs 能够根æ®ä½ å·²ç»è¾“入的
-文字确定你想è¦è¾“入的内容,它就会自动帮你补é½ã€‚有关 Completion 的详细说
-明å¯ä»¥åœ¨ Emacs Info 中的“Completionâ€ä¸€èŠ‚é‡Œæ‰¾åˆ°ã€‚
+文字确定你想è¦è¾“入的内容,它就会自动帮你补é½ã€‚Completion 也å¯ç”¨äºŽå‘½ä»¤
+å和文件å。有关 Completion 的详细说明å¯ä»¥åœ¨ Emacs Info 中的
+“Completionâ€ä¸€èŠ‚é‡Œæ‰¾åˆ°ã€‚
Dired 能够在一个缓冲区里列出一个目录下的所有文件(å¯ä»¥é€‰æ‹©æ˜¯å¦ä¹Ÿåˆ—出å­
目录),然åŽä½ å¯ä»¥åœ¨è¿™ä¸ªæ–‡ä»¶åˆ—表上完æˆå¯¹æ–‡ä»¶çš„移动ã€è®¿é—®ã€é‡å‘½å或删除
-等等æ“作。Dired 也在 Emacs Info 中有详细介ç»ï¼Œå‚è§â€œDiredâ€ä¸€èŠ‚ã€‚
+等等æ“作。Dired 也在 Emacs 使用手册中有详细介ç»ï¼Œå‚è§â€œDiredâ€ä¸€èŠ‚ã€‚
Emacs 使用手册里还有许许多多的精彩功能等ç€ä½ æ¥äº†è§£ã€‚
@@ -894,8 +899,7 @@ Emacs 使用手册里还有许许多多的精彩功能等ç€ä½ æ¥äº†è§£ã€‚
* 总结(CONCLUSION)
--------------------
-è®°ä½ï¼Œè¦é€€å‡º Emacs 请用 C-x C-cã€‚è¦æš‚æ—¶åˆ‡æ¢åˆ° shell 并且ç¨åŽå†å›žåˆ°
-Emacs 里æ¥ï¼Œè¯·ç”¨ C-z。ã€åˆ‡æ¢åˆ° shell 仅对控制å°ä¸‹çš„ Emacs 有效】
+è¦é€€å‡º Emacs 请用 C-x C-c。
æœ¬æ–‡å®Œå…¨æ˜¯ä¸ºé›¶èµ·ç‚¹æ–°æ‰‹æ‰€å†™çš„èµ·æ­¥æ•™ç¨‹ã€‚å¦‚æžœä½ è§‰å¾—å“ªé‡Œè¿˜çœ‹ä¸æ˜Žç™½ï¼Œåƒä¸‡ä¸
è¦æ€€ç–‘è‡ªå·±ï¼Œé‚£ä¸€å®šæ˜¯æˆ‘ä»¬æ²¡æœ‰å†™å¥½ã€‚æˆ‘ä»¬æ°¸è¿œæ¬¢è¿Žä½ çš„ä¸æ»¡å’ŒæŠ±æ€¨ã€‚
@@ -905,6 +909,7 @@ Emacs 里æ¥ï¼Œè¯·ç”¨ C-z。ã€åˆ‡æ¢åˆ° shell 仅对控制å°ä¸‹çš„ Emacs 有æ•
---------------------
翻译:孙一江 <sunyijiang@gmail.com>
+维护:薛富侨 <xfq.free@gmail.com>
校对:水木社区(www.newsmth.net)Emacs æ¿ä¼—多网å‹åŠä¼—多 Emacs 中文用户
Emacs 快速指å—(Tutorial)早有两个刘昭å®çš„中文译本,ç¹ç®€å„一。其简体版本
@@ -915,11 +920,11 @@ Emacs 快速指å—(Tutorial)早有两个刘昭å®çš„中文译本,ç¹ç®€å„
的译文质é‡å¾ˆé«˜ï¼Œåœ¨ç¿»è¯‘过程中给予过我们许多借鉴和å‚考,在此对刘昭å®çš„工作
表示感谢。
-翻译过程中最大的挑战莫过于术语译è¯çš„选择了。ç»è¿‡æ°´æœ¨ç¤¾åŒº Emacs æ¿çƒ­å¿ƒç½‘
-å‹å°èŒƒå›´å†…的讨论,我们选择了现在的译法。用户的广泛å‚与是自由软件生命力
-çš„æºæ³‰ï¼Œæ‰€ä»¥å¦‚果你有任何建议ã€å‹˜è¯¯æˆ–想法,请用你喜欢的方å¼å‘我们æå‡ºã€‚
-ä½ å¯ä»¥é€šè¿‡ç”µå­é‚®ä»¶ç›´æŽ¥è”系译者,也å¯ä»¥æ”¾åˆ° GNU Emacs 的开å‘邮件列表或者
-水木社区的 Emacs æ¿ä¸Šè¿›è¡Œè®¨è®ºã€‚
+翻译过程中最大的挑战莫过于术语译è¯çš„选择了。ç»è¿‡æ°´æœ¨ç¤¾åŒº Emacs æ¿çƒ­å¿ƒ
+网å‹å°èŒƒå›´å†…的讨论,我们选择了现在的译法。用户的广泛å‚与是自由软件生命
+åŠ›çš„æºæ³‰ï¼Œæ‰€ä»¥å¦‚果你有任何建议ã€å‹˜è¯¯æˆ–想法,请用你喜欢的方å¼å‘我们æå‡ºã€‚
+ä½ å¯ä»¥é€šè¿‡ç”µå­é‚®ä»¶ç›´æŽ¥è”系维护者,也å¯ä»¥æ”¾åˆ° GNU Emacs 的开å‘邮件列表
+或者水木社区的 Emacs æ¿ä¸Šè¿›è¡Œè®¨è®ºã€‚
下é¢åˆ—å‡ºä¸»è¦æœ¯è¯­çš„译è¯å¯¹ç…§ï¼Œå¹¶ç»™å‡ºæ³¨é‡Šè¯´æ˜Žï¼š
@@ -941,6 +946,8 @@ Emacs 快速指å—(Tutorial)早有两个刘昭å®çš„中文译本,ç¹ç®€å„
search æœç´¢
incremental search æ¸è¿›å¼æœç´¢ [3]
+对于其他没有æåˆ°çš„æœ¯è¯­ï¼Œè¯»è€…å¯ä»¥å‚考 Emacs 使用手册里的术语表。
+
[1] “windowâ€ä¸€è¯åœ¨è®¡ç®—机相关的领域一般都被译为“窗å£â€ã€‚但是在 Emacs
中,还有一个“frameâ€çš„æ¦‚念。在被广泛使用的 X 窗å£ç³»ç»Ÿå’Œå¾®è½¯çš„视窗
(Windows)系列æ“作系统中,Emacs 的一个“frameâ€å°±æ˜¯ä¸€ä¸ªâ€œçª—å£â€ï¼Œå› 
@@ -977,46 +984,56 @@ Emacs 快速指å—(Tutorial)早有两个刘昭å®çš„中文译本,ç¹ç®€å„
This tutorial descends from a long line of Emacs tutorials
starting with the one written by Stuart Cracraft for the original Emacs.
-This version of the tutorial, like GNU Emacs, is copyrighted, and
-comes with permission to distribute copies on certain conditions:
+This version of the tutorial is a part of GNU Emacs. It is copyrighted
+and comes with permission to distribute copies on certain conditions:
+
+ Copyright (C) 1985, 1996, 1998, 2001-2013 Free Software Foundation,
+ Inc.
+
+ This file is part of GNU Emacs.
-Copyright (C) 1985, 1996, 1998, 2001-2013 Free Software Foundation, Inc.
+ GNU Emacs is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
- Permission is granted to anyone to make or distribute verbatim copies
- of this document as received, in any medium, provided that the
- copyright notice and permission notice are preserved,
- and that the distributor grants the recipient permission
- for further redistribution as permitted by this notice.
+ GNU Emacs is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
- Permission is granted to distribute modified versions
- of this document, or of portions of it,
- under the above conditions, provided also that they
- carry prominent notices stating who last altered them.
+ You should have received a copy of the GNU General Public License
+ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
-The conditions for copying Emacs itself are more complex, but in the
-same spirit. Please read the file COPYING and then do give copies of
-GNU Emacs to your friends. Help stamp out software obstructionism
-("ownership") by using, writing, and sharing free software!
+Please read the file COPYING and then do give copies of GNU Emacs to
+your friends. Help stamp out software obstructionism ("ownership") by
+using, writing, and sharing free software!
ã€ä¸‹é¢ä¸ºç‰ˆæƒå£°æ˜Žçš„译文,仅供å‚考。实际法律效力以英文原文为准。】
æœ¬å¿«é€ŸæŒ‡å—æ²¿è¢­è‡ªåކ岿‚ ä¹…çš„ Emacs 快速指å—,å¯ä¸Šæº¯è‡³ Stuart Cracraft 为最
åˆçš„ Emacs 所作的版本。
-本篇文档与 GNU Emacs 一样拥有版æƒï¼Œå¹¶å…许在下列æ¡ä»¶çš„约æŸä¸‹å‘行其拷è´ï¼š
+æœ¬ç¯‡æŒ‡å—æ˜¯ GNU Emacs 的一部分,并å…许在下列æ¡ä»¶çš„约æŸä¸‹å‘行其拷è´ï¼š
+
+ Copyright (C) 1985, 1996, 1998, 2001-2013 Free Software Foundation,
+ Inc.
+
+ 本文件为 GNU Emacs 的一部分。
- Copyright (C) 1985, 1996, 1998, 2001-2013 Free Software Foundation, Inc.
+ GNU Emacs 为自由软件;您å¯ä¾æ®è‡ªç”±è½¯ä»¶åŸºé‡‘会所å‘表的GNU通用公共授æƒ
+ æ¡æ¬¾ï¼Œå¯¹æœ¬ç¨‹åºå†æ¬¡å‘布和/æˆ–ä¿®æ”¹ï¼›æ— è®ºæ‚¨ä¾æ®çš„æ˜¯æœ¬æŽˆæƒçš„第三版,或
+ (您å¯é€‰çš„)任一日åŽå‘行的版本。
- 本文档å…许在ä¸å˜æ›´æ–‡æ¡£å†…容的情况下由任何人å‘å¸ƒåœ¨ä»»ä½•åª’ä½“ä¸Šï¼ŒåŒæ—¶å¿…é¡»
- 完整ä¿ç•™ç‰ˆæƒå’Œè®¸å¯å£°æ˜Žï¼Œä¸”需给予å—众与å‘行者完全相åŒçš„ã€å¦‚本声明所å…
- è®¸çš„å†æ¬¡å‘行本文档的æƒåˆ©ã€‚
+ GNU Emacs 是基于使用目的而加以å‘布,然而ä¸è´Ÿä»»ä½•æ‹…ä¿è´£ä»»ï¼›äº¦æ— å¯¹é€‚
+ 售性或特定目的适用性所为的默示性担ä¿ã€‚详情请å‚ç…§GNU通用公共授æƒã€‚
- 本声明å…许在与上述æ¡ä»¶ç›¸åŒçš„æƒ…况下å‘布ç»è¿‡ä¿®æ”¹çš„å…¨éƒ¨æˆ–éƒ¨åˆ†æ–‡æ¡£ï¼ŒåŒæ—¶
- 必须附带显è¦çš„æ–‡å­—以申明文档的最åŽä¿®æ”¹è€…。
+ 您应已收到附éšäºŽ GNU Emacs çš„GNU通用公共授æƒçš„副本;如果没有,请å‚ç…§
+ <http://www.gnu.org/licenses/>.
-Emacs 自身的版æƒé—®é¢˜è™½æ¯”本文档è¦å¤æ‚一些,但也基于相åŒçš„精神。敬请阅读文
-件“COPYINGâ€ï¼Œç„¶åŽå‘你的朋å‹ä»¬åˆ†å‘ GNU Emacs æ‹·è´ã€‚让我们以使用ã€ç¼–写和
-分享自由软件的实际行动æ¥å…±åŒç¥›é™¤è½¯ä»¶éšœç¢ä¸»ä¹‰ï¼ˆæ‰€è°“的“所有æƒâ€ï¼‰ï¼
+敬请阅读文件“COPYINGâ€ï¼Œç„¶åŽå‘你的朋å‹ä»¬åˆ†å‘ GNU Emacs æ‹·è´ã€‚让我们以使
+用ã€ç¼–写和分享自由软件的实际行动æ¥å…±åŒç¥›é™¤è½¯ä»¶éšœç¢ä¸»ä¹‰ï¼ˆæ‰€è°“的“所有
+æƒâ€ï¼‰ï¼
;;; Local Variables:
;;; coding: utf-8
diff --git a/etc/tutorials/TUTORIAL.es b/etc/tutorials/TUTORIAL.es
index e8a23e6d7a4..15b0a4e26bf 100644
--- a/etc/tutorials/TUTORIAL.es
+++ b/etc/tutorials/TUTORIAL.es
@@ -285,7 +285,7 @@ Explicaremos después como usar múltiples ventanas. Ahora mismo
queremos explicar cómo deshacerse de ventanas adicionales y volver a
la edición básica en una ventana. Es sencillo:
- C-x 1 Una ventana (p.ej., elimina todas las otras ventanas).
+ C-x 1 Una ventana (es decir, elimina todas las demás ventanas).
Esto es CONTROL-x seguido por el dígito 1. C-x 1 expande la ventana que
contiene el cursor, para ocupar toda la pantalla. Esto borra todas las
@@ -374,7 +374,7 @@ resumen de las operaciones de borrado:
Note que <DEL> y C-d, comparados con M-<DEL> y M-d, extienden el
paralelismo iniciado por C-f y M-f (bien, <DEL> no es realmente una
tecla de control, pero no nos preocuparemos de eso ahora). C-k y M-k,
-en ciertas forma, son como C-e y M-e, en que las líneas de unos
+en cierta forma, son como C-e y M-e, en que las líneas de unos
corresponden a sentencias en los otros.
También puede eliminar un segmento contiguo de texto con un método
diff --git a/etc/tutorials/TUTORIAL.translators b/etc/tutorials/TUTORIAL.translators
index 3ec948eb79a..25897d753a6 100644
--- a/etc/tutorials/TUTORIAL.translators
+++ b/etc/tutorials/TUTORIAL.translators
@@ -7,7 +7,7 @@ Maintainer: Ognyan Kulev <ogi@tower.3.bg>
* TUTORIAL.cn:
Author: Sun Yijiang <sunyijiang@gmail.com>
-Maintainer: Sun Yijiang <sunyijiang@gmail.com>
+Maintainer: Xue Fuqiao <xfq.free@gmail.com>
* TUTORIAL.cs:
Author: Milan Zamazal <pdm@zamazal.org>
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index d914582c280..5dfca6b8e2f 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -22,15 +22,208 @@
(vc-bzr-ignore-completion-table):
(vc-bzr-find-ignore-file): New functions.
+2013-08-04 Juanma Barranquero <lekktu@gmail.com>
+
+ * frameset.el (frameset-p, frameset-save): Fix autoload cookies.
+ (frameset-filter-minibuffer): Doc fix.
+ (frameset-restore): Fix autoload cookie. Fix typo in docstring.
+
+ * desktop.el (desktop-clear): Only delete frames when called
+ interactively and desktop-restore-frames is non-nil. Doc fix.
+ (desktop-read): Set desktop-saved-frameset to nil.
+
+2013-08-03 Juanma Barranquero <lekktu@gmail.com>
+
+ * frameset.el (frameset-prop): New function and setter.
+ (frameset-save): Do not modify frame list passed by the caller.
+
+2013-08-03 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * emacs-lisp/package.el (package-desc-from-define): Ignore unknown keys.
+
+2013-08-02 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * emacs-lisp/easy-mmode.el (define-globalized-minor-mode)
+ (easy-mmode-define-navigation): Avoid ((lambda (..) ..) ...).
+
+ * custom.el (custom-initialize-default, custom-initialize-set)
+ (custom-initialize-reset, custom-initialize-changed): Affect the
+ toplevel-default-value (bug#6275, bug#14586).
+ * emacs-lisp/advice.el (ad-compile-function): Undo previous workaround
+ for bug#6275.
+
+2013-08-02 Juanma Barranquero <lekktu@gmail.com>
+
+ * emacs-lisp/lisp-mode.el (lisp-imenu-generic-expression):
+ Add cl-def* expressions.
+
+ * frameset.el (frameset-filter-params): Fix order of arguments.
+
+2013-08-02 Juanma Barranquero <lekktu@gmail.com>
+
+ Move code related to saving frames to frameset.el.
+ * desktop.el: Require frameset.
+ (desktop-restore-frames): Doc fix.
+ (desktop-restore-reuses-frames): Rename from
+ desktop-restoring-reuses-frames.
+ (desktop-saved-frameset): Rename from desktop-saved-frame-states.
+ (desktop-clear): Clear frames too.
+ (desktop-filter-parameters-alist): Set from frameset-filter-alist.
+ (desktop--filter-tty*, desktop-save, desktop-read):
+ Use frameset functions.
+ (desktop-before-saving-frames-functions, desktop--filter-*-color)
+ (desktop--filter-minibuffer, desktop--filter-restore-desktop-parm)
+ (desktop--filter-save-desktop-parm, desktop--filter-iconified-position)
+ (desktop-restore-in-original-display-p, desktop--filter-frame-parms)
+ (desktop--process-minibuffer-frames, desktop-save-frames)
+ (desktop--reuse-list, desktop--compute-pos, desktop--move-onscreen)
+ (desktop--find-frame, desktop--select-frame, desktop--make-frame)
+ (desktop--sort-states, desktop-restoring-frames-p)
+ (desktop-restore-frames): Remove. Most code moved to frameset.el.
+ (desktop-restoring-frameset-p, desktop-restore-frameset)
+ (desktop--check-dont-save, desktop-save-frameset): New functions.
+ (desktop--app-id): New constant.
+ (desktop-first-buffer, desktop-buffer-ok-count)
+ (desktop-buffer-fail-count): Move before first use.
+ * frameset.el: New file.
+
+2013-08-01 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * files.el: Use lexical-binding.
+ (dir-locals-read-from-file): Remove unused `err' variable.
+ (hack-dir-local-variables--warned-coding): New var.
+ (hack-dir-local-variables): Use it to avoid repeated warnings.
+ (make-backup-file-name--default-function): New function.
+ (make-backup-file-name-function): Use it as default.
+ (buffer-stale--default-function): New function.
+ (buffer-stale-function): Use it as default.
+ (revert-buffer-insert-file-contents--default-function): New function.
+ (revert-buffer-insert-file-contents-function): Use it as default.
+ (insert-directory): Avoid add-to-list.
+
+ * autorevert.el (auto-revert-handler): Simplify.
+ Use buffer-stale--default-function.
+
+2013-08-01 Tassilo Horn <tsdh@gnu.org>
+
+ * speedbar.el (speedbar-query-confirmation-method): Doc fix.
+
+ * whitespace.el (whitespace-ensure-local-variables): New function.
+ (whitespace-cleanup-region): Call it.
+ (whitespace-turn-on): Call it.
+
+2013-08-01 Michael Albinus <michael.albinus@gmx.de>
+
+ Complete file name handlers.
+
+ * net/tramp.el (tramp-handle-set-visited-file-modtime)
+ (tramp-handle-verify-visited-file-modtime)
+ (tramp-handle-file-notify-rm-watch): New functions.
+ (tramp-call-process): Do not bind `default-directory'.
+
+ * net/tramp-adb.el (tramp-adb-file-name-handler-alist):
+ Order alphabetically.
+ [access-file, add-name-to-file, dired-call-process]:
+ [dired-compress-file, file-acl, file-notify-rm-watch]:
+ [file-ownership-preserved-p, file-selinux-context]:
+ [make-directory-internal, make-symbolic-link, set-file-acl]:
+ [set-file-selinux-context, set-visited-file-modtime]:
+ [verify-visited-file-modtime]: Add handler.
+ (tramp-adb-handle-write-region): Apply `set-visited-file-modtime'.
+
+ * net/tramp-gvfs.el (tramp-gvfs-file-name-handler-alist)
+ [file-notify-add-watch, file-notify-rm-watch]:
+ [set-file-times, set-visited-file-modtime]:
+ [verify-visited-file-modtime]: Add handler.
+ (with-tramp-gvfs-error-message)
+ (tramp-gvfs-handle-set-visited-file-modtime)
+ (tramp-gvfs-fuse-file-name): Remove.
+ (tramp-gvfs-handle-file-notify-add-watch)
+ (tramp-gvfs-file-gvfs-monitor-file-process-filter): New defuns.
+ (tramp-gvfs-handle-write-region): Fix error in moving tmpfile.
+
+ * net/tramp-sh.el (tramp-sh-file-name-handler-alist):
+ Order alphabetically.
+ [file-notify-rm-watch ]: Use default Tramp handler.
+ [executable-find]: Remove private handler.
+ (tramp-do-copy-or-rename-file-out-of-band): Do not bind
+ `default-directory'.
+ (tramp-sh-handle-executable-find)
+ (tramp-sh-handle-file-notify-rm-watch): Remove functions.
+ (tramp-sh-file-gvfs-monitor-dir-process-filter)
+ (tramp-sh-file-inotifywait-process-filter, tramp-set-remote-path):
+ Do not use `format' in `tramp-message'.
+
+ * net/tramp-smb.el (tramp-smb-file-name-handler-alist)
+ [file-notify-rm-watch, set-visited-file-modtime]:
+ [verify-visited-file-modtime]: Add handler.
+ (tramp-smb-call-winexe): Do not bind `default-directory'.
+
+2013-08-01 Xue Fuqiao <xfq.free@gmail.com>
+
+ * vc/vc-hooks.el (vc-menu-map): Fix menu entry for vc-ignore.
+
+2013-07-31 Dmitry Gutov <dgutov@yandex.ru>
+
+ * vc/log-view.el (log-view-diff): Extract `log-view-diff-common',
+ use it.
+ (log-view-diff-changeset): Same.
+ (log-view-diff-common): Call backend command `previous-revision'
+ to find out the previous revision, in both cases. Swap the
+ variables `to' and `fr', so that `fr' usually refers to the
+ earlier revision (Bug#14989).
+
+2013-07-31 Kan-Ru Chen <kanru@kanru.info>
+
+ * ibuf-ext.el (ibuffer-filter-by-filename):
+ Make it work with dired buffers too.
+
+2013-07-31 Dmitry Antipov <dmantipov@yandex.ru>
+
+ * emacs-lisp/re-builder.el (reb-color-display-p):
+ * files.el (save-buffers-kill-terminal):
+ * net/browse-url.el (browse-url):
+ * server.el (server-save-buffers-kill-terminal):
+ * textmodes/reftex-toc.el (reftex-toc, reftex-toc-revert):
+ Prefer nil to selected-frame for the first arg of frame-parameter.
+
+2013-07-31 Xue Fuqiao <xfq.free@gmail.com>
+
+ * vc/vc-hooks.el (vc-menu-map): Add menu entry for vc-ignore.
+
+2013-07-30 Stephen Berman <stephen.berman@gmx.net>
+
+ * minibuffer.el (completion--twq-all): Try and preserve each
+ completion's case choice (bug#14907).
+
+2013-07-30 Lars Magne Ingebrigtsen <larsi@gnus.org>
+
+ * net/network-stream.el (open-network-stream): Mention the new
+ :nogreeting parameter.
+ (network-stream-open-starttls): Use the :nogreeting parameter
+ (bug#14938).
+
+ * net/shr.el (shr-mouse-browse-url): Remove and use `shr-browse-url'.
+
+ * net/eww.el (eww-setup-buffer): Switching to the buffer seems
+ more natural than popping.
+
+ * net/shr.el (shr-urlify): Put `follow-link' on URLs (bug#14815).
+ (shr-urlify): Highlight under mouse.
+
2013-07-30 Xue Fuqiao <xfq.free@gmail.com>
+ * vc/vc-hooks.el (vc-prefix-map): Add key binding for vc-ignore.
+
+ * vc/vc-dir.el (vc-dir-mode-map): Change key binding for vc-dir-ignore.
+
* vc/vc-svn.el (vc-svn-ignore): Remove `interactive'. Use `*vc*'
buffer for output.
* vc/vc-hg.el (vc-hg-ignore): Remove `interactive'. Do not assume
point-min==1. Fix search string. Fix parentheses missing.
- * vc/vc-git.el (vc-git-ignore): Remove `interactive'. Do not
+ * vc/vc-git.el (vc-git-ignore): Remove `interactive'. Do not
assume point-min==1. Fix search string. Fix parentheses missing.
* vc/vc-cvs.el (vc-cvs-ignore): Remove `interactive'.
@@ -94,7 +287,7 @@
* progmodes/cc-engine.el (c-beginning-of-statement-1)
(c-after-conditional): Adapt to deal with c-block-stmt-1-2-key.
* progmodes/cc-fonts.el (c-font-lock-declarations): Adapt to deal
- with c-block-stmet-1-2-key.
+ with c-block-stmt-1-2-key.
2013-07-27 Juanma Barranquero <lekktu@gmail.com>
diff --git a/lisp/autorevert.el b/lisp/autorevert.el
index 1617a31cd82..978a834cb4c 100644
--- a/lisp/autorevert.el
+++ b/lisp/autorevert.el
@@ -595,14 +595,14 @@ This is an internal function used by Auto-Revert Mode."
(setq size
(nth 7 (file-attributes
buffer-file-name)))))
- (and (file-readable-p buffer-file-name)
- (not (verify-visited-file-modtime buffer)))))
+ (funcall (or buffer-stale-function
+ #'buffer-stale--default-function)
+ t)))
(and (or auto-revert-mode
global-auto-revert-non-file-buffers)
- revert-buffer-function
- (boundp 'buffer-stale-function)
- (functionp buffer-stale-function)
- (funcall buffer-stale-function t))))
+ (funcall (or buffer-stale-function
+ #'buffer-stale--default-function)
+ t))))
eob eoblist)
(setq auto-revert-notify-modified-p nil)
(when revert
diff --git a/lisp/custom.el b/lisp/custom.el
index f2d58084e9e..3db34e4d1fb 100644
--- a/lisp/custom.el
+++ b/lisp/custom.el
@@ -49,63 +49,66 @@ Users should not set it.")
;;; The `defcustom' Macro.
-(defun custom-initialize-default (symbol value)
- "Initialize SYMBOL with VALUE.
+(defun custom-initialize-default (symbol exp)
+ "Initialize SYMBOL with EXP.
This will do nothing if symbol already has a default binding.
Otherwise, if symbol has a `saved-value' property, it will evaluate
the car of that and use it as the default binding for symbol.
-Otherwise, VALUE will be evaluated and used as the default binding for
+Otherwise, EXP will be evaluated and used as the default binding for
symbol."
- (eval `(defvar ,symbol ,(if (get symbol 'saved-value)
- (car (get symbol 'saved-value))
- value))))
+ (eval `(defvar ,symbol ,(let ((sv (get symbol 'saved-value)))
+ (if sv (car sv) exp)))))
-(defun custom-initialize-set (symbol value)
- "Initialize SYMBOL based on VALUE.
+(defun custom-initialize-set (symbol exp)
+ "Initialize SYMBOL based on EXP.
If the symbol doesn't have a default binding already,
then set it using its `:set' function (or `set-default' if it has none).
The value is either the value in the symbol's `saved-value' property,
-if any, or VALUE."
- (unless (default-boundp symbol)
- (funcall (or (get symbol 'custom-set) 'set-default)
- symbol
- (eval (if (get symbol 'saved-value)
- (car (get symbol 'saved-value))
- value)))))
-
-(defun custom-initialize-reset (symbol value)
- "Initialize SYMBOL based on VALUE.
+if any, or the value of EXP."
+ (condition-case nil
+ (default-toplevel-value symbol)
+ (error
+ (funcall (or (get symbol 'custom-set) #'set-default-toplevel-value)
+ symbol
+ (eval (let ((sv (get symbol 'saved-value)))
+ (if sv (car sv) exp)))))))
+
+(defun custom-initialize-reset (symbol exp)
+ "Initialize SYMBOL based on EXP.
Set the symbol, using its `:set' function (or `set-default' if it has none).
The value is either the symbol's current value
(as obtained using the `:get' function), if any,
or the value in the symbol's `saved-value' property if any,
-or (last of all) VALUE."
- (funcall (or (get symbol 'custom-set) 'set-default)
+or (last of all) the value of EXP."
+ (funcall (or (get symbol 'custom-set) #'set-default-toplevel-value)
symbol
- (cond ((default-boundp symbol)
- (funcall (or (get symbol 'custom-get) 'default-value)
- symbol))
- ((get symbol 'saved-value)
- (eval (car (get symbol 'saved-value))))
- (t
- (eval value)))))
-
-(defun custom-initialize-changed (symbol value)
- "Initialize SYMBOL with VALUE.
+ (condition-case nil
+ (let ((def (default-toplevel-value symbol))
+ (getter (get symbol 'custom-get)))
+ (if getter (funcall getter symbol) def))
+ (error
+ (eval (let ((sv (get symbol 'saved-value)))
+ (if sv (car sv) exp)))))))
+
+(defun custom-initialize-changed (symbol exp)
+ "Initialize SYMBOL with EXP.
Like `custom-initialize-reset', but only use the `:set' function if
not using the standard setting.
For the standard setting, use `set-default'."
- (cond ((default-boundp symbol)
- (funcall (or (get symbol 'custom-set) 'set-default)
- symbol
- (funcall (or (get symbol 'custom-get) 'default-value)
- symbol)))
- ((get symbol 'saved-value)
- (funcall (or (get symbol 'custom-set) 'set-default)
- symbol
- (eval (car (get symbol 'saved-value)))))
- (t
- (set-default symbol (eval value)))))
+ (condition-case nil
+ (let ((def (default-toplevel-value symbol)))
+ (funcall (or (get symbol 'custom-set) #'set-default-toplevel-value)
+ symbol
+ (let ((getter (get symbol 'custom-get)))
+ (if getter (funcall getter symbol) def))))
+ (error
+ (cond
+ ((get symbol 'saved-value)
+ (funcall (or (get symbol 'custom-set) #'set-default-toplevel-value)
+ symbol
+ (eval (car (get symbol 'saved-value)))))
+ (t
+ (set-default symbol (eval exp)))))))
(defvar custom-delayed-init-variables nil
"List of variables whose initialization is pending.")
diff --git a/lisp/desktop.el b/lisp/desktop.el
index 299bdc0eeb4..778c37484e1 100644
--- a/lisp/desktop.el
+++ b/lisp/desktop.el
@@ -134,6 +134,7 @@
;;; Code:
(require 'cl-lib)
+(require 'frameset)
(defvar desktop-file-version "206"
"Version number of desktop file format.
@@ -372,7 +373,7 @@ modes are restored automatically; they should not be listed here."
:group 'desktop)
(defcustom desktop-restore-frames t
- "When non-nil, save window/frame configuration to desktop file."
+ "When non-nil, save frames to desktop file."
:type 'boolean
:group 'desktop
:version "24.4")
@@ -399,7 +400,7 @@ few pixels, especially near the right / bottom borders of the screen."
:group 'desktop
:version "24.4")
-(defcustom desktop-restoring-reuses-frames t
+(defcustom desktop-restore-reuses-frames t
"If t, restoring frames reuses existing frames.
If nil, existing frames are deleted.
If `keep', existing frames are kept and not reused."
@@ -409,13 +410,6 @@ If `keep', existing frames are kept and not reused."
:group 'desktop
:version "24.4")
-(defcustom desktop-before-saving-frames-functions nil
- "Abnormal hook run before saving frames.
-Functions in this hook are called with one argument, a live frame."
- :type 'hook
- :group 'desktop
- :version "24.4")
-
(defcustom desktop-file-name-format 'absolute
"Format in which desktop file names should be saved.
Possible values are:
@@ -599,7 +593,7 @@ DIRNAME omitted or nil means use `desktop-dirname'."
"Checksum of the last auto-saved contents of the desktop file.
Used to avoid writing contents unchanged between auto-saves.")
-(defvar desktop-saved-frame-states nil
+(defvar desktop-saved-frameset nil
"Saved state of all frames.
Only valid during frame saving & restoring; intended for internal use.")
@@ -649,7 +643,10 @@ DIRNAME omitted or nil means use `desktop-dirname'."
"Empty the Desktop.
This kills all buffers except for internal ones and those with names matched by
a regular expression in the list `desktop-clear-preserve-buffers'.
-Furthermore, it clears the variables listed in `desktop-globals-to-clear'."
+Furthermore, it clears the variables listed in `desktop-globals-to-clear'.
+When called interactively and `desktop-restore-frames' is non-nil, it also
+deletes all frames except the selected one (and its minibuffer frame,
+if different)."
(interactive)
(desktop-lazy-abort)
(dolist (var desktop-globals-to-clear)
@@ -667,7 +664,21 @@ Furthermore, it clears the variables listed in `desktop-globals-to-clear'."
(unless (or (eq (aref bufname 0) ?\s) ;; Don't kill internal buffers
(string-match-p preserve-regexp bufname))
(kill-buffer buffer)))))
- (delete-other-windows))
+ (delete-other-windows)
+ (when (and desktop-restore-frames
+ ;; Non-interactive calls to desktop-clear happen before desktop-read
+ ;; which already takes care of frame restoration and deletion.
+ (called-interactively-p 'any))
+ (let* ((this (selected-frame))
+ (mini (window-frame (minibuffer-window this)))) ; in case they difer
+ (dolist (frame (sort (frame-list) #'frameset-sort-frames-for-deletion))
+ (condition-case err
+ (unless (or (eq frame this)
+ (eq frame mini)
+ (frame-parameter frame 'desktop-dont-clear))
+ (delete-frame frame))
+ (error
+ (delay-warning 'desktop (error-message-string err))))))))
;; ----------------------------------------------------------------------------
(unless noninteractive
@@ -890,223 +901,41 @@ DIRNAME must be the directory in which the desktop file will be saved."
;; ----------------------------------------------------------------------------
(defvar desktop-filter-parameters-alist
- '((background-color . desktop--filter-*-color)
- (buffer-list . t)
- (buffer-predicate . t)
- (buried-buffer-list . t)
- (desktop--font . desktop--filter-restore-desktop-parm)
- (desktop--fullscreen . desktop--filter-restore-desktop-parm)
- (desktop--height . desktop--filter-restore-desktop-parm)
- (desktop--width . desktop--filter-restore-desktop-parm)
- (font . desktop--filter-save-desktop-parm)
- (font-backend . t)
- (foreground-color . desktop--filter-*-color)
- (fullscreen . desktop--filter-save-desktop-parm)
- (height . desktop--filter-save-desktop-parm)
- (left . desktop--filter-iconified-position)
- (minibuffer . desktop--filter-minibuffer)
- (name . t)
- (outer-window-id . t)
- (parent-id . t)
- (top . desktop--filter-iconified-position)
- (tty . desktop--filter-tty*)
- (tty-type . desktop--filter-tty*)
- (width . desktop--filter-save-desktop-parm)
- (window-id . t)
- (window-system . t))
+ (append '((font-backend . t)
+ (name . t)
+ (outer-window-id . t)
+ (parent-id . t)
+ (tty . desktop--filter-tty*)
+ (tty-type . desktop--filter-tty*)
+ (window-id . t)
+ (window-system . t))
+ frameset-filter-alist)
"Alist of frame parameters and filtering functions.
-
-Each element is a cons (PARAM . FILTER), where PARAM is a parameter
-name (a symbol identifying a frame parameter), and FILTER can be t
-\(meaning the parameter is removed from the parameter list on saving
-and restoring), or a function that will be called with three args:
-
- CURRENT a cons (PARAM . VALUE), where PARAM is the one being
- filtered and VALUE is its current value
- PARAMETERS the complete alist of parameters being filtered
- SAVING non-nil if filtering before saving state, nil otherwise
-
-The FILTER function must return:
- nil CURRENT is removed from the list
- t CURRENT is left as is
- (PARAM' . VALUE') replace CURRENT with this
-
-Frame parameters not on this list are passed intact.")
-
-(defvar desktop--target-display nil
- "Either (minibuffer . VALUE) or nil.
-This refers to the current frame config being processed inside
-`frame--restore-frames' and its auxiliary functions (like filtering).
-If nil, there is no need to change the display.
-If non-nil, display parameter to use when creating the frame.
-Internal use only.")
-
-(defun desktop-switch-to-gui-p (parameters)
- "True when switching to a graphic display.
-Return t if PARAMETERS describes a text-only terminal and
-the target is a graphic display; otherwise return nil.
-Only meaningful when called from a filtering function in
-`desktop-filter-parameters-alist'."
- (and desktop--target-display ; we're switching
- (null (cdr (assq 'display parameters))) ; from a tty
- (cdr desktop--target-display))) ; to a GUI display
-
-(defun desktop-switch-to-tty-p (parameters)
- "True when switching to a text-only terminal.
-Return t if PARAMETERS describes a graphic display and
-the target is a text-only terminal; otherwise return nil.
-Only meaningful when called from a filtering function in
-`desktop-filter-parameters-alist'."
- (and desktop--target-display ; we're switching
- (cdr (assq 'display parameters)) ; from a GUI display
- (null (cdr desktop--target-display)))) ; to a tty
+Its format is identical to `frameset-filter-alist' (which see).")
(defun desktop--filter-tty* (_current parameters saving)
;; Remove tty and tty-type parameters when switching
;; to a GUI frame.
(or saving
- (not (desktop-switch-to-gui-p parameters))))
+ (not (frameset-switch-to-gui-p parameters))))
-(defun desktop--filter-*-color (current parameters saving)
- ;; Remove (foreground|background)-color parameters
- ;; when switching to a GUI frame if they denote an
- ;; "unspecified" color.
- (or saving
- (not (desktop-switch-to-gui-p parameters))
- (not (stringp (cdr current)))
- (not (string-match-p "^unspecified-[fb]g$" (cdr current)))))
-
-(defun desktop--filter-minibuffer (current _parameters saving)
- ;; When minibuffer is a window, save it as minibuffer . t
- (or (not saving)
- (if (windowp (cdr current))
- '(minibuffer . t)
- t)))
-
-(defun desktop--filter-restore-desktop-parm (current parameters saving)
- ;; When switching to a GUI frame, convert desktop--XXX parameter to XXX
- (or saving
- (not (desktop-switch-to-gui-p parameters))
- (let ((val (cdr current)))
- (if (eq val :desktop-processed)
- nil
- (cons (intern (substring (symbol-name (car current))
- 9)) ;; (length "desktop--")
- val)))))
-
-(defun desktop--filter-save-desktop-parm (current parameters saving)
- ;; When switching to a tty frame, save parameter XXX as desktop--XXX so it
- ;; can be restored in a subsequent GUI session, unless it already exists.
- (cond (saving t)
- ((desktop-switch-to-tty-p parameters)
- (let ((sym (intern (format "desktop--%s" (car current)))))
- (if (assq sym parameters)
- nil
- (cons sym (cdr current)))))
- ((desktop-switch-to-gui-p parameters)
- (let* ((dtp (assq (intern (format "desktop--%s" (car current)))
- parameters))
- (val (cdr dtp)))
- (if (eq val :desktop-processed)
- nil
- (setcdr dtp :desktop-processed)
- (cons (car current) val))))
- (t t)))
-
-(defun desktop--filter-iconified-position (_current parameters saving)
- ;; When saving an iconified frame, top & left are meaningless,
- ;; so remove them to allow restoring to a default position.
- (not (and saving (eq (cdr (assq 'visibility parameters)) 'icon))))
-
-(defun desktop-restore-in-original-display-p ()
- "True if saved frames' displays should be honored."
- (cond ((daemonp) t)
- ((eq system-type 'windows-nt) nil)
- (t (null desktop-restore-in-current-display))))
-
-(defun desktop--filter-frame-parms (parameters saving)
- "Filter frame parameters and return filtered list.
-PARAMETERS is a parameter alist as returned by `frame-parameters'.
-If SAVING is non-nil, filtering is happening before saving frame state;
-otherwise, filtering is being done before restoring frame state.
-Parameters are filtered according to the setting of
-`desktop-filter-parameters-alist' (which see).
-Internal use only."
- (let ((filtered nil))
- (dolist (param parameters)
- (let ((filter (cdr (assq (car param) desktop-filter-parameters-alist)))
- this)
- (cond (;; no filter: pass param
- (null filter)
- (push param filtered))
- (;; filter = t; skip param
- (eq filter t))
- (;; filter func returns nil: skip param
- (null (setq this (funcall filter param parameters saving))))
- (;; filter func returns t: pass param
- (eq this t)
- (push param filtered))
- (;; filter func returns a new param: use it
- t
- (push this filtered)))))
- ;; Set the display parameter after filtering, so that filter functions
- ;; have access to its original value.
- (when desktop--target-display
- (let ((display (assq 'display filtered)))
- (if display
- (setcdr display (cdr desktop--target-display))
- (push desktop--target-display filtered))))
- filtered))
-
-(defun desktop--process-minibuffer-frames (frames)
- ;; Adds a desktop--mini parameter to frames
- ;; desktop--mini is a list (MINIBUFFER NUMBER DEFAULT?) where
- ;; MINIBUFFER t if the frame (including minibuffer-only) owns a minibuffer
- ;; NUMBER if MINIBUFFER = t, an ID for the frame; if nil, the ID of
- ;; the frame containing the minibuffer used by this frame
- ;; DEFAULT? if t, this frame is the value of default-minibuffer-frame
- (let ((count 0))
- ;; Reset desktop--mini for all frames
- (dolist (frame (frame-list))
- (set-frame-parameter frame 'desktop--mini nil))
- ;; Number all frames with its own minibuffer
- (dolist (frame (minibuffer-frame-list))
- (set-frame-parameter frame 'desktop--mini
- (list t
- (cl-incf count)
- (eq frame default-minibuffer-frame))))
- ;; Now link minibufferless frames with their minibuffer frames
- (dolist (frame frames)
- (unless (frame-parameter frame 'desktop--mini)
- (let ((mb-frame (window-frame (minibuffer-window frame))))
- ;; Frames whose minibuffer frame has been filtered out will have
- ;; desktop--mini = nil, so desktop-restore-frames will restore them
- ;; according to their minibuffer parameter. Set up desktop--mini
- ;; for the rest.
- (when (memq mb-frame frames)
- (set-frame-parameter frame 'desktop--mini
- (list nil
- (cl-second (frame-parameter mb-frame 'desktop--mini))
- nil))))))))
-
-(defun desktop-save-frames ()
- "Save frame state in `desktop-saved-frame-states'.
-Runs the hook `desktop-before-saving-frames-functions'.
+(defun desktop--check-dont-save (frame)
+ (not (frame-parameter frame 'desktop-dont-save)))
+
+(defconst desktop--app-id `(desktop . ,desktop-file-version))
+
+(defun desktop-save-frameset ()
+ "Save the state of existing frames in `desktop-saved-frameset'.
Frames with a non-nil `desktop-dont-save' parameter are not saved."
- (setq desktop-saved-frame-states
+ (setq desktop-saved-frameset
(and desktop-restore-frames
- (let ((frames (cl-delete-if
- (lambda (frame)
- (run-hook-with-args 'desktop-before-saving-frames-functions frame)
- (frame-parameter frame 'desktop-dont-save))
- (frame-list))))
- ;; In case some frame was deleted by a hook function
- (setq frames (cl-delete-if-not #'frame-live-p frames))
- (desktop--process-minibuffer-frames frames)
- (mapcar (lambda (frame)
- (cons (desktop--filter-frame-parms (frame-parameters frame) t)
- (window-state-get (frame-root-window frame) t)))
- frames)))))
+ (let ((name (concat user-login-name "@" system-name
+ (format-time-string " %Y-%m-%d %T"))))
+ (frameset-save nil
+ :filters desktop-filter-parameters-alist
+ :predicate #'desktop--check-dont-save
+ :properties (list :app desktop--app-id
+ :name name))))))
;;;###autoload
(defun desktop-save (dirname &optional release auto-save)
@@ -1148,11 +977,11 @@ and don't save the buffer if they are the same."
(insert "\n;; Global section:\n")
;; Called here because we save the window/frame state as a global
;; variable for compatibility with previous Emacsen.
- (desktop-save-frames)
- (unless (memq 'desktop-saved-frame-states desktop-globals-to-save)
- (desktop-outvar 'desktop-saved-frame-states))
+ (desktop-save-frameset)
+ (unless (memq 'desktop-saved-frameset desktop-globals-to-save)
+ (desktop-outvar 'desktop-saved-frameset))
(mapc (function desktop-outvar) desktop-globals-to-save)
- (setq desktop-saved-frame-states nil) ; after saving desktop-globals-to-save
+ (setq desktop-saved-frameset nil) ; after saving desktop-globals-to-save
(when (memq 'kill-ring desktop-globals-to-save)
(insert
"(setq kill-ring-yank-pointer (nthcdr "
@@ -1210,319 +1039,26 @@ This function also sets `desktop-dirname' to nil."
(defvar desktop-lazy-timer nil)
;; ----------------------------------------------------------------------------
-(defvar desktop--reuse-list nil
- "Internal use only.")
-
-(defun desktop--compute-pos (value left/top right/bottom)
- (pcase value
- (`(+ ,val) (+ left/top val))
- (`(- ,val) (+ right/bottom val))
- (val val)))
-
-(defun desktop--move-onscreen (frame)
- "If FRAME is offscreen, move it back onscreen and, if necessary, resize it.
-When forced onscreen, frames wider than the monitor's workarea are converted
-to fullwidth, and frames taller than the workarea are converted to fullheight.
-NOTE: This only works for non-iconified frames."
- (pcase-let* ((`(,left ,top ,width ,height) (cl-cdadr (frame-monitor-attributes frame)))
- (right (+ left width -1))
- (bottom (+ top height -1))
- (fr-left (desktop--compute-pos (frame-parameter frame 'left) left right))
- (fr-top (desktop--compute-pos (frame-parameter frame 'top) top bottom))
- (ch-width (frame-char-width frame))
- (ch-height (frame-char-height frame))
- (fr-width (max (frame-pixel-width frame) (* ch-width (frame-width frame))))
- (fr-height (max (frame-pixel-height frame) (* ch-height (frame-height frame))))
- (fr-right (+ fr-left fr-width -1))
- (fr-bottom (+ fr-top fr-height -1)))
- (when (pcase desktop-restore-forces-onscreen
- ;; Any corner is outside the screen.
- (`all (or (< fr-bottom top) (> fr-bottom bottom)
- (< fr-left left) (> fr-left right)
- (< fr-right left) (> fr-right right)
- (< fr-top top) (> fr-top bottom)))
- ;; Displaced to the left, right, above or below the screen.
- (`t (or (> fr-left right)
- (< fr-right left)
- (> fr-top bottom)
- (< fr-bottom top)))
- (_ nil))
- (let ((fullwidth (> fr-width width))
- (fullheight (> fr-height height))
- (params nil))
- ;; Position frame horizontally.
- (cond (fullwidth
- (push `(left . ,left) params))
- ((> fr-right right)
- (push `(left . ,(+ left (- width fr-width))) params))
- ((< fr-left left)
- (push `(left . ,left) params)))
- ;; Position frame vertically.
- (cond (fullheight
- (push `(top . ,top) params))
- ((> fr-bottom bottom)
- (push `(top . ,(+ top (- height fr-height))) params))
- ((< fr-top top)
- (push `(top . ,top) params)))
- ;; Compute fullscreen state, if required.
- (when (or fullwidth fullheight)
- (push (cons 'fullscreen
- (cond ((not fullwidth) 'fullheight)
- ((not fullheight) 'fullwidth)
- (t 'maximized)))
- params))
- ;; Finally, move the frame back onscreen.
- (when params
- (modify-frame-parameters frame params))))))
-
-(defun desktop--find-frame (predicate display &rest args)
- "Find a suitable frame in `desktop--reuse-list'.
-Look through frames whose display property matches DISPLAY and
-return the first one for which (PREDICATE frame ARGS) returns t.
-If PREDICATE is nil, it is always satisfied. Internal use only.
-This is an auxiliary function for `desktop--select-frame'."
- (cl-find-if (lambda (frame)
- (and (equal (frame-parameter frame 'display) display)
- (or (null predicate)
- (apply predicate frame args))))
- desktop--reuse-list))
-
-(defun desktop--select-frame (display frame-cfg)
- "Look for an existing frame to reuse.
-DISPLAY is the display where the frame will be shown, and FRAME-CFG
-is the parameter list of the frame being restored. Internal use only."
- (if (eq desktop-restoring-reuses-frames t)
- (let ((frame nil)
- mini)
- ;; There are no fancy heuristics there. We could implement some
- ;; based on frame size and/or position, etc., but it is not clear
- ;; that any "gain" (in the sense of reduced flickering, etc.) is
- ;; worth the added complexity. In fact, the code below mainly
- ;; tries to work nicely when M-x desktop-read is used after a desktop
- ;; session has already been loaded. The other main use case, which
- ;; is the initial desktop-read upon starting Emacs, should usually
- ;; only have one, or very few, frame(s) to reuse.
- (cond ((null display)
- ;; When the target is tty, every existing frame is reusable.
- (setq frame (desktop--find-frame nil display)))
- ((car (setq mini (cdr (assq 'desktop--mini frame-cfg))))
- ;; If the frame has its own minibuffer, let's see whether
- ;; that frame has already been loaded (which can happen after
- ;; M-x desktop-read).
- (setq frame (desktop--find-frame
- (lambda (f m)
- (equal (frame-parameter f 'desktop--mini) m))
- display mini))
- ;; If it has not been loaded, and it is not a minibuffer-only frame,
- ;; let's look for an existing non-minibuffer-only frame to reuse.
- (unless (or frame (eq (cdr (assq 'minibuffer frame-cfg)) 'only))
- (setq frame (desktop--find-frame
- (lambda (f)
- (let ((w (frame-parameter f 'minibuffer)))
- (and (window-live-p w)
- (window-minibuffer-p w)
- (eq (window-frame w) f))))
- display))))
- (mini
- ;; For minibufferless frames, check whether they already exist,
- ;; and that they are linked to the right minibuffer frame.
- (setq frame (desktop--find-frame
- (lambda (f n)
- (pcase-let (((and m `(,hasmini ,num))
- (frame-parameter f 'desktop--mini)))
- (and m
- (null hasmini)
- (= num n)
- (equal (cl-second (frame-parameter
- (window-frame (minibuffer-window f))
- 'desktop--mini))
- n))))
- display (cl-second mini))))
- (t
- ;; Default to just finding a frame in the same display.
- (setq frame (desktop--find-frame nil display))))
- ;; If found, remove from the list.
- (when frame
- (setq desktop--reuse-list (delq frame desktop--reuse-list)))
- frame)
- nil))
-
-(defun desktop--make-frame (frame-cfg window-cfg)
- "Set up a frame according to its saved state.
-That means either creating a new frame or reusing an existing one.
-FRAME-CFG is the parameter list of the new frame; WINDOW-CFG is
-its window state. Internal use only."
- (let* ((fullscreen (cdr (assq 'fullscreen frame-cfg)))
- (lines (assq 'tool-bar-lines frame-cfg))
- (filtered-cfg (desktop--filter-frame-parms frame-cfg nil))
- (display (cdr (assq 'display filtered-cfg))) ;; post-filtering
- alt-cfg frame)
-
- ;; This works around bug#14795 (or feature#14795, if not a bug :-)
- (setq filtered-cfg (assq-delete-all 'tool-bar-lines filtered-cfg))
- (push '(tool-bar-lines . 0) filtered-cfg)
-
- (when fullscreen
- ;; Currently Emacs has the limitation that it does not record the size
- ;; and position of a frame before maximizing it, so we cannot save &
- ;; restore that info. Instead, when restoring, we resort to creating
- ;; invisible "fullscreen" frames of default size and then maximizing them
- ;; (and making them visible) which at least is somewhat user-friendly
- ;; when these frames are later de-maximized.
- (let ((width (and (eq fullscreen 'fullheight) (cdr (assq 'width filtered-cfg))))
- (height (and (eq fullscreen 'fullwidth) (cdr (assq 'height filtered-cfg))))
- (visible (assq 'visibility filtered-cfg)))
- (setq filtered-cfg (cl-delete-if (lambda (p)
- (memq p '(visibility fullscreen width height)))
- filtered-cfg :key #'car))
- (when width
- (setq filtered-cfg (append `((user-size . t) (width . ,width))
- filtered-cfg)))
- (when height
- (setq filtered-cfg (append `((user-size . t) (height . ,height))
- filtered-cfg)))
- ;; These are parameters to apply after creating/setting the frame.
- (push visible alt-cfg)
- (push (cons 'fullscreen fullscreen) alt-cfg)))
-
- ;; Time to find or create a frame an apply the big bunch of parameters.
- ;; If a frame needs to be created and it falls partially or wholly offscreen,
- ;; sometimes it gets "pushed back" onscreen; however, moving it afterwards is
- ;; allowed. So we create the frame as invisible and then reapply the full
- ;; parameter list (including position and size parameters).
- (setq frame (or (desktop--select-frame display filtered-cfg)
- (make-frame-on-display display
- (cons '(visibility)
- (cl-loop
- for param in '(left top width height minibuffer)
- collect (assq param filtered-cfg))))))
- (modify-frame-parameters frame
- (if (eq (frame-parameter frame 'fullscreen) fullscreen)
- ;; Workaround for bug#14949
- (assq-delete-all 'fullscreen filtered-cfg)
- filtered-cfg))
-
- ;; If requested, force frames to be onscreen.
- (when (and desktop-restore-forces-onscreen
- ;; FIXME: iconified frames should be checked too,
- ;; but it is impossible without deiconifying them.
- (not (eq (frame-parameter frame 'visibility) 'icon)))
- (desktop--move-onscreen frame))
-
- ;; Let's give the finishing touches (visibility, tool-bar, maximization).
- (when lines (push lines alt-cfg))
- (when alt-cfg (modify-frame-parameters frame alt-cfg))
- ;; Now restore window state.
- (window-state-put window-cfg (frame-root-window frame) 'safe)
- frame))
-
-(defun desktop--sort-states (state1 state2)
- ;; Order: default minibuffer frame
- ;; other frames with minibuffer, ascending ID
- ;; minibufferless frames, ascending ID
- (pcase-let ((`(,_p1 ,hasmini1 ,num1 ,default1) (assq 'desktop--mini (car state1)))
- (`(,_p2 ,hasmini2 ,num2 ,default2) (assq 'desktop--mini (car state2))))
- (cond (default1 t)
- (default2 nil)
- ((eq hasmini1 hasmini2) (< num1 num2))
- (t hasmini1))))
-
-(defun desktop-restoring-frames-p ()
- "True if calling `desktop-restore-frames' will actually restore frames."
- (and desktop-restore-frames desktop-saved-frame-states t))
-
-(defun desktop-restore-frames ()
- "Restore window/frame configuration.
-This function depends on the value of `desktop-saved-frame-states'
+(defun desktop-restoring-frameset-p ()
+ "True if calling `desktop-restore-frameset' will actually restore it."
+ (and desktop-restore-frames desktop-saved-frameset t))
+
+(defun desktop-restore-frameset ()
+ "Restore the state of a set of frames.
+This function depends on the value of `desktop-saved-frameset'
being set (usually, by reading it from the desktop)."
- (when (desktop-restoring-frames-p)
- (let* ((frame-mb-map nil) ;; Alist of frames with their own minibuffer
- (delete-saved (eq desktop-restore-in-current-display 'delete))
- (forcing (not (desktop-restore-in-original-display-p)))
- (target (and forcing (cons 'display (frame-parameter nil 'display)))))
-
- ;; Sorting saved states allows us to easily restore minibuffer-owning frames
- ;; before minibufferless ones.
- (setq desktop-saved-frame-states (sort desktop-saved-frame-states
- #'desktop--sort-states))
- ;; Potentially all existing frames are reusable. Later we will decide which ones
- ;; to reuse, and how to deal with any leftover.
- (setq desktop--reuse-list (frame-list))
-
- (dolist (state desktop-saved-frame-states)
- (condition-case err
- (pcase-let* ((`(,frame-cfg . ,window-cfg) state)
- ((and d-mini `(,hasmini ,num ,default))
- (cdr (assq 'desktop--mini frame-cfg)))
- (frame nil) (to-tty nil))
- ;; Only set target if forcing displays and the target display is different.
- (if (or (not forcing)
- (equal target (or (assq 'display frame-cfg) '(display . nil))))
- (setq desktop--target-display nil)
- (setq desktop--target-display target
- to-tty (null (cdr target))))
- ;; Time to restore frames and set up their minibuffers as they were.
- ;; We only skip a frame (thus deleting it) if either:
- ;; - we're switching displays, and the user chose the option to delete, or
- ;; - we're switching to tty, and the frame to restore is minibuffer-only.
- (unless (and desktop--target-display
- (or delete-saved
- (and to-tty
- (eq (cdr (assq 'minibuffer frame-cfg)) 'only))))
-
- ;; Restore minibuffers. Some of this stuff could be done in a filter
- ;; function, but it would be messy because restoring minibuffers affects
- ;; global state; it's best to do it here than add a bunch of global
- ;; variables to pass info back-and-forth to/from the filter function.
- (cond
- ((null d-mini)) ;; No desktop--mini. Process as normal frame.
- (to-tty) ;; Ignore minibuffer stuff and process as normal frame.
- (hasmini ;; Frame has minibuffer (or it is minibuffer-only).
- (when (eq (cdr (assq 'minibuffer frame-cfg)) 'only)
- (setq frame-cfg (append '((tool-bar-lines . 0) (menu-bar-lines . 0))
- frame-cfg))))
- (t ;; Frame depends on other frame's minibuffer window.
- (let ((mb-frame (cdr (assq num frame-mb-map))))
- (unless (frame-live-p mb-frame)
- (error "Minibuffer frame %s not found" num))
- (let ((mb-param (assq 'minibuffer frame-cfg))
- (mb-window (minibuffer-window mb-frame)))
- (unless (and (window-live-p mb-window)
- (window-minibuffer-p mb-window))
- (error "Not a minibuffer window %s" mb-window))
- (if mb-param
- (setcdr mb-param mb-window)
- (push (cons 'minibuffer mb-window) frame-cfg))))))
- ;; OK, we're ready at last to create (or reuse) a frame and
- ;; restore the window config.
- (setq frame (desktop--make-frame frame-cfg window-cfg))
- ;; Set default-minibuffer if required.
- (when default (setq default-minibuffer-frame frame))
- ;; Store NUM/frame to assign to minibufferless frames.
- (when hasmini (push (cons num frame) frame-mb-map))))
- (error
- (delay-warning 'desktop (error-message-string err) :error))))
-
- ;; In case we try to delete the initial frame, we want to make sure that
- ;; other frames are already visible (discussed in thread for bug#14841).
- (sit-for 0 t)
-
- ;; Delete remaining frames, but do not fail if some resist being deleted.
- (unless (eq desktop-restoring-reuses-frames 'keep)
- (dolist (frame desktop--reuse-list)
- (condition-case err
- (delete-frame frame)
- (error
- (delay-warning 'desktop (error-message-string err))))))
- (setq desktop--reuse-list nil)
- ;; Make sure there's at least one visible frame, and select it.
- (unless (or (daemonp)
- (cl-find-if #'frame-visible-p (frame-list)))
- (let ((visible (if (frame-live-p default-minibuffer-frame)
- default-minibuffer-frame
- (car (frame-list)))))
- (make-frame-visible visible)
- (select-frame-set-input-focus visible))))))
+ (when (desktop-restoring-frameset-p)
+ (frameset-restore desktop-saved-frameset
+ :filters desktop-filter-parameters-alist
+ :reuse-frames desktop-restore-reuses-frames
+ :force-display desktop-restore-in-current-display
+ :force-onscreen desktop-restore-forces-onscreen)))
+
+;; Just to silence the byte compiler.
+;; Dynamicaly bound in `desktop-read'.
+(defvar desktop-first-buffer)
+(defvar desktop-buffer-ok-count)
+(defvar desktop-buffer-fail-count)
;;;###autoload
(defun desktop-read (&optional dirname)
@@ -1583,7 +1119,7 @@ Using it may cause conflicts. Use it anyway? " owner)))))
(file-error (message "Couldn't record use of desktop file")
(sit-for 1))))
- (unless (desktop-restoring-frames-p)
+ (unless (desktop-restoring-frameset-p)
;; `desktop-create-buffer' puts buffers at end of the buffer list.
;; We want buffers existing prior to evaluating the desktop (and
;; not reused) to be placed at the end of the buffer list, so we
@@ -1593,9 +1129,14 @@ Using it may cause conflicts. Use it anyway? " owner)))))
(switch-to-buffer (car (buffer-list))))
(run-hooks 'desktop-delay-hook)
(setq desktop-delay-hook nil)
- (desktop-restore-frames)
+ (desktop-restore-frameset)
(run-hooks 'desktop-after-read-hook)
- (message "Desktop: %d buffer%s restored%s%s."
+ (message "Desktop: %s%d buffer%s restored%s%s."
+ (if desktop-saved-frameset
+ (let ((fn (length (frameset-states desktop-saved-frameset))))
+ (format "%d frame%s, "
+ fn (if (= fn 1) "" "s")))
+ "")
desktop-buffer-ok-count
(if (= 1 desktop-buffer-ok-count) "" "s")
(if (< 0 desktop-buffer-fail-count)
@@ -1605,7 +1146,7 @@ Using it may cause conflicts. Use it anyway? " owner)))))
(format ", %d to restore lazily"
(length desktop-buffer-args-list))
""))
- (unless (desktop-restoring-frames-p)
+ (unless (desktop-restoring-frameset-p)
;; Bury the *Messages* buffer to not reshow it when burying
;; the buffer we switched to above.
(when (buffer-live-p (get-buffer "*Messages*"))
@@ -1618,6 +1159,7 @@ Using it may cause conflicts. Use it anyway? " owner)))))
(walk-window-tree (lambda (window)
(set-window-prev-buffers window nil)
(set-window-next-buffers window nil))))
+ (setq desktop-saved-frameset nil)
t))
;; No desktop file found.
(desktop-clear)
@@ -1743,14 +1285,6 @@ integer, start a new timer to call `desktop-auto-save' in that many seconds."
;; Create a buffer, load its file, set its mode, ...;
;; called from Desktop file only.
-;; Just to silence the byte compiler.
-
-(defvar desktop-first-buffer) ; Dynamically bound in `desktop-read'
-
-;; Bound locally in `desktop-read'.
-(defvar desktop-buffer-ok-count)
-(defvar desktop-buffer-fail-count)
-
(defun desktop-create-buffer
(file-version
buffer-filename
diff --git a/lisp/emacs-lisp/advice.el b/lisp/emacs-lisp/advice.el
index 3d03e894534..eb1d63e788b 100644
--- a/lisp/emacs-lisp/advice.el
+++ b/lisp/emacs-lisp/advice.el
@@ -2280,7 +2280,6 @@ For that it has to be fbound with a non-autoload definition."
(defun ad-compile-function (function)
"Byte-compile the assembled advice function."
(require 'bytecomp)
- (require 'warnings) ;To define warning-suppress-types before we let-bind it.
(let ((byte-compile-warnings byte-compile-warnings)
;; Don't pop up windows showing byte-compiler warnings.
(warning-suppress-types '((bytecomp))))
diff --git a/lisp/emacs-lisp/easy-mmode.el b/lisp/emacs-lisp/easy-mmode.el
index ed10080cc35..f8fb65be4d3 100644
--- a/lisp/emacs-lisp/easy-mmode.el
+++ b/lisp/emacs-lisp/easy-mmode.el
@@ -419,7 +419,7 @@ See `%s' for more information on %s."
;; Go through existing buffers.
(dolist (buf (buffer-list))
(with-current-buffer buf
- (if ,global-mode (,turn-on) (when ,mode (,mode -1))))))
+ (if ,global-mode (funcall #',turn-on) (when ,mode (,mode -1))))))
;; Autoloading define-globalized-minor-mode autoloads everything
;; up-to-here.
@@ -449,8 +449,8 @@ See `%s' for more information on %s."
(if ,mode
(progn
(,mode -1)
- (,turn-on))
- (,turn-on))))
+ (funcall #',turn-on))
+ (funcall #',turn-on))))
(setq ,MODE-major-mode major-mode)))))
(put ',MODE-enable-in-buffers 'definition-name ',global-mode)
@@ -589,7 +589,7 @@ BODY is executed after moving to the destination location."
(prog1 (or (< (- (point-max) (point-min)) (buffer-size)))
(widen))))
,body
- (when was-narrowed (,narrowfun)))))))
+ (when was-narrowed (funcall #',narrowfun)))))))
(unless name (setq name base-name))
`(progn
(defun ,next-sym (&optional count)
@@ -601,13 +601,13 @@ BODY is executed after moving to the destination location."
,(funcall when-narrowed
`(if (not (re-search-forward ,re nil t count))
(if (looking-at ,re)
- (goto-char (or ,(if endfun `(,endfun)) (point-max)))
+ (goto-char (or ,(if endfun `(funcall #',endfun)) (point-max)))
(user-error "No next %s" ,name))
(goto-char (match-beginning 0))
(when (and (eq (current-buffer) (window-buffer (selected-window)))
(called-interactively-p 'interactive))
(let ((endpt (or (save-excursion
- ,(if endfun `(,endfun)
+ ,(if endfun `(funcall #',endfun)
`(re-search-forward ,re nil t 2)))
(point-max))))
(unless (pos-visible-in-window-p endpt nil t)
diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el
index af30deca4cc..3cbd6d4a585 100644
--- a/lisp/emacs-lisp/lisp-mode.el
+++ b/lisp/emacs-lisp/lisp-mode.el
@@ -110,7 +110,9 @@ It has `lisp-mode-abbrev-table' as its parent."
"define-compiler-macro" "define-modify-macro"
"defsetf" "define-setf-expander"
"define-method-combination"
- "defgeneric" "defmethod") t))
+ "defgeneric" "defmethod"
+ "cl-defun" "cl-defsubst" "cl-defmacro"
+ "cl-define-compiler-macro") t))
"\\s-+\\(\\(\\sw\\|\\s_\\)+\\)"))
2)
(list (purecopy "Variables")
@@ -132,7 +134,8 @@ It has `lisp-mode-abbrev-table' as its parent."
(regexp-opt
'("defgroup" "deftheme" "deftype" "defstruct"
"defclass" "define-condition" "define-widget"
- "defface" "defpackage") t))
+ "defface" "defpackage" "cl-deftype"
+ "cl-defstruct") t))
"\\s-+'?\\(\\(\\sw\\|\\s_\\)+\\)"))
2))
diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el
index 68d2880d33e..add73fd4bde 100644
--- a/lisp/emacs-lisp/package.el
+++ b/lisp/emacs-lisp/package.el
@@ -296,7 +296,7 @@ contrast, `package-user-dir' contains packages for personal use."
(:constructor
package-desc-from-define
(name-string version-string &optional summary requirements
- &key kind archive
+ &key kind archive &allow-other-keys
&aux
(name (intern name-string))
(version (version-to-list version-string))
diff --git a/lisp/emacs-lisp/re-builder.el b/lisp/emacs-lisp/re-builder.el
index 9b73bea065f..d463bfac412 100644
--- a/lisp/emacs-lisp/re-builder.el
+++ b/lisp/emacs-lisp/re-builder.el
@@ -319,7 +319,7 @@ Except for Lisp syntax this is the same as `reb-regexp'.")
(eq 'color
;; emacs/xemacs compatibility
(if (fboundp 'frame-parameter)
- (frame-parameter (selected-frame) 'display-type)
+ (frame-parameter nil 'display-type)
(if (fboundp 'frame-property)
(frame-property (selected-frame) 'display-type)))))
diff --git a/lisp/files.el b/lisp/files.el
index 10d66e0b2e0..526c535450b 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -1,4 +1,4 @@
-;;; files.el --- file input and output commands for Emacs
+;;; files.el --- file input and output commands for Emacs -*- lexical-binding:t -*-
;; Copyright (C) 1985-1987, 1992-2013 Free Software Foundation, Inc.
@@ -3645,20 +3645,19 @@ is found. Returns the new class name."
(with-temp-buffer
;; This is with-demoted-errors, but we want to mention dir-locals
;; in any error message.
- (let (err)
- (condition-case err
- (progn
- (insert-file-contents file)
- (unless (zerop (buffer-size))
- (let* ((dir-name (file-name-directory file))
- (class-name (intern dir-name))
- (variables (let ((read-circle nil))
- (read (current-buffer)))))
- (dir-locals-set-class-variables class-name variables)
- (dir-locals-set-directory-class dir-name class-name
- (nth 5 (file-attributes file)))
- class-name)))
- (error (message "Error reading dir-locals: %S" err) nil)))))
+ (condition-case err
+ (progn
+ (insert-file-contents file)
+ (unless (zerop (buffer-size))
+ (let* ((dir-name (file-name-directory file))
+ (class-name (intern dir-name))
+ (variables (let ((read-circle nil))
+ (read (current-buffer)))))
+ (dir-locals-set-class-variables class-name variables)
+ (dir-locals-set-directory-class dir-name class-name
+ (nth 5 (file-attributes file)))
+ class-name)))
+ (error (message "Error reading dir-locals: %S" err) nil))))
(defcustom enable-remote-dir-locals nil
"Non-nil means dir-local variables will be applied to remote files."
@@ -3666,6 +3665,8 @@ is found. Returns the new class name."
:type 'boolean
:group 'find-file)
+(defvar hack-dir-local-variables--warned-coding nil)
+
(defun hack-dir-local-variables ()
"Read per-directory local variables for the current buffer.
Store the directory-local variables in `dir-local-variables-alist'
@@ -3697,8 +3698,10 @@ This does nothing if either `enable-local-variables' or
(when variables
(dolist (elt variables)
(if (eq (car elt) 'coding)
- (display-warning :warning
- "Coding cannot be specified by dir-locals")
+ (unless hack-dir-local-variables--warned-coding
+ (setq hack-dir-local-variables--warned-coding t)
+ (display-warning :warning
+ "Coding cannot be specified by dir-locals"))
(unless (memq (car elt) '(eval mode))
(setq dir-local-variables-alist
(assq-delete-all (car elt) dir-local-variables-alist)))
@@ -4145,9 +4148,9 @@ FILENAME defaults to `buffer-file-name'."
(file-name-sans-extension
(file-name-nondirectory (or filename (buffer-file-name)))))
-(defcustom make-backup-file-name-function nil
+(defcustom make-backup-file-name-function
+ #'make-backup-file-name--default-function
"A function to use instead of the default `make-backup-file-name'.
-A value of nil gives the default `make-backup-file-name' behavior.
This could be buffer-local to do something special for specific
files. If you define it, you may need to change `backup-file-name-p'
@@ -4155,8 +4158,7 @@ and `file-name-sans-versions' too.
See also `backup-directory-alist'."
:group 'backup
- :type '(choice (const :tag "Default" nil)
- (function :tag "Your function")))
+ :type '(function :tag "Your function"))
(defcustom backup-directory-alist nil
"Alist of filename patterns and backup directory names.
@@ -4216,24 +4218,26 @@ Checks for files in `temporary-file-directory',
Normally this will just be the file's name with `~' appended.
Customization hooks are provided as follows.
-If the variable `make-backup-file-name-function' is non-nil, its value
-should be a function which will be called with FILE as its argument;
-the resulting name is used.
+The value of `make-backup-file-name-function' should be a function which
+will be called with FILE as its argument; the resulting name is used.
-Otherwise a match for FILE is sought in `backup-directory-alist'; see
+By default, a match for FILE is sought in `backup-directory-alist'; see
the documentation of that variable. If the directory for the backup
doesn't exist, it is created."
- (if make-backup-file-name-function
- (funcall make-backup-file-name-function file)
- (if (and (eq system-type 'ms-dos)
- (not (msdos-long-file-names)))
- (let ((fn (file-name-nondirectory file)))
- (concat (file-name-directory file)
- (or (and (string-match "\\`[^.]+\\'" fn)
- (concat (match-string 0 fn) ".~"))
- (and (string-match "\\`[^.]+\\.\\(..?\\)?" fn)
- (concat (match-string 0 fn) "~")))))
- (concat (make-backup-file-name-1 file) "~"))))
+ (funcall (or make-backup-file-name-function
+ #'make-backup-file-name--default-function)
+ file))
+
+(defun make-backup-file-name--default-function (file)
+ (if (and (eq system-type 'ms-dos)
+ (not (msdos-long-file-names)))
+ (let ((fn (file-name-nondirectory file)))
+ (concat (file-name-directory file)
+ (or (and (string-match "\\`[^.]+\\'" fn)
+ (concat (match-string 0 fn) ".~"))
+ (and (string-match "\\`[^.]+\\.\\(..?\\)?" fn)
+ (concat (match-string 0 fn) "~")))))
+ (concat (make-backup-file-name-1 file) "~")))
(defun make-backup-file-name-1 (file)
"Subroutine of `make-backup-file-name' and `find-backup-file-name'."
@@ -5254,14 +5258,20 @@ It also has access to the `preserve-modes' argument of `revert-buffer'
via the `revert-buffer-preserve-modes' dynamic variable.")
(put 'revert-buffer-insert-file-contents-function 'permanent-local t)
-(defvar revert-buffer-insert-file-contents-function nil
+(defvar revert-buffer-insert-file-contents-function
+ #'revert-buffer-insert-file-contents--default-function
"Function to use to insert contents when reverting this buffer.
Gets two args, first the nominal file name to use,
and second, t if reading the auto-save file.
The function you specify is responsible for updating (or preserving) point.")
-(defvar buffer-stale-function nil
+(defun buffer-stale--default-function (&optional _noconfirm)
+ (and buffer-file-name
+ (file-readable-p buffer-file-name)
+ (not (verify-visited-file-modtime (current-buffer)))))
+
+(defvar buffer-stale-function #'buffer-stale--default-function
"Function to check whether a non-file buffer needs reverting.
This should be a function with one optional argument NOCONFIRM.
Auto Revert Mode passes t for NOCONFIRM. The function should return
@@ -5382,62 +5392,11 @@ non-nil, it is called instead of rereading visited file contents."
(local-hook (when (local-variable-p 'after-revert-hook)
after-revert-hook))
(inhibit-read-only t))
- (cond
- (revert-buffer-insert-file-contents-function
- (unless (eq buffer-undo-list t)
- ;; Get rid of all undo records for this buffer.
- (setq buffer-undo-list nil))
- ;; Don't make undo records for the reversion.
- (let ((buffer-undo-list t))
- (funcall revert-buffer-insert-file-contents-function
- file-name auto-save-p)))
- ((not (file-exists-p file-name))
- (error (if buffer-file-number
- "File %s no longer exists!"
- "Cannot revert nonexistent file %s")
- file-name))
- ((not (file-readable-p file-name))
- (error (if buffer-file-number
- "File %s no longer readable!"
- "Cannot revert unreadable file %s")
- file-name))
- (t
- ;; Bind buffer-file-name to nil
- ;; so that we don't try to lock the file.
- (let ((buffer-file-name nil))
- (or auto-save-p
- (unlock-buffer)))
- (widen)
- (let ((coding-system-for-read
- ;; Auto-saved file should be read by Emacs's
- ;; internal coding.
- (if auto-save-p 'auto-save-coding
- (or coding-system-for-read
- (and
- buffer-file-coding-system-explicit
- (car buffer-file-coding-system-explicit))))))
- (if (and (not enable-multibyte-characters)
- coding-system-for-read
- (not (memq (coding-system-base
- coding-system-for-read)
- '(no-conversion raw-text))))
- ;; As a coding system suitable for multibyte
- ;; buffer is specified, make the current
- ;; buffer multibyte.
- (set-buffer-multibyte t))
-
- ;; This force after-insert-file-set-coding
- ;; (called from insert-file-contents) to set
- ;; buffer-file-coding-system to a proper value.
- (kill-local-variable 'buffer-file-coding-system)
-
- ;; Note that this preserves point in an intelligent way.
- (if revert-buffer-preserve-modes
- (let ((buffer-file-format buffer-file-format))
- (insert-file-contents file-name (not auto-save-p)
- nil nil t))
- (insert-file-contents file-name (not auto-save-p)
- nil nil t)))))
+ ;; FIXME: Throw away undo-log when preserve-modes is nil?
+ (funcall
+ (or revert-buffer-insert-file-contents-function
+ #'revert-buffer-insert-file-contents--default-function)
+ file-name auto-save-p)
;; Recompute the truename in case changes in symlinks
;; have changed the truename.
(setq buffer-file-truename
@@ -5452,6 +5411,56 @@ non-nil, it is called instead of rereading visited file contents."
(run-hooks 'revert-buffer-internal-hook))
t)))))
+(defun revert-buffer-insert-file-contents--default-function (file-name auto-save-p)
+ (cond
+ ((not (file-exists-p file-name))
+ (error (if buffer-file-number
+ "File %s no longer exists!"
+ "Cannot revert nonexistent file %s")
+ file-name))
+ ((not (file-readable-p file-name))
+ (error (if buffer-file-number
+ "File %s no longer readable!"
+ "Cannot revert unreadable file %s")
+ file-name))
+ (t
+ ;; Bind buffer-file-name to nil
+ ;; so that we don't try to lock the file.
+ (let ((buffer-file-name nil))
+ (or auto-save-p
+ (unlock-buffer)))
+ (widen)
+ (let ((coding-system-for-read
+ ;; Auto-saved file should be read by Emacs's
+ ;; internal coding.
+ (if auto-save-p 'auto-save-coding
+ (or coding-system-for-read
+ (and
+ buffer-file-coding-system-explicit
+ (car buffer-file-coding-system-explicit))))))
+ (if (and (not enable-multibyte-characters)
+ coding-system-for-read
+ (not (memq (coding-system-base
+ coding-system-for-read)
+ '(no-conversion raw-text))))
+ ;; As a coding system suitable for multibyte
+ ;; buffer is specified, make the current
+ ;; buffer multibyte.
+ (set-buffer-multibyte t))
+
+ ;; This force after-insert-file-set-coding
+ ;; (called from insert-file-contents) to set
+ ;; buffer-file-coding-system to a proper value.
+ (kill-local-variable 'buffer-file-coding-system)
+
+ ;; Note that this preserves point in an intelligent way.
+ (if revert-buffer-preserve-modes
+ (let ((buffer-file-format buffer-file-format))
+ (insert-file-contents file-name (not auto-save-p)
+ nil nil t))
+ (insert-file-contents file-name (not auto-save-p)
+ nil nil t))))))
+
(defun recover-this-file ()
"Recover the visited file--get contents from its last auto-save file."
(interactive)
@@ -6204,9 +6213,10 @@ normally equivalent short `-D' option is just passed on to
;; directory if FILE is a symbolic link.
(unless full-directory-p
(setq switches
- (if (stringp switches)
- (concat switches " -d")
- (add-to-list 'switches "-d" 'append))))
+ (cond
+ ((stringp switches) (concat switches " -d"))
+ ((member "-d" switches) switches)
+ (t (append switches '("-d"))))))
(apply 'call-process
insert-directory-program nil t nil
(append
@@ -6479,7 +6489,7 @@ With prefix ARG, silently save all file-visiting buffers, then kill.
If emacsclient was started with a list of filenames to edit, then
only these files will be asked to be saved."
(interactive "P")
- (if (frame-parameter (selected-frame) 'client)
+ (if (frame-parameter nil 'client)
(server-save-buffers-kill-terminal arg)
(save-buffers-kill-emacs arg)))
diff --git a/lisp/frameset.el b/lisp/frameset.el
new file mode 100644
index 00000000000..63ee9af23fc
--- /dev/null
+++ b/lisp/frameset.el
@@ -0,0 +1,693 @@
+;;; frameset.el --- save and restore frame and window setup -*- lexical-binding: t -*-
+
+;; Copyright (C) 2013 Free Software Foundation, Inc.
+
+;; Author: Juanma Barranquero <lekktu@gmail.com>
+;; Keywords: convenience
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This file provides a set of operations to save a frameset (the state
+;; of all or a subset of the existing frames and windows), both
+;; in-session and persistently, and restore it at some point in the
+;; future.
+;;
+;; It should be noted that restoring the frames' windows depends on
+;; the buffers they are displaying, but this package does not provide
+;; any way to save and restore sets of buffers (see desktop.el for
+;; that). So, it's up to the user of frameset.el to make sure that
+;; any relevant buffer is loaded before trying to restore a frameset.
+;; When a window is restored and a buffer is missing, the window will
+;; be deleted unless it is the last one in the frame, in which case
+;; some previous buffer will be shown instead.
+
+;;; Code:
+
+(require 'cl-lib)
+
+
+;; Framesets have two fields:
+;; - properties: a property list to store both frameset-specific and
+;; user-defined serializable data. Currently defined properties
+;; include:
+;; :version ID - Identifies the version of the frameset struct;
+;; this is the only property always present and
+;; must not be modified.
+;; :app APPINFO - Freeform. Can be used by applications and
+;; packages to indicate the intended (but by no
+;; means exclusive) use of the frameset. For
+;; example, currently desktop.el sets :app to
+;; `(desktop . ,desktop-file-version).
+;; :name NAME - The name of the frameset instance; a string.
+;; :desc TEXT - A description for user consumption (to choose
+;; among framesets, etc.); a string.
+;; - states: an alist of items (FRAME-PARAMETERS . WINDOW-STATE) in
+;; no particular order. Each item represents a frame to be
+;; restored.
+
+(cl-defstruct (frameset (:type list) :named
+ (:copier nil)
+ (:predicate nil))
+ properties ;; property list
+ states) ;; list of conses (frame-state . window-state)
+
+(defun copy-frameset (frameset)
+ "Return a copy of FRAMESET.
+This is a deep copy done with `copy-tree'."
+ (copy-tree frameset t))
+
+;;;###autoload
+(defun frameset-p (frameset)
+ "If FRAMESET is a frameset, return its :version.
+Else return nil."
+ (and (eq (car-safe frameset) 'frameset)
+ (plist-get (cl-second frameset) :version)))
+
+;; A setf'able accessor to the frameset's properties
+(defun frameset-prop (frameset prop)
+ "Return the value of the PROP property of FRAMESET.
+
+Properties other than :version can be set with
+
+ (setf (frameset-prop FRAMESET PROP) NEW-VALUE)"
+ (plist-get (frameset-properties frameset) prop))
+
+(gv-define-setter frameset-prop (val fs prop)
+ (macroexp-let2 nil v val
+ `(progn
+ (cl-assert (not (eq ,prop :version)) t ":version can not be set")
+ (setf (frameset-properties ,fs)
+ (plist-put (frameset-properties ,fs) ,prop ,v))
+ ,v)))
+
+
+;; Filtering
+
+(defvar frameset-filter-alist
+ '((background-color . frameset-filter-sanitize-color)
+ (buffer-list . t)
+ (buffer-predicate . t)
+ (buried-buffer-list . t)
+ (font . frameset-filter-save-parm)
+ (foreground-color . frameset-filter-sanitize-color)
+ (fullscreen . frameset-filter-save-parm)
+ (GUI:font . frameset-filter-restore-parm)
+ (GUI:fullscreen . frameset-filter-restore-parm)
+ (GUI:height . frameset-filter-restore-parm)
+ (GUI:width . frameset-filter-restore-parm)
+ (height . frameset-filter-save-parm)
+ (left . frameset-filter-iconified)
+ (minibuffer . frameset-filter-minibuffer)
+ (top . frameset-filter-iconified)
+ (width . frameset-filter-save-parm))
+ "Alist of frame parameters and filtering functions.
+
+Each element is a cons (PARAM . ACTION), where PARAM is a parameter
+name (a symbol identifying a frame parameter), and ACTION can be:
+
+ t The parameter is always removed from the parameter list.
+ :save The parameter is removed when saving the frame.
+ :restore The parameter is removed when restoring the frame.
+ FILTER A filter function.
+
+FILTER can be a symbol FILTER-FUN, or a list (FILTER-FUN ARGS...).
+It will be called with four arguments CURRENT, FILTERED, PARAMETERS
+and SAVING, plus any additional ARGS:
+
+ CURRENT A cons (PARAM . VALUE), where PARAM is the one being
+ filtered and VALUE is its current value.
+ FILTERED The alist of parameters filtered so far.
+ PARAMETERS The complete alist of parameters being filtered,
+ SAVING Non-nil if filtering before saving state, nil otherwise.
+
+The FILTER-FUN function must return:
+ nil CURRENT is removed from the list.
+ t CURRENT is left as is.
+ (PARAM' . VALUE') Replace CURRENT with this.
+
+Frame parameters not on this list are passed intact.")
+
+(defvar frameset--target-display nil
+ ;; Either (minibuffer . VALUE) or nil.
+ ;; This refers to the current frame config being processed inside
+ ;; `frame--restore-frames' and its auxiliary functions (like filtering).
+ ;; If nil, there is no need to change the display.
+ ;; If non-nil, display parameter to use when creating the frame.
+ "Internal use only.")
+
+(defun frameset-switch-to-gui-p (parameters)
+ "True when switching to a graphic display.
+Return t if PARAMETERS describes a text-only terminal and
+the target is a graphic display; otherwise return nil.
+Only meaningful when called from a filtering function in
+`frameset-filter-alist'."
+ (and frameset--target-display ; we're switching
+ (null (cdr (assq 'display parameters))) ; from a tty
+ (cdr frameset--target-display))) ; to a GUI display
+
+(defun frameset-switch-to-tty-p (parameters)
+ "True when switching to a text-only terminal.
+Return t if PARAMETERS describes a graphic display and
+the target is a text-only terminal; otherwise return nil.
+Only meaningful when called from a filtering function in
+`frameset-filter-alist'."
+ (and frameset--target-display ; we're switching
+ (cdr (assq 'display parameters)) ; from a GUI display
+ (null (cdr frameset--target-display)))) ; to a tty
+
+(defun frameset-filter-sanitize-color (current _filtered parameters saving)
+ "When switching to a GUI frame, remove \"unspecified\" colors.
+Useful as a filter function for tty-specific parameters."
+ (or saving
+ (not (frameset-switch-to-gui-p parameters))
+ (not (stringp (cdr current)))
+ (not (string-match-p "^unspecified-[fb]g$" (cdr current)))))
+
+(defun frameset-filter-minibuffer (current _filtered _parameters saving)
+ "When saving, convert (minibuffer . #<window>) parameter to (minibuffer . t)."
+ (or (not saving)
+ (if (windowp (cdr current))
+ '(minibuffer . t)
+ t)))
+
+(defun frameset-filter-save-parm (current _filtered parameters saving
+ &optional prefix)
+ "When switching to a tty frame, save parameter P as PREFIX:P.
+The parameter can be later restored with `frameset-filter-restore-parm'.
+PREFIX defaults to `GUI'."
+ (unless prefix (setq prefix 'GUI))
+ (cond (saving t)
+ ((frameset-switch-to-tty-p parameters)
+ (let ((prefix:p (intern (format "%s:%s" prefix (car current)))))
+ (if (assq prefix:p parameters)
+ nil
+ (cons prefix:p (cdr current)))))
+ ((frameset-switch-to-gui-p parameters)
+ (not (assq (intern (format "%s:%s" prefix (car current))) parameters)))
+ (t t)))
+
+(defun frameset-filter-restore-parm (current filtered parameters saving)
+ "When switching to a GUI frame, restore PREFIX:P parameter as P.
+CURRENT must be of the form (PREFIX:P . value)."
+ (or saving
+ (not (frameset-switch-to-gui-p parameters))
+ (let* ((prefix:p (symbol-name (car current)))
+ (p (intern (substring prefix:p
+ (1+ (string-match-p ":" prefix:p)))))
+ (val (cdr current))
+ (found (assq p filtered)))
+ (if (not found)
+ (cons p val)
+ (setcdr found val)
+ nil))))
+
+(defun frameset-filter-iconified (_current _filtered parameters saving)
+ "Remove CURRENT when saving an iconified frame.
+This is used for positions parameters `left' and `top', which are
+meaningless in an iconified frame, so the frame is restored in a
+default position."
+ (not (and saving (eq (cdr (assq 'visibility parameters)) 'icon))))
+
+(defun frameset-keep-original-display-p (force-display)
+ "True if saved frames' displays should be honored."
+ (cond ((daemonp) t)
+ ((eq system-type 'windows-nt) nil)
+ (t (null force-display))))
+
+(defun frameset-filter-params (parameters filter-alist saving)
+ "Filter parameter list PARAMETERS and return a filtered list.
+FILTER-ALIST is an alist of parameter filters, in the format of
+`frameset-filter-alist' (which see).
+SAVING is non-nil while filtering parameters to save a frameset,
+nil while the filtering is done to restore it."
+ (let ((filtered nil))
+ (dolist (current parameters)
+ (pcase (cdr (assq (car current) filter-alist))
+ (`nil
+ (push current filtered))
+ (`t
+ nil)
+ (:save
+ (unless saving (push current filtered)))
+ (:restore
+ (when saving (push current filtered)))
+ ((or `(,fun . ,args) (and fun (pred fboundp)))
+ (let ((this (apply fun current filtered parameters saving args)))
+ (when this
+ (push (if (eq this t) current this) filtered))))
+ (other
+ (delay-warning 'frameset (format "Unknown filter %S" other) :error))))
+ ;; Set the display parameter after filtering, so that filter functions
+ ;; have access to its original value.
+ (when frameset--target-display
+ (let ((display (assq 'display filtered)))
+ (if display
+ (setcdr display (cdr frameset--target-display))
+ (push frameset--target-display filtered))))
+ filtered))
+
+
+;; Saving framesets
+
+(defun frameset--set-id (frame)
+ "Set FRAME's `frameset-id' if not yet set.
+Internal use only."
+ (unless (frame-parameter frame 'frameset-id)
+ (set-frame-parameter frame
+ 'frameset-id
+ (mapconcat (lambda (n) (format "%04X" n))
+ (cl-loop repeat 4 collect (random 65536))
+ "-"))))
+
+(defun frameset--process-minibuffer-frames (frame-list)
+ "Process FRAME-LIST and record minibuffer relationships.
+FRAME-LIST is a list of frames."
+ ;; Record frames with their own minibuffer
+ (dolist (frame (minibuffer-frame-list))
+ (when (memq frame frame-list)
+ (frameset--set-id frame)
+ ;; For minibuffer-owning frames, frameset--mini is a cons
+ ;; (t . DEFAULT?), where DEFAULT? is a boolean indicating whether
+ ;; the frame is the one pointed out by `default-minibuffer-frame'.
+ (set-frame-parameter frame
+ 'frameset--mini
+ (cons t (eq frame default-minibuffer-frame)))))
+ ;; Now link minibufferless frames with their minibuffer frames
+ (dolist (frame frame-list)
+ (unless (frame-parameter frame 'frameset--mini)
+ (frameset--set-id frame)
+ (let* ((mb-frame (window-frame (minibuffer-window frame)))
+ (id (and mb-frame (frame-parameter mb-frame 'frameset-id))))
+ (if (null id)
+ (error "Minibuffer frame %S for %S is excluded" mb-frame frame)
+ ;; For minibufferless frames, frameset--mini is a cons
+ ;; (nil . FRAME-ID), where FRAME-ID is the frameset-id of
+ ;; the frame containing its minibuffer window.
+ (set-frame-parameter frame
+ 'frameset--mini
+ (cons nil id)))))))
+
+;;;###autoload
+(cl-defun frameset-save (frame-list &key filters predicate properties)
+ "Return the frameset of FRAME-LIST, a list of frames.
+If nil, FRAME-LIST defaults to all live frames.
+FILTERS is an alist of parameter filters; defaults to `frameset-filter-alist'.
+PREDICATE is a predicate function, which must return non-nil for frames that
+should be saved; it defaults to saving all frames from FRAME-LIST.
+PROPERTIES is a user-defined property list to add to the frameset."
+ (let ((frames (cl-delete-if-not #'frame-live-p
+ (cl-delete-if-not (or predicate #'framep)
+ (or (copy-sequence frame-list)
+ (frame-list))))))
+ (frameset--process-minibuffer-frames frames)
+ (make-frameset :properties (append '(:version 1) properties)
+ :states (mapcar
+ (lambda (frame)
+ (cons
+ (frameset-filter-params (frame-parameters frame)
+ (or filters
+ frameset-filter-alist)
+ t)
+ (window-state-get (frame-root-window frame) t)))
+ frames))))
+
+
+;; Restoring framesets
+
+(defvar frameset--reuse-list nil
+ "Internal use only.")
+
+(defun frameset--compute-pos (value left/top right/bottom)
+ (pcase value
+ (`(+ ,val) (+ left/top val))
+ (`(- ,val) (+ right/bottom val))
+ (val val)))
+
+(defun frameset--move-onscreen (frame force-onscreen)
+ "If FRAME is offscreen, move it back onscreen and, if necessary, resize it.
+For the description of FORCE-ONSCREEN, see `frameset-restore'.
+When forced onscreen, frames wider than the monitor's workarea are converted
+to fullwidth, and frames taller than the workarea are converted to fullheight.
+NOTE: This only works for non-iconified frames. Internal use only."
+ (pcase-let* ((`(,left ,top ,width ,height) (cl-cdadr (frame-monitor-attributes frame)))
+ (right (+ left width -1))
+ (bottom (+ top height -1))
+ (fr-left (frameset--compute-pos (frame-parameter frame 'left) left right))
+ (fr-top (frameset--compute-pos (frame-parameter frame 'top) top bottom))
+ (ch-width (frame-char-width frame))
+ (ch-height (frame-char-height frame))
+ (fr-width (max (frame-pixel-width frame) (* ch-width (frame-width frame))))
+ (fr-height (max (frame-pixel-height frame) (* ch-height (frame-height frame))))
+ (fr-right (+ fr-left fr-width -1))
+ (fr-bottom (+ fr-top fr-height -1)))
+ (when (pcase force-onscreen
+ ;; Any corner is outside the screen.
+ (`all (or (< fr-bottom top) (> fr-bottom bottom)
+ (< fr-left left) (> fr-left right)
+ (< fr-right left) (> fr-right right)
+ (< fr-top top) (> fr-top bottom)))
+ ;; Displaced to the left, right, above or below the screen.
+ (`t (or (> fr-left right)
+ (< fr-right left)
+ (> fr-top bottom)
+ (< fr-bottom top)))
+ ;; Fully inside, no need to do anything.
+ (_ nil))
+ (let ((fullwidth (> fr-width width))
+ (fullheight (> fr-height height))
+ (params nil))
+ ;; Position frame horizontally.
+ (cond (fullwidth
+ (push `(left . ,left) params))
+ ((> fr-right right)
+ (push `(left . ,(+ left (- width fr-width))) params))
+ ((< fr-left left)
+ (push `(left . ,left) params)))
+ ;; Position frame vertically.
+ (cond (fullheight
+ (push `(top . ,top) params))
+ ((> fr-bottom bottom)
+ (push `(top . ,(+ top (- height fr-height))) params))
+ ((< fr-top top)
+ (push `(top . ,top) params)))
+ ;; Compute fullscreen state, if required.
+ (when (or fullwidth fullheight)
+ (push (cons 'fullscreen
+ (cond ((not fullwidth) 'fullheight)
+ ((not fullheight) 'fullwidth)
+ (t 'maximized)))
+ params))
+ ;; Finally, move the frame back onscreen.
+ (when params
+ (modify-frame-parameters frame params))))))
+
+(defun frameset--find-frame (predicate display &rest args)
+ "Find a frame in `frameset--reuse-list' satisfying PREDICATE.
+Look through available frames whose display property matches DISPLAY
+and return the first one for which (PREDICATE frame ARGS) returns t.
+If PREDICATE is nil, it is always satisfied. Internal use only."
+ (cl-find-if (lambda (frame)
+ (and (equal (frame-parameter frame 'display) display)
+ (or (null predicate)
+ (apply predicate frame args))))
+ frameset--reuse-list))
+
+(defun frameset--reuse-frame (display frame-cfg)
+ "Look for an existing frame to reuse.
+DISPLAY is the display where the frame will be shown, and FRAME-CFG
+is the parameter list of the frame being restored. Internal use only."
+ (let ((frame nil)
+ mini)
+ ;; There are no fancy heuristics there. We could implement some
+ ;; based on frame size and/or position, etc., but it is not clear
+ ;; that any "gain" (in the sense of reduced flickering, etc.) is
+ ;; worth the added complexity. In fact, the code below mainly
+ ;; tries to work nicely when M-x desktop-read is used after a
+ ;; desktop session has already been loaded. The other main use
+ ;; case, which is the initial desktop-read upon starting Emacs,
+ ;; will usually have only one frame, and should already work.
+ (cond ((null display)
+ ;; When the target is tty, every existing frame is reusable.
+ (setq frame (frameset--find-frame nil display)))
+ ((car (setq mini (cdr (assq 'frameset--mini frame-cfg))))
+ ;; If the frame has its own minibuffer, let's see whether
+ ;; that frame has already been loaded (which can happen after
+ ;; M-x desktop-read).
+ (setq frame (frameset--find-frame
+ (lambda (f id)
+ (string= (frame-parameter f 'frameset-id) id))
+ display (cdr mini)))
+ ;; If it has not been loaded, and it is not a minibuffer-only frame,
+ ;; let's look for an existing non-minibuffer-only frame to reuse.
+ (unless (or frame (eq (cdr (assq 'minibuffer frame-cfg)) 'only))
+ (setq frame (frameset--find-frame
+ (lambda (f)
+ (let ((w (frame-parameter f 'minibuffer)))
+ (and (window-live-p w)
+ (window-minibuffer-p w)
+ (eq (window-frame w) f))))
+ display))))
+ (mini
+ ;; For minibufferless frames, check whether they already exist,
+ ;; and that they are linked to the right minibuffer frame.
+ (setq frame (frameset--find-frame
+ (lambda (f id mini-id)
+ (and (string= (frame-parameter f 'frameset-id) id)
+ (string= (frame-parameter (window-frame (minibuffer-window f))
+ 'frameset-id)
+ mini-id)))
+ display (cdr (assq 'frameset-id frame-cfg)) (cdr mini))))
+ (t
+ ;; Default to just finding a frame in the same display.
+ (setq frame (frameset--find-frame nil display))))
+ ;; If found, remove from the list.
+ (when frame
+ (setq frameset--reuse-list (delq frame frameset--reuse-list)))
+ frame))
+
+(defun frameset--get-frame (frame-cfg window-cfg filters force-onscreen)
+ "Set up and return a frame according to its saved state.
+That means either reusing an existing frame or creating one anew.
+FRAME-CFG is the frame's parameter list; WINDOW-CFG is its window state.
+For the meaning of FORCE-ONSCREEN, see `frameset-restore'."
+ (let* ((fullscreen (cdr (assq 'fullscreen frame-cfg)))
+ (lines (assq 'tool-bar-lines frame-cfg))
+ (filtered-cfg (frameset-filter-params frame-cfg filters nil))
+ (display (cdr (assq 'display filtered-cfg))) ;; post-filtering
+ alt-cfg frame)
+
+ ;; This works around bug#14795 (or feature#14795, if not a bug :-)
+ (setq filtered-cfg (assq-delete-all 'tool-bar-lines filtered-cfg))
+ (push '(tool-bar-lines . 0) filtered-cfg)
+
+ (when fullscreen
+ ;; Currently Emacs has the limitation that it does not record the size
+ ;; and position of a frame before maximizing it, so we cannot save &
+ ;; restore that info. Instead, when restoring, we resort to creating
+ ;; invisible "fullscreen" frames of default size and then maximizing them
+ ;; (and making them visible) which at least is somewhat user-friendly
+ ;; when these frames are later de-maximized.
+ (let ((width (and (eq fullscreen 'fullheight) (cdr (assq 'width filtered-cfg))))
+ (height (and (eq fullscreen 'fullwidth) (cdr (assq 'height filtered-cfg))))
+ (visible (assq 'visibility filtered-cfg)))
+ (setq filtered-cfg (cl-delete-if (lambda (p)
+ (memq p '(visibility fullscreen width height)))
+ filtered-cfg :key #'car))
+ (when width
+ (setq filtered-cfg (append `((user-size . t) (width . ,width))
+ filtered-cfg)))
+ (when height
+ (setq filtered-cfg (append `((user-size . t) (height . ,height))
+ filtered-cfg)))
+ ;; These are parameters to apply after creating/setting the frame.
+ (push visible alt-cfg)
+ (push (cons 'fullscreen fullscreen) alt-cfg)))
+
+ ;; Time to find or create a frame an apply the big bunch of parameters.
+ ;; If a frame needs to be created and it falls partially or fully offscreen,
+ ;; sometimes it gets "pushed back" onscreen; however, moving it afterwards is
+ ;; allowed. So we create the frame as invisible and then reapply the full
+ ;; parameter list (including position and size parameters).
+ (setq frame (or (and frameset--reuse-list
+ (frameset--reuse-frame display filtered-cfg))
+ (make-frame-on-display display
+ (cons '(visibility)
+ (cl-loop
+ for param in '(left top width height minibuffer)
+ collect (assq param filtered-cfg))))))
+ (modify-frame-parameters frame
+ (if (eq (frame-parameter frame 'fullscreen) fullscreen)
+ ;; Workaround for bug#14949
+ (assq-delete-all 'fullscreen filtered-cfg)
+ filtered-cfg))
+
+ ;; If requested, force frames to be onscreen.
+ (when (and force-onscreen
+ ;; FIXME: iconified frames should be checked too,
+ ;; but it is impossible without deiconifying them.
+ (not (eq (frame-parameter frame 'visibility) 'icon)))
+ (frameset--move-onscreen frame force-onscreen))
+
+ ;; Let's give the finishing touches (visibility, tool-bar, maximization).
+ (when lines (push lines alt-cfg))
+ (when alt-cfg (modify-frame-parameters frame alt-cfg))
+ ;; Now restore window state.
+ (window-state-put window-cfg (frame-root-window frame) 'safe)
+ frame))
+
+(defun frameset--sort-states (state1 state2)
+ "Predicate to sort frame states in a suitable order to be created.
+It sorts minibuffer-owning frames before minibufferless ones."
+ (pcase-let ((`(,hasmini1 ,id-def1) (assq 'frameset--mini (car state1)))
+ (`(,hasmini2 ,id-def2) (assq 'frameset--mini (car state2))))
+ (cond ((eq id-def1 t) t)
+ ((eq id-def2 t) nil)
+ ((not (eq hasmini1 hasmini2)) (eq hasmini1 t))
+ ((eq hasmini1 nil) (string< id-def1 id-def2))
+ (t t))))
+
+(defun frameset-sort-frames-for-deletion (frame1 _frame2)
+ "Predicate to sort live frames for deletion.
+Minibufferless frames must go first to avoid errors when attempting
+to delete a frame whose minibuffer window is used by another frame."
+ (not (frame-parameter frame1 'minibuffer)))
+
+;;;###autoload
+(cl-defun frameset-restore (frameset &key filters reuse-frames force-display force-onscreen)
+ "Restore a FRAMESET into the current display(s).
+
+FILTERS is an alist of parameter filters; defaults to `frameset-filter-alist'.
+
+REUSE-FRAMES describes how to reuse existing frames while restoring a frameset:
+ t Reuse any existing frame if possible; delete leftover frames.
+ nil Restore frameset in new frames and delete existing frames.
+ keep Restore frameset in new frames and keep the existing ones.
+ LIST A list of frames to reuse; only these will be reused, if possible,
+ and any leftover one will be deleted; other frames not on this
+ list will be kept.
+
+FORCE-DISPLAY can be:
+ t Frames will be restored in the current display.
+ nil Frames will be restored, if possible, in their original displays.
+ delete Frames in other displays will be deleted instead of restored.
+
+FORCE-ONSCREEN can be:
+ all Force onscreen any frame fully or partially offscreen.
+ t Force onscreen only those frames that are fully offscreen.
+ nil Do not force any frame back onscreen.
+
+All keywords default to nil."
+
+ (cl-assert (frameset-p frameset))
+
+ (let* ((delete-saved (eq force-display 'delete))
+ (forcing (not (frameset-keep-original-display-p force-display)))
+ (target (and forcing (cons 'display (frame-parameter nil 'display))))
+ other-frames)
+
+ ;; frameset--reuse-list is a list of frames potentially reusable. Later we
+ ;; will decide which ones can be reused, and how to deal with any leftover.
+ (pcase reuse-frames
+ ((or `nil `keep)
+ (setq frameset--reuse-list nil
+ other-frames (frame-list)))
+ ((pred consp)
+ (setq frameset--reuse-list (copy-sequence reuse-frames)
+ other-frames (cl-delete-if (lambda (frame)
+ (memq frame frameset--reuse-list))
+ (frame-list))))
+ (_
+ (setq frameset--reuse-list (frame-list)
+ other-frames nil)))
+
+ ;; Sort saved states to guarantee that minibufferless frames will be created
+ ;; after the frames that contain their minibuffer windows.
+ (dolist (state (sort (copy-sequence (frameset-states frameset))
+ #'frameset--sort-states))
+ (condition-case-unless-debug err
+ (pcase-let* ((`(,frame-cfg . ,window-cfg) state)
+ ((and d-mini `(,hasmini . ,mb-id))
+ (cdr (assq 'frameset--mini frame-cfg)))
+ (default (and (booleanp mb-id) mb-id))
+ (frame nil) (to-tty nil))
+ ;; Only set target if forcing displays and the target display is different.
+ (if (or (not forcing)
+ (equal target (or (assq 'display frame-cfg) '(display . nil))))
+ (setq frameset--target-display nil)
+ (setq frameset--target-display target
+ to-tty (null (cdr target))))
+ ;; If keeping non-reusable frames, and the frame-id of one of them
+ ;; matches the frame-id of a frame being restored (because, for example,
+ ;; the frameset has already been read in the same session), remove the
+ ;; frame-id from the non-reusable frame, which is not useful anymore.
+ (when (and other-frames
+ (or (eq reuse-frames 'keep) (consp reuse-frames)))
+ (let ((dup (cl-find (cdr (assq 'frameset-frame-id frame-cfg))
+ other-frames
+ :key (lambda (frame)
+ (frame-parameter frame 'frameset-frame-id))
+ :test #'string=)))
+ (when dup
+ (set-frame-parameter dup 'frameset-frame-id nil))))
+ ;; Time to restore frames and set up their minibuffers as they were.
+ ;; We only skip a frame (thus deleting it) if either:
+ ;; - we're switching displays, and the user chose the option to delete, or
+ ;; - we're switching to tty, and the frame to restore is minibuffer-only.
+ (unless (and frameset--target-display
+ (or delete-saved
+ (and to-tty
+ (eq (cdr (assq 'minibuffer frame-cfg)) 'only))))
+
+ ;; Restore minibuffers. Some of this stuff could be done in a filter
+ ;; function, but it would be messy because restoring minibuffers affects
+ ;; global state; it's best to do it here than add a bunch of global
+ ;; variables to pass info back-and-forth to/from the filter function.
+ (cond
+ ((null d-mini)) ;; No frameset--mini. Process as normal frame.
+ (to-tty) ;; Ignore minibuffer stuff and process as normal frame.
+ (hasmini ;; Frame has minibuffer (or it is minibuffer-only).
+ (when (eq (cdr (assq 'minibuffer frame-cfg)) 'only)
+ (setq frame-cfg (append '((tool-bar-lines . 0) (menu-bar-lines . 0))
+ frame-cfg))))
+ (t ;; Frame depends on other frame's minibuffer window.
+ (let* ((mb-frame (or (cl-find-if
+ (lambda (f)
+ (string= (frame-parameter f 'frameset-id)
+ mb-id))
+ (frame-list))
+ (error "Minibuffer frame %S not found" mb-id)))
+ (mb-param (assq 'minibuffer frame-cfg))
+ (mb-window (minibuffer-window mb-frame)))
+ (unless (and (window-live-p mb-window)
+ (window-minibuffer-p mb-window))
+ (error "Not a minibuffer window %s" mb-window))
+ (if mb-param
+ (setcdr mb-param mb-window)
+ (push (cons 'minibuffer mb-window) frame-cfg))))))
+ ;; OK, we're ready at last to create (or reuse) a frame and
+ ;; restore the window config.
+ (setq frame (frameset--get-frame frame-cfg window-cfg
+ (or filters frameset-filter-alist)
+ force-onscreen))
+ ;; Set default-minibuffer if required.
+ (when default (setq default-minibuffer-frame frame)))
+ (error
+ (delay-warning 'frameset (error-message-string err) :error))))
+
+ ;; In case we try to delete the initial frame, we want to make sure that
+ ;; other frames are already visible (discussed in thread for bug#14841).
+ (sit-for 0 t)
+
+ ;; Delete remaining frames, but do not fail if some resist being deleted.
+ (unless (eq reuse-frames 'keep)
+ (dolist (frame (sort (nconc (if (listp reuse-frames) nil other-frames)
+ frameset--reuse-list)
+ #'frameset-sort-frames-for-deletion))
+ (condition-case err
+ (delete-frame frame)
+ (error
+ (delay-warning 'frameset (error-message-string err))))))
+ (setq frameset--reuse-list nil)
+
+ ;; Make sure there's at least one visible frame.
+ (unless (or (daemonp) (visible-frame-list))
+ (make-frame-visible (car (frame-list))))))
+
+(provide 'frameset)
+
+;;; frameset.el ends here
diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog
index 4230d010a5d..2164fd96b46 100644
--- a/lisp/gnus/ChangeLog
+++ b/lisp/gnus/ChangeLog
@@ -1,5 +1,76 @@
+2013-08-02 Lars Magne Ingebrigtsen <larsi@gnus.org>
+
+ * gnus-delay.el (gnus-delay-article): Fix typo.
+
+ * gnus-group.el (gnus-group-delete-articles): Allow deleting only "old"
+ articles.
+
+ * gnus-delay.el (gnus-delay-article): Run `message-send-hook' so that
+ we can get spell-checking etc.
+
+2013-08-02 Katsumi Yamaoka <yamaoka@jpl.org>
+
+ * rfc2047.el (rfc2047-encode-message-header): Unify charsets into
+ a single one used for encoding the whole text in a header.
+
+2013-08-01 Lars Magne Ingebrigtsen <larsi@gnus.org>
+
+ * message.el (message-ignored-news-headers): Delete X-Gnus-Delayed
+ before sending.
+
+ * mm-decode.el (mm-command-output): New face.
+ (mm-display-external): Use it.
+
+2013-08-01 Kan-Ru Chen (陳侃如) <kanru@kanru.info> (tiny change)
+
+ * nnmbox.el (nnmbox-request-article): Don't change point.
+
+2013-08-01 Lars Magne Ingebrigtsen <larsi@gnus.org>
+
+ * gnus-icalendar.el (gnus-icalendar-event:inline-reply-buttons):
+ Include `handle' parameter.
+
+2013-08-01 Jan Tatarik <jan.tatarik@gmail.com>
+
+ * gnus-icalendar.el: New file.
+
+2013-08-01 Lars Magne Ingebrigtsen <larsi@gnus.org>
+
+ * gnus-int.el (gnus-warp-to-article): Mention that warp means jump.
+
+ * gnus-uu.el (gnus-uu-mark-thread, gnus-uu-unmark-thread): Work with
+ dummy roots, too.
+
+2013-08-01 David Edmondson <dme@dme.org>
+
+ * mml2015.el (mml2015-epg-key-image-to-string): Protect against bugging
+ out on ttys.
+
+2013-08-01 Lars Magne Ingebrigtsen <larsi@gnus.org>
+
+ * gnus-start.el (gnus-dribble-save): Only save the dribble file if it's
+ not empty.
+
+ * nnrss.el (nnrss-discover-feed): Indent.
+
+2013-08-01 Katsumi Yamaoka <yamaoka@jpl.org>
+
+ * gnus-util.el (gnus-emacs-completing-read): Isolate XEmacs stuff.
+
+2013-07-30 Lars Magne Ingebrigtsen <larsi@gnus.org>
+
+ * gnus-start.el (gnus-read-active-for-groups): Always mark the data as
+ dirty to ensure nnimap data being saved.
+
2013-07-30 Tassilo Horn <tsdh@gnu.org>
+ * gnus-sum.el (gnus-summary-make-menu-bar): Add "Current thread score"
+ menu entry.
+
+ * gnus-score.el (gnus-summary-current-score): Use prefix arg to show
+ the current thread's total score instead of the current article's
+ score.
+
* gnus-sum.el (gnus-subthread-sort-functions): New defcustom.
(gnus-sort-threads-recursively): Delete defcustom.
(gnus-sort-threads-recursive): Adapt accordingly.
diff --git a/lisp/gnus/gnus-delay.el b/lisp/gnus/gnus-delay.el
index 921d24109c2..2cdafe1565b 100644
--- a/lisp/gnus/gnus-delay.el
+++ b/lisp/gnus/gnus-delay.el
@@ -80,6 +80,8 @@ DELAY is a string, giving the length of the time. Possible values are:
(list (read-string
"Target date (YYYY-MM-DD), time (hh:mm), or length of delay (units in [mhdwMY]): "
gnus-delay-default-delay)))
+ ;; Allow spell checking etc.
+ (run-hooks 'message-send-hook)
(let (num unit days year month day hour minute deadline)
(cond ((string-match
"\\([0-9][0-9][0-9]?[0-9]?\\)-\\([0-9]+\\)-\\([0-9]+\\)"
diff --git a/lisp/gnus/gnus-group.el b/lisp/gnus/gnus-group.el
index 8050f5d59d7..9533f5819a4 100644
--- a/lisp/gnus/gnus-group.el
+++ b/lisp/gnus/gnus-group.el
@@ -2796,14 +2796,21 @@ server."
(lambda (group)
(gnus-group-delete-group group nil t))))))
-(defun gnus-group-delete-articles (group)
- "Delete all articles in the current group."
- (interactive (list (gnus-group-group-name)))
+(defun gnus-group-delete-articles (group &optional oldp)
+ "Delete all articles in the current group.
+If OLDP (the prefix), only delete articles that are \"old\",
+according to the expiry settings. Note that this will delete old
+not-expirable articles, too."
+ (interactive (list (gnus-group-group-name)
+ current-prefix-arg))
(let ((articles (gnus-uncompress-range (gnus-active group))))
(when (gnus-yes-or-no-p
(format "Do you really want to delete these %d articles forever? "
(length articles)))
- (gnus-request-expire-articles articles group 'force))))
+ (gnus-request-expire-articles articles group
+ (if current-prefix-arg
+ nil
+ 'force)))))
(defun gnus-group-delete-group (group &optional force no-prompt)
"Delete the current group. Only meaningful with editable groups.
diff --git a/lisp/gnus/gnus-icalendar.el b/lisp/gnus/gnus-icalendar.el
new file mode 100644
index 00000000000..0286fd5dd89
--- /dev/null
+++ b/lisp/gnus/gnus-icalendar.el
@@ -0,0 +1,837 @@
+;;; gnus-icalendar.el --- reply to iCalendar meeting requests
+
+;; Copyright (C) 2013 Free Software Foundation, Inc.
+
+;; Author: Jan Tatarik <Jan.Tatarik@gmail.com>
+;; Keywords: mail, icalendar, org
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; To install:
+;; (require 'gnus-icalendar)
+;; (gnus-icalendar-setup)
+
+;; to enable optional iCalendar->Org sync functionality
+;; NOTE: both the capture file and the headline(s) inside must already exist
+;; (setq gnus-icalendar-org-capture-file "~/org/notes.org")
+;; (setq gnus-icalendar-org-capture-headline '("Calendar"))
+;; (gnus-icalendar-org-setup)
+
+
+;;; Code:
+
+(require 'icalendar)
+(require 'eieio)
+(require 'mm-decode)
+(require 'gnus-sum)
+
+(eval-when-compile (require 'cl))
+
+(defun gnus-icalendar-find-if (pred seq)
+ (catch 'found
+ (while seq
+ (when (funcall pred (car seq))
+ (throw 'found (car seq)))
+ (pop seq))))
+
+;;;
+;;; ical-event
+;;;
+
+(defclass gnus-icalendar-event ()
+ ((organizer :initarg :organizer
+ :accessor gnus-icalendar-event:organizer
+ :initform ""
+ :type (or null string))
+ (summary :initarg :summary
+ :accessor gnus-icalendar-event:summary
+ :initform ""
+ :type (or null string))
+ (description :initarg :description
+ :accessor gnus-icalendar-event:description
+ :initform ""
+ :type (or null string))
+ (location :initarg :location
+ :accessor gnus-icalendar-event:location
+ :initform ""
+ :type (or null string))
+ (start :initarg :start
+ :accessor gnus-icalendar-event:start
+ :initform ""
+ :type (or null string))
+ (end :initarg :end
+ :accessor gnus-icalendar-event:end
+ :initform ""
+ :type (or null string))
+ (recur :initarg :recur
+ :accessor gnus-icalendar-event:recur
+ :initform ""
+ :type (or null string))
+ (uid :initarg :uid
+ :accessor gnus-icalendar-event:uid
+ :type string)
+ (method :initarg :method
+ :accessor gnus-icalendar-event:method
+ :initform "PUBLISH"
+ :type (or null string))
+ (rsvp :initarg :rsvp
+ :accessor gnus-icalendar-event:rsvp
+ :initform nil
+ :type (or null boolean)))
+ "generic iCalendar Event class")
+
+(defclass gnus-icalendar-event-request (gnus-icalendar-event)
+ nil
+ "iCalendar class for REQUEST events")
+
+(defclass gnus-icalendar-event-cancel (gnus-icalendar-event)
+ nil
+ "iCalendar class for CANCEL events")
+
+(defclass gnus-icalendar-event-reply (gnus-icalendar-event)
+ nil
+ "iCalendar class for REPLY events")
+
+(defmethod gnus-icalendar-event:recurring-p ((event gnus-icalendar-event))
+ "Return t if EVENT is recurring."
+ (not (null (gnus-icalendar-event:recur event))))
+
+(defmethod gnus-icalendar-event:recurring-freq ((event gnus-icalendar-event))
+ "Return recurring frequency of EVENT."
+ (let ((rrule (gnus-icalendar-event:recur event)))
+ (string-match "FREQ=\\([[:alpha:]]+\\)" rrule)
+ (match-string 1 rrule)))
+
+(defmethod gnus-icalendar-event:recurring-interval ((event gnus-icalendar-event))
+ "Return recurring interval of EVENT."
+ (let ((rrule (gnus-icalendar-event:recur event))
+ (default-interval 1))
+
+ (string-match "INTERVAL=\\([[:digit:]]+\\)" rrule)
+ (or (match-string 1 rrule)
+ default-interval)))
+
+(defmethod gnus-icalendar-event:start-time ((event gnus-icalendar-event))
+ "Return time value of the EVENT start date."
+ (date-to-time (gnus-icalendar-event:start event)))
+
+(defmethod gnus-icalendar-event:end-time ((event gnus-icalendar-event))
+ "Return time value of the EVENT end date."
+ (date-to-time (gnus-icalendar-event:end event)))
+
+
+(defun gnus-icalendar-event--decode-datefield (ical field zone-map &optional date-style)
+ (let* ((calendar-date-style (or date-style 'european))
+ (date (icalendar--get-event-property ical field))
+ (date-zone (icalendar--find-time-zone
+ (icalendar--get-event-property-attributes
+ ical field)
+ zone-map))
+ (date-decoded (icalendar--decode-isodatetime date nil date-zone)))
+
+ (concat (icalendar--datetime-to-iso-date date-decoded "-")
+ " "
+ (icalendar--datetime-to-colontime date-decoded))))
+
+(defun gnus-icalendar-event--find-attendee (ical name-or-email)
+ (let* ((event (car (icalendar--all-events ical)))
+ (event-props (caddr event)))
+ (labels ((attendee-name (att) (plist-get (cadr att) 'CN))
+ (attendee-email (att)
+ (replace-regexp-in-string "^.*MAILTO:" "" (caddr att)))
+ (attendee-prop-matches-p (prop)
+ (and (eq (car prop) 'ATTENDEE)
+ (or (member (attendee-name prop) name-or-email)
+ (let ((att-email (attendee-email prop)))
+ (gnus-icalendar-find-if (lambda (email)
+ (string-match email att-email))
+ name-or-email))))))
+
+ (gnus-icalendar-find-if #'attendee-prop-matches-p event-props))))
+
+
+(defun gnus-icalendar-event-from-ical (ical &optional attendee-name-or-email)
+ (let* ((event (car (icalendar--all-events ical)))
+ (zone-map (icalendar--convert-all-timezones ical))
+ (organizer (replace-regexp-in-string
+ "^.*MAILTO:" ""
+ (or (icalendar--get-event-property event 'ORGANIZER) "")))
+ (prop-map '((summary . SUMMARY)
+ (description . DESCRIPTION)
+ (location . LOCATION)
+ (recur . RRULE)
+ (uid . UID)))
+ (method (caddr (assoc 'METHOD (caddr (car (nreverse ical))))))
+ (attendee (when attendee-name-or-email
+ (gnus-icalendar-event--find-attendee ical attendee-name-or-email)))
+ (args (list :method method
+ :organizer organizer
+ :start (gnus-icalendar-event--decode-datefield event 'DTSTART zone-map)
+ :end (gnus-icalendar-event--decode-datefield event 'DTEND zone-map)
+ :rsvp (string= (plist-get (cadr attendee) 'RSVP)
+ "TRUE")))
+ (event-class (pcase method
+ ("REQUEST" 'gnus-icalendar-event-request)
+ ("CANCEL" 'gnus-icalendar-event-cancel)
+ ("REPLY" 'gnus-icalendar-event-reply)
+ (_ 'gnus-icalendar-event))))
+
+ (labels ((map-property (prop)
+ (let ((value (icalendar--get-event-property event prop)))
+ (when value
+ ;; ugly, but cannot get
+ ;;replace-regexp-in-string work with "\\" as
+ ;;REP, plus we should also handle "\\;"
+ (replace-regexp-in-string
+ "\\\\," ","
+ (replace-regexp-in-string
+ "\\\\n" "\n" (substring-no-properties value))))))
+ (accumulate-args (mapping)
+ (destructuring-bind (slot . ical-property) mapping
+ (setq args (append (list
+ (intern (concat ":" (symbol-name slot)))
+ (map-property ical-property))
+ args)))))
+
+ (mapc #'accumulate-args prop-map)
+ (apply 'make-instance event-class args))))
+
+(defun gnus-icalendar-event-from-buffer (buf &optional attendee-name-or-email)
+ "Parse RFC5545 iCalendar in buffer BUF and return an event object.
+
+Return a gnus-icalendar-event object representing the first event
+contained in the invitation. Return nil for calendars without an event entry.
+
+ATTENDEE-NAME-OR-EMAIL is a list of strings that will be matched
+against the event's attendee names and emails. Invitation rsvp
+status will be retrieved from the first matching attendee record."
+ (let ((ical (with-current-buffer (icalendar--get-unfolded-buffer (get-buffer buf))
+ (goto-char (point-min))
+ (icalendar--read-element nil nil))))
+
+ (when ical
+ (gnus-icalendar-event-from-ical ical attendee-name-or-email))))
+
+;;;
+;;; gnus-icalendar-event-reply
+;;;
+
+(defun gnus-icalendar-event--build-reply-event-body (ical-request status identities)
+ (let ((summary-status (capitalize (symbol-name status)))
+ (attendee-status (upcase (symbol-name status)))
+ reply-event-lines)
+ (labels ((update-summary (line)
+ (if (string-match "^[^:]+:" line)
+ (replace-match (format "\\&%s: " summary-status) t nil line)
+ line))
+ (update-dtstamp ()
+ (format-time-string "DTSTAMP:%Y%m%dT%H%M%SZ" nil t))
+ (attendee-matches-identity (line)
+ (gnus-icalendar-find-if (lambda (name) (string-match-p name line))
+ identities))
+ (update-attendee-status (line)
+ (when (and (attendee-matches-identity line)
+ (string-match "\\(PARTSTAT=\\)[^;]+" line))
+ (replace-match (format "\\1%s" attendee-status) t nil line)))
+ (process-event-line (line)
+ (when (string-match "^\\([^;:]+\\)" line)
+ (let* ((key (match-string 0 line))
+ ;; NOTE: not all of the below fields are mandatory,
+ ;; but they are often present in other clients'
+ ;; replies. Can be helpful for debugging, too.
+ (new-line (pcase key
+ ("ATTENDEE" (update-attendee-status line))
+ ("SUMMARY" (update-summary line))
+ ("DTSTAMP" (update-dtstamp))
+ ((or "ORGANIZER" "DTSTART" "DTEND"
+ "LOCATION" "DURATION" "SEQUENCE"
+ "RECURRENCE-ID" "UID") line)
+ (_ nil))))
+ (when new-line
+ (push new-line reply-event-lines))))))
+
+ (mapc #'process-event-line (split-string ical-request "\n"))
+
+ (unless (gnus-icalendar-find-if (lambda (x) (string-match "^ATTENDEE" x))
+ reply-event-lines)
+ (error "Could not find an event attendee matching given identity"))
+
+ (mapconcat #'identity `("BEGIN:VEVENT"
+ ,@(nreverse reply-event-lines)
+ "END:VEVENT")
+ "\n"))))
+
+(defun gnus-icalendar-event-reply-from-buffer (buf status identities)
+ "Build a calendar event reply for request contained in BUF.
+The reply will have STATUS (`accepted', `tentative' or `declined').
+The reply will be composed for attendees matching any entry
+on the IDENTITIES list."
+ (flet ((extract-block (blockname)
+ (save-excursion
+ (let ((block-start-re (format "^BEGIN:%s" blockname))
+ (block-end-re (format "^END:%s" blockname))
+ start)
+ (when (re-search-forward block-start-re nil t)
+ (setq start (line-beginning-position))
+ (re-search-forward block-end-re)
+ (buffer-substring-no-properties start (line-end-position)))))))
+
+ (let (zone event)
+ (with-current-buffer (icalendar--get-unfolded-buffer (get-buffer buf))
+ (goto-char (point-min))
+ (setq zone (extract-block "VTIMEZONE")
+ event (extract-block "VEVENT")))
+
+ (when event
+ (let ((contents (list "BEGIN:VCALENDAR"
+ "METHOD:REPLY"
+ "PRODID:Gnus"
+ "VERSION:2.0"
+ zone
+ (gnus-icalendar-event--build-reply-event-body event status identities)
+ "END:VCALENDAR")))
+
+ (mapconcat #'identity (delq nil contents) "\n"))))))
+
+;;;
+;;; gnus-icalendar-org
+;;;
+;;; TODO: this is an optional feature, and it's only available with org-mode
+;;; 7+, so will need to properly handle emacsen with no/outdated org-mode
+
+(require 'org)
+(require 'org-capture)
+
+(defgroup gnus-icalendar-org nil
+ "Settings for Calendar Event gnus/org integration."
+ :group 'gnus-icalendar
+ :prefix "gnus-icalendar-org-")
+
+(defcustom gnus-icalendar-org-capture-file nil
+ "Target Org file for storing captured calendar events."
+ :type 'file
+ :group 'gnus-icalendar-org)
+
+(defcustom gnus-icalendar-org-capture-headline nil
+ "Target outline in `gnus-icalendar-org-capture-file' for storing captured events."
+ :type '(repeat string)
+ :group 'gnus-icalendar-org)
+
+(defcustom gnus-icalendar-org-template-name "used by gnus-icalendar-org"
+ "Org-mode template name."
+ :type '(string)
+ :group 'gnus-icalendar-org)
+
+(defcustom gnus-icalendar-org-template-key "#"
+ "Org-mode template hotkey."
+ :type '(string)
+ :group 'gnus-icalendar-org)
+
+(defvar gnus-icalendar-org-enabled-p nil)
+
+
+(defmethod gnus-icalendar-event:org-repeat ((event gnus-icalendar-event))
+ "Return `org-mode' timestamp repeater string for recurring EVENT.
+Return nil for non-recurring EVENT."
+ (when (gnus-icalendar-event:recurring-p event)
+ (let* ((freq-map '(("HOURLY" . "h")
+ ("DAILY" . "d")
+ ("WEEKLY" . "w")
+ ("MONTHLY" . "m")
+ ("YEARLY" . "y")))
+ (org-freq (cdr (assoc (gnus-icalendar-event:recurring-freq event) freq-map))))
+
+ (when org-freq
+ (format "+%s%s" (gnus-icalendar-event:recurring-interval event) org-freq)))))
+
+(defmethod gnus-icalendar-event:org-timestamp ((event gnus-icalendar-event))
+ "Build `org-mode' timestamp from EVENT start/end dates and recurrence info."
+ (let* ((start (gnus-icalendar-event:start-time event))
+ (end (gnus-icalendar-event:end-time event))
+ (start-date (format-time-string "%Y-%m-%d %a" start t))
+ (start-time (format-time-string "%H:%M" start t))
+ (end-date (format-time-string "%Y-%m-%d %a" end t))
+ (end-time (format-time-string "%H:%M" end t))
+ (org-repeat (gnus-icalendar-event:org-repeat event))
+ (repeat (if org-repeat (concat " " org-repeat) "")))
+
+ (if (equal start-date end-date)
+ (format "<%s %s-%s%s>" start-date start-time end-time repeat)
+ (format "<%s %s>--<%s %s>" start-date start-time end-date end-time))))
+
+;; TODO: make the template customizable
+(defmethod gnus-icalendar-event->org-entry ((event gnus-icalendar-event) reply-status)
+ "Return string with new `org-mode' entry describing EVENT."
+ (with-temp-buffer
+ (org-mode)
+ (with-slots (organizer summary description location
+ recur uid) event
+ (let* ((reply (if reply-status (capitalize (symbol-name reply-status))
+ "Not replied yet"))
+ (props `(("ICAL_EVENT" . "t")
+ ("ID" . ,uid)
+ ("DT" . ,(gnus-icalendar-event:org-timestamp event))
+ ("ORGANIZER" . ,(gnus-icalendar-event:organizer event))
+ ("LOCATION" . ,(gnus-icalendar-event:location event))
+ ("RRULE" . ,(gnus-icalendar-event:recur event))
+ ("REPLY" . ,reply))))
+
+ (insert (format "* %s (%s)\n\n" summary location))
+ (mapc (lambda (prop)
+ (org-entry-put (point) (car prop) (cdr prop)))
+ props))
+
+ (when description
+ (save-restriction
+ (narrow-to-region (point) (point))
+ (insert description)
+ (indent-region (point-min) (point-max) 2)
+ (fill-region (point-min) (point-max))))
+
+ (buffer-string))))
+
+(defun gnus-icalendar--deactivate-org-timestamp (ts)
+ (replace-regexp-in-string "[<>]"
+ (lambda (m) (pcase m ("<" "[") (">" "]")))
+ ts))
+
+(defun gnus-icalendar-find-org-event-file (event &optional org-file)
+ "Return the name of the file containing EVENT org entry.
+Return nil when not found.
+
+All org agenda files are searched for the EVENT entry. When
+the optional ORG-FILE argument is specified, only that one file
+is searched."
+ (let ((uid (gnus-icalendar-event:uid event))
+ (files (or org-file (org-agenda-files t 'ifmode))))
+ (flet
+ ((find-event-in (file)
+ (org-check-agenda-file file)
+ (with-current-buffer (find-file-noselect file)
+ (let ((event-pos (org-find-entry-with-id uid)))
+ (when (and event-pos
+ (string= (cdr (assoc "ICAL_EVENT" (org-entry-properties event-pos)))
+ "t"))
+ (throw 'found file))))))
+
+ (gnus-icalendar-find-if #'find-event-in files))))
+
+
+(defun gnus-icalendar--show-org-event (event &optional org-file)
+ (let ((file (gnus-icalendar-find-org-event-file event org-file)))
+ (when file
+ (switch-to-buffer (find-file file))
+ (goto-char (org-find-entry-with-id (gnus-icalendar-event:uid event)))
+ (org-show-entry))))
+
+
+(defun gnus-icalendar--update-org-event (event reply-status &optional org-file)
+ (let ((file (gnus-icalendar-find-org-event-file event org-file)))
+ (when file
+ (with-current-buffer (find-file-noselect file)
+ (with-slots (uid summary description organizer location recur) event
+ (let ((event-pos (org-find-entry-with-id uid)))
+ (when event-pos
+ (goto-char event-pos)
+
+ ;; update the headline, keep todo, priority and tags, if any
+ (save-excursion
+ (let* ((priority (org-entry-get (point) "PRIORITY"))
+ (headline (delq nil (list
+ (org-entry-get (point) "TODO")
+ (when priority (format "[#%s]" priority))
+ (format "%s (%s)" summary location)
+ (org-entry-get (point) "TAGS")))))
+
+ (re-search-forward "^\\*+ " (line-end-position))
+ (delete-region (point) (line-end-position))
+ (insert (mapconcat #'identity headline " "))))
+
+ ;; update props and description
+ (let ((entry-end (org-entry-end-position))
+ (entry-outline-level (org-outline-level)))
+
+ ;; delete body of the entry, leave org drawers intact
+ (save-restriction
+ (org-narrow-to-element)
+ (goto-char entry-end)
+ (re-search-backward "^[\t ]*:END:")
+ (forward-line)
+ (delete-region (point) entry-end))
+
+ ;; put new event description in the entry body
+ (when description
+ (save-restriction
+ (narrow-to-region (point) (point))
+ (insert "\n" (replace-regexp-in-string "[\n]+$" "\n" description) "\n")
+ (indent-region (point-min) (point-max) (1+ entry-outline-level))
+ (fill-region (point-min) (point-max))))
+
+ ;; update entry properties
+ (org-entry-put event-pos "DT" (gnus-icalendar-event:org-timestamp event))
+ (org-entry-put event-pos "ORGANIZER" organizer)
+ (org-entry-put event-pos "LOCATION" location)
+ (org-entry-put event-pos "RRULE" recur)
+ (when reply-status (org-entry-put event-pos "REPLY"
+ (capitalize (symbol-name reply-status))))
+ (save-buffer)))))))))
+
+
+(defun gnus-icalendar--cancel-org-event (event &optional org-file)
+ (let ((file (gnus-icalendar-find-org-event-file event org-file)))
+ (when file
+ (with-current-buffer (find-file-noselect file)
+ (let ((event-pos (org-find-entry-with-id (gnus-icalendar-event:uid event))))
+ (when event-pos
+ (let ((ts (org-entry-get event-pos "DT")))
+ (when ts
+ (org-entry-put event-pos "DT" (gnus-icalendar--deactivate-org-timestamp ts))
+ (save-buffer)))))))))
+
+
+(defun gnus-icalendar--get-org-event-reply-status (event &optional org-file)
+ (let ((file (gnus-icalendar-find-org-event-file event org-file)))
+ (when file
+ (save-excursion
+ (with-current-buffer (find-file-noselect file)
+ (let ((event-pos (org-find-entry-with-id (gnus-icalendar-event:uid event))))
+ (org-entry-get event-pos "REPLY")))))))
+
+
+(defun gnus-icalendar-insinuate-org-templates ()
+ (unless (gnus-icalendar-find-if (lambda (x) (string= (cadr x) gnus-icalendar-org-template-name))
+ org-capture-templates)
+ (setq org-capture-templates
+ (append `((,gnus-icalendar-org-template-key
+ ,gnus-icalendar-org-template-name
+ entry
+ (file+olp ,gnus-icalendar-org-capture-file ,@gnus-icalendar-org-capture-headline)
+ "%i"
+ :immediate-finish t))
+ org-capture-templates))
+
+ ;; hide the template from interactive template selection list
+ ;; (org-capture)
+ ;; NOTE: doesn't work when capturing from string
+ ;; (when (boundp 'org-capture-templates-contexts)
+ ;; (push `(,gnus-icalendar-org-template-key "" ((in-mode . "gnus-article-mode")))
+ ;; org-capture-templates-contexts))
+ ))
+
+(defun gnus-icalendar:org-event-save (event reply-status)
+ (with-temp-buffer
+ (org-capture-string (gnus-icalendar-event->org-entry event reply-status)
+ gnus-icalendar-org-template-key)))
+
+(defun gnus-icalendar-show-org-agenda (event)
+ (let* ((time-delta (time-subtract (gnus-icalendar-event:end-time event)
+ (gnus-icalendar-event:start-time event)))
+ (duration-days (1+ (/ (+ (* (car time-delta) (expt 2 16))
+ (cadr time-delta))
+ 86400))))
+
+ (org-agenda-list nil (gnus-icalendar-event:start event) duration-days)))
+
+(defmethod gnus-icalendar-event:sync-to-org ((event gnus-icalendar-event-request) reply-status)
+ (if (gnus-icalendar-find-org-event-file event)
+ (gnus-icalendar--update-org-event event reply-status)
+ (gnus-icalendar:org-event-save event reply-status)))
+
+(defmethod gnus-icalendar-event:sync-to-org ((event gnus-icalendar-event-cancel))
+ (when (gnus-icalendar-find-org-event-file event)
+ (gnus-icalendar--cancel-org-event event)))
+
+(defun gnus-icalendar-org-setup ()
+ (if (and gnus-icalendar-org-capture-file gnus-icalendar-org-capture-headline)
+ (progn
+ (gnus-icalendar-insinuate-org-templates)
+ (setq gnus-icalendar-org-enabled-p t))
+ (message "Cannot enable Calendar->Org: missing capture file, headline")))
+
+;;;
+;;; gnus-icalendar
+;;;
+
+(defgroup gnus-icalendar nil
+ "Settings for inline display of iCalendar invitations."
+ :group 'gnus-article
+ :prefix "gnus-icalendar-")
+
+(defcustom gnus-icalendar-reply-bufname "*CAL*"
+ "Buffer used for building iCalendar invitation reply."
+ :type '(string)
+ :group 'gnus-icalendar)
+
+(make-variable-buffer-local
+ (defvar gnus-icalendar-reply-status nil))
+
+(make-variable-buffer-local
+ (defvar gnus-icalendar-event nil))
+
+(make-variable-buffer-local
+ (defvar gnus-icalendar-handle nil))
+
+(defvar gnus-icalendar-identities
+ (apply #'append
+ (mapcar (lambda (x) (if (listp x) x (list x)))
+ (list user-full-name (regexp-quote user-mail-address)
+ ; NOTE: this one can be a list
+ gnus-ignored-from-addresses))))
+
+;; TODO: make the template customizable
+(defmethod gnus-icalendar-event->gnus-calendar ((event gnus-icalendar-event) &optional reply-status)
+ "Format an overview of EVENT details."
+ (flet ((format-header (x)
+ (format "%-12s%s"
+ (propertize (concat (car x) ":") 'face 'bold)
+ (cadr x))))
+
+ (with-slots (organizer summary description location recur uid method rsvp) event
+ (let ((headers `(("Summary" ,summary)
+ ("Location" ,location)
+ ("Time" ,(gnus-icalendar-event:org-timestamp event))
+ ("Organizer" ,organizer)
+ ("Method" ,method))))
+
+ (when (and (not (gnus-icalendar-event-reply-p event)) rsvp)
+ (setq headers (append headers
+ `(("Status" ,(or reply-status "Not replied yet"))))))
+
+ (concat
+ (mapconcat #'format-header headers "\n")
+ "\n\n"
+ description)))))
+
+(defmacro gnus-icalendar-with-decoded-handle (handle &rest body)
+ "Execute BODY in buffer containing the decoded contents of HANDLE."
+ (let ((charset (make-symbol "charset")))
+ `(let ((,charset (cdr (assoc 'charset (mm-handle-type ,handle)))))
+ (with-temp-buffer
+ (mm-insert-part ,handle)
+ (when (string= ,charset "utf-8")
+ (mm-decode-coding-region (point-min) (point-max) 'utf-8))
+
+ ,@body))))
+
+
+(defun gnus-icalendar-event-from-handle (handle &optional attendee-name-or-email)
+ (gnus-icalendar-with-decoded-handle handle
+ (gnus-icalendar-event-from-buffer (current-buffer) attendee-name-or-email)))
+
+(defun gnus-icalendar-insert-button (text callback data)
+ ;; FIXME: the gnus-mime-button-map keymap does not make sense for this kind
+ ;; of button.
+ (let ((start (point)))
+ (gnus-add-text-properties
+ start
+ (progn
+ (insert "[ " text " ]")
+ (point))
+ `(gnus-callback
+ ,callback
+ keymap ,gnus-mime-button-map
+ face ,gnus-article-button-face
+ gnus-data ,data))
+ (widget-convert-button 'link start (point)
+ :action 'gnus-widget-press-button
+ :button-keymap gnus-widget-button-keymap)))
+
+(defun gnus-icalendar-send-buffer-by-mail (buffer-name subject)
+ (let ((message-signature nil))
+ (with-current-buffer gnus-summary-buffer
+ (gnus-summary-reply)
+ (message-goto-body)
+ (mml-insert-multipart "alternative")
+ (mml-insert-empty-tag 'part 'type "text/plain")
+ (mml-attach-buffer buffer-name "text/calendar; method=REPLY; charset=UTF-8")
+ (message-goto-subject)
+ (delete-region (line-beginning-position) (line-end-position))
+ (insert "Subject: " subject)
+ (message-send-and-exit))))
+
+(defun gnus-icalendar-reply (data)
+ (let* ((handle (car data))
+ (status (cadr data))
+ (event (caddr data))
+ (reply (gnus-icalendar-with-decoded-handle handle
+ (gnus-icalendar-event-reply-from-buffer
+ (current-buffer) status gnus-icalendar-identities))))
+
+ (when reply
+ (flet ((fold-icalendar-buffer ()
+ (goto-char (point-min))
+ (while (re-search-forward "^\\(.\\{72\\}\\)\\(.+\\)$" nil t)
+ (replace-match "\\1\n \\2")
+ (goto-char (line-beginning-position)))))
+ (let ((subject (concat (capitalize (symbol-name status))
+ ": " (gnus-icalendar-event:summary event))))
+
+ (with-current-buffer (get-buffer-create gnus-icalendar-reply-bufname)
+ (delete-region (point-min) (point-max))
+ (insert reply)
+ (fold-icalendar-buffer)
+ (gnus-icalendar-send-buffer-by-mail (buffer-name) subject))
+
+ ;; Back in article buffer
+ (setq-local gnus-icalendar-reply-status status)
+ (when gnus-icalendar-org-enabled-p
+ (gnus-icalendar--update-org-event event status)
+ ;; refresh article buffer to update the reply status
+ (with-current-buffer gnus-summary-buffer
+ (gnus-summary-show-article))))))))
+
+(defun gnus-icalendar-sync-event-to-org (event)
+ (gnus-icalendar-event:sync-to-org event gnus-icalendar-reply-status))
+
+(defmethod gnus-icalendar-event:inline-reply-buttons ((event gnus-icalendar-event) handle)
+ (when (gnus-icalendar-event:rsvp event)
+ `(("Accept" gnus-icalendar-reply (,handle accepted ,event))
+ ("Tentative" gnus-icalendar-reply (,handle tentative ,event))
+ ("Decline" gnus-icalendar-reply (,handle declined ,event)))))
+
+(defmethod gnus-icalendar-event:inline-reply-buttons ((event gnus-icalendar-event-reply) handle)
+ "No buttons for REPLY events."
+ nil)
+
+(defmethod gnus-icalendar-event:inline-reply-status ((event gnus-icalendar-event))
+ (or (when gnus-icalendar-org-enabled-p
+ (gnus-icalendar--get-org-event-reply-status event))
+ "Not replied yet"))
+
+(defmethod gnus-icalendar-event:inline-reply-status ((event gnus-icalendar-event-reply))
+ "No reply status for REPLY events."
+ nil)
+
+
+(defmethod gnus-icalendar-event:inline-org-buttons ((event gnus-icalendar-event))
+ (let* ((org-entry-exists-p (gnus-icalendar-find-org-event-file event))
+ (export-button-text (if org-entry-exists-p "Update Org Entry" "Export to Org")))
+
+ (delq nil (list
+ `("Show Agenda" gnus-icalendar-show-org-agenda ,event)
+ (when (gnus-icalendar-event-request-p event)
+ `(,export-button-text gnus-icalendar-sync-event-to-org ,event))
+ (when org-entry-exists-p
+ `("Show Org Entry" gnus-icalendar--show-org-event ,event))))))
+
+(defun gnus-icalendar-mm-inline (handle)
+ (let ((event (gnus-icalendar-event-from-handle handle gnus-icalendar-identities)))
+
+ (setq gnus-icalendar-reply-status nil)
+
+ (when event
+ (flet ((insert-button-group (buttons)
+ (when buttons
+ (mapc (lambda (x)
+ (apply 'gnus-icalendar-insert-button x)
+ (insert " "))
+ buttons)
+ (insert "\n\n"))))
+
+ (insert-button-group
+ (gnus-icalendar-event:inline-reply-buttons event handle))
+
+ (when gnus-icalendar-org-enabled-p
+ (insert-button-group (gnus-icalendar-event:inline-org-buttons event)))
+
+ (setq gnus-icalendar-event event
+ gnus-icalendar-handle handle)
+
+ (insert (gnus-icalendar-event->gnus-calendar
+ event
+ (gnus-icalendar-event:inline-reply-status event)))))))
+
+(defun gnus-icalendar-save-part (handle)
+ (let (event)
+ (when (and (equal (car (mm-handle-type handle)) "text/calendar")
+ (setq event (gnus-icalendar-event-from-handle handle gnus-icalendar-identities)))
+
+ (gnus-icalendar-event:sync-to-org event))))
+
+
+(defun gnus-icalendar-save-event ()
+ "Save the Calendar event in the text/calendar part under point."
+ (interactive)
+ (gnus-article-check-buffer)
+ (let ((data (get-text-property (point) 'gnus-data)))
+ (when data
+ (gnus-icalendar-save-part data))))
+
+(defun gnus-icalendar-reply-accept ()
+ "Accept invitation in the current article."
+ (interactive)
+ (with-current-buffer gnus-article-buffer
+ (gnus-icalendar-reply (list gnus-icalendar-handle 'accepted gnus-icalendar-event))
+ (setq-local gnus-icalendar-reply-status 'accepted)))
+
+(defun gnus-icalendar-reply-tentative ()
+ "Send tentative response to invitation in the current article."
+ (interactive)
+ (with-current-buffer gnus-article-buffer
+ (gnus-icalendar-reply (list gnus-icalendar-handle 'tentative gnus-icalendar-event))
+ (setq-local gnus-icalendar-reply-status 'tentative)))
+
+(defun gnus-icalendar-reply-decline ()
+ "Decline invitation in the current article."
+ (interactive)
+ (with-current-buffer gnus-article-buffer
+ (gnus-icalendar-reply (list gnus-icalendar-handle 'declined gnus-icalendar-event))
+ (setq-local gnus-icalendar-reply-status 'declined)))
+
+(defun gnus-icalendar-event-export ()
+ "Export calendar event to `org-mode', or update existing agenda entry."
+ (interactive)
+ (with-current-buffer gnus-article-buffer
+ (gnus-icalendar-sync-event-to-org gnus-icalendar-event))
+ ;; refresh article buffer in case the reply had been sent before initial org
+ ;; export
+ (with-current-buffer gnus-summary-buffer
+ (gnus-summary-show-article)))
+
+(defun gnus-icalendar-event-show ()
+ "Display `org-mode' agenda entry related to the calendar event."
+ (interactive)
+ (gnus-icalendar--show-org-event
+ (with-current-buffer gnus-article-buffer
+ gnus-icalendar-event)))
+
+(defun gnus-icalendar-event-check-agenda ()
+ "Display `org-mode' agenda for days between event start and end dates."
+ (interactive)
+ (gnus-icalendar-show-org-agenda
+ (with-current-buffer gnus-article-buffer gnus-icalendar-event)))
+
+(defun gnus-icalendar-setup ()
+ (add-to-list 'mm-inlined-types "text/calendar")
+ (add-to-list 'mm-automatic-display "text/calendar")
+ (add-to-list 'mm-inline-media-tests '("text/calendar" gnus-icalendar-mm-inline identity))
+
+ (gnus-define-keys (gnus-summary-calendar-map "i" gnus-summary-mode-map)
+ "a" gnus-icalendar-reply-accept
+ "t" gnus-icalendar-reply-tentative
+ "d" gnus-icalendar-reply-decline
+ "c" gnus-icalendar-event-check-agenda
+ "e" gnus-icalendar-event-export
+ "s" gnus-icalendar-event-show)
+
+ (require 'gnus-art)
+ (add-to-list 'gnus-mime-action-alist
+ (cons "save calendar event" 'gnus-icalendar-save-event)
+ t))
+
+(provide 'gnus-icalendar)
+
+;;; gnus-icalendar.el ends here
diff --git a/lisp/gnus/gnus-int.el b/lisp/gnus/gnus-int.el
index 2378b598eeb..6aa874f0347 100644
--- a/lisp/gnus/gnus-int.el
+++ b/lisp/gnus/gnus-int.el
@@ -582,8 +582,8 @@ This is the string that Gnus uses to identify the group."
(gnus-group-method group)))
(defun gnus-warp-to-article ()
- "Warps from an article in a virtual group to the article in its
-real group. Does nothing on a real group."
+ "Jump from an article in a virtual group to the article in its real group.
+Does nothing in a real group."
(interactive)
(when (gnus-virtual-group-p gnus-newsgroup-name)
(let ((gnus-command-method
diff --git a/lisp/gnus/gnus-score.el b/lisp/gnus/gnus-score.el
index da5c31325bd..5f91246761e 100644
--- a/lisp/gnus/gnus-score.el
+++ b/lisp/gnus/gnus-score.el
@@ -1071,10 +1071,15 @@ EXTRA is the possible non-standard header."
(push (cons article n) gnus-newsgroup-scored)))
(gnus-summary-update-line)))
-(defun gnus-summary-current-score ()
- "Return the score of the current article."
- (interactive)
- (gnus-message 1 "%s" (gnus-summary-article-score)))
+(defun gnus-summary-current-score (arg)
+ "Return the score of the current article.
+ With prefix ARG, return the total score of the current (sub)thread."
+ (interactive "P")
+ (gnus-message 1 "%s" (if arg
+ (gnus-thread-total-score
+ (gnus-id-to-thread
+ (mail-header-id (gnus-summary-article-header))))
+ (gnus-summary-article-score))))
(defun gnus-score-change-score-file (file)
"Change current score alist."
diff --git a/lisp/gnus/gnus-start.el b/lisp/gnus/gnus-start.el
index 05cf290cac9..9f3f469ad43 100644
--- a/lisp/gnus/gnus-start.el
+++ b/lisp/gnus/gnus-start.el
@@ -944,7 +944,8 @@ If REGEXP is given, lines that match it will be deleted."
(when (and gnus-dribble-buffer
(buffer-name gnus-dribble-buffer))
(with-current-buffer gnus-dribble-buffer
- (save-buffer))))
+ (when (> (buffer-size) 0)
+ (save-buffer)))))
(defun gnus-dribble-clear ()
(when (gnus-buffer-exists-p gnus-dribble-buffer)
@@ -1807,6 +1808,9 @@ backend check whether the group actually exists."
(or (not (gnus-agent-method-p method))
(gnus-online method)))
(gnus-finish-retrieve-group-infos method infos early-data)
+ ;; We may have altered the data now, so mark the dribble buffer
+ ;; as dirty so that it gets saved.
+ (gnus-dribble-touch)
(gnus-agent-save-active method))
;; Most backends have -retrieve-groups.
((gnus-check-backend-function 'retrieve-groups (car method))
diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el
index a7269baee74..94f4e703180 100644
--- a/lisp/gnus/gnus-sum.el
+++ b/lisp/gnus/gnus-sum.el
@@ -2359,7 +2359,8 @@ increase the score of each group you read."
["Mark above" gnus-summary-mark-above t]
["Tick above" gnus-summary-tick-above t]
["Clear above" gnus-summary-clear-above t])
- ["Current score" gnus-summary-current-score t]
+ ["Current article score" gnus-summary-current-score t]
+ ["Current thread score" (gnus-summary-current-score 'total) t]
["Set score" gnus-summary-set-score t]
["Switch current score file..." gnus-score-change-score-file t]
["Set mark below..." gnus-score-set-mark-below t]
diff --git a/lisp/gnus/gnus-util.el b/lisp/gnus/gnus-util.el
index 0f0e9675c71..1d2ab2da248 100644
--- a/lisp/gnus/gnus-util.el
+++ b/lisp/gnus/gnus-util.el
@@ -1558,12 +1558,15 @@ SPEC is a predicate specifier that contains stuff like `or', `and',
"Call standard `completing-read-function'."
(let ((completion-styles gnus-completion-styles))
(completing-read prompt
- ;; Old XEmacs (at least 21.4) expect an alist,
- ;; in which the car of each element is a string,
- ;; for collection.
- (mapcar (lambda (elem)
- (list (format "%s" (or (car-safe elem) elem))))
- collection)
+ (if (featurep 'xemacs)
+ ;; Old XEmacs (at least 21.4) expect an alist,
+ ;; in which the car of each element is a string,
+ ;; for collection.
+ (mapcar
+ (lambda (elem)
+ (list (format "%s" (or (car-safe elem) elem))))
+ collection)
+ collection)
nil require-match initial-input history def)))
(autoload 'ido-completing-read "ido")
diff --git a/lisp/gnus/gnus-uu.el b/lisp/gnus/gnus-uu.el
index c50dcde0034..16ed4f17801 100644
--- a/lisp/gnus/gnus-uu.el
+++ b/lisp/gnus/gnus-uu.el
@@ -640,7 +640,7 @@ When called interactively, prompt for REGEXP."
(let ((level (gnus-summary-thread-level)))
(while (and (gnus-summary-set-process-mark
(gnus-summary-article-number))
- (zerop (gnus-summary-next-subject 1 nil t))
+ (zerop (forward-line 1))
(> (gnus-summary-thread-level) level)))))
(gnus-summary-position-point))
@@ -650,7 +650,7 @@ When called interactively, prompt for REGEXP."
(let ((level (gnus-summary-thread-level)))
(while (and (gnus-summary-remove-process-mark
(gnus-summary-article-number))
- (zerop (gnus-summary-next-subject 1))
+ (zerop (forward-line 1))
(> (gnus-summary-thread-level) level))))
(gnus-summary-position-point))
diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el
index b35eb9dca12..d6d6b3f8bed 100644
--- a/lisp/gnus/message.el
+++ b/lisp/gnus/message.el
@@ -264,7 +264,7 @@ This is a list of regexps and regexp matches."
:type 'sexp)
(defcustom message-ignored-news-headers
- "^NNTP-Posting-Host:\\|^Xref:\\|^[BGF]cc:\\|^Resent-Fcc:\\|^X-Draft-From:\\|^X-Gnus-Agent-Meta-Information:\\|^X-Message-SMTP-Method:"
+ "^NNTP-Posting-Host:\\|^Xref:\\|^[BGF]cc:\\|^Resent-Fcc:\\|^X-Draft-From:\\|^X-Gnus-Agent-Meta-Information:\\|^X-Message-SMTP-Method:\\|^X-Gnus-Delayed:"
"*Regexp of headers to be removed unconditionally before posting."
:group 'message-news
:group 'message-headers
diff --git a/lisp/gnus/mm-decode.el b/lisp/gnus/mm-decode.el
index 98be1c5def2..7274708f014 100644
--- a/lisp/gnus/mm-decode.el
+++ b/lisp/gnus/mm-decode.el
@@ -63,6 +63,18 @@
:group 'news
:group 'multimedia)
+(defface mm-command-output
+ '((((class color)
+ (background dark))
+ (:foreground "ForestGreen"))
+ (((class color)
+ (background light))
+ (:foreground "red3"))
+ (t
+ (:italic t)))
+ "Face used for displaying output from commands."
+ :group 'mime-display)
+
;;; Convenience macros.
(defmacro mm-handle-buffer (handle)
@@ -983,9 +995,12 @@ external if displayed external."
(let ((buffer-read-only nil)
(point (point)))
(forward-line 2)
- (mm-insert-inline
- handle (with-current-buffer buffer
- (buffer-string)))
+ (let ((start (point)))
+ (mm-insert-inline
+ handle (with-current-buffer buffer
+ (buffer-string)))
+ (put-text-property start (point)
+ 'face 'mm-command-output))
(goto-char point))))
(when (buffer-live-p buffer)
(kill-buffer buffer)))
diff --git a/lisp/gnus/mml2015.el b/lisp/gnus/mml2015.el
index 2c2187a5f8d..3efa5c23bb3 100644
--- a/lisp/gnus/mml2015.el
+++ b/lisp/gnus/mml2015.el
@@ -885,17 +885,19 @@ If set, it overrides the setting of `mml2015-sign-with-sender'."
(defun mml2015-epg-key-image-to-string (key-id)
"Return a string with the image of a key, if any"
- (let* ((result "")
- (key-image (mml2015-epg-key-image key-id)))
- (when key-image
- (setq result " ")
- (put-text-property
- 1 2 'display
- (gnus-rescale-image key-image
- (cons mml2015-maximum-key-image-dimension
- mml2015-maximum-key-image-dimension))
- result))
- result))
+ (let ((key-image (mml2015-epg-key-image key-id)))
+ (if (not key-image)
+ ""
+ (condition-case error
+ (let ((result " "))
+ (put-text-property
+ 1 2 'display
+ (gnus-rescale-image key-image
+ (cons mml2015-maximum-key-image-dimension
+ mml2015-maximum-key-image-dimension))
+ result)
+ result)
+ (error "")))))
(defun mml2015-epg-signature-to-string (signature)
(concat (epg-signature-to-string signature)
diff --git a/lisp/gnus/nnmbox.el b/lisp/gnus/nnmbox.el
index 3228eacdd0a..c605541e7f1 100644
--- a/lisp/gnus/nnmbox.el
+++ b/lisp/gnus/nnmbox.el
@@ -148,28 +148,29 @@
(deffoo nnmbox-request-article (article &optional newsgroup server buffer)
(nnmbox-possibly-change-newsgroup newsgroup server)
(with-current-buffer nnmbox-mbox-buffer
- (when (nnmbox-find-article article)
- (let (start stop)
- (re-search-backward (concat "^" message-unix-mail-delimiter) nil t)
- (setq start (point))
- (forward-line 1)
- (setq stop (if (re-search-forward (concat "^"
- message-unix-mail-delimiter)
- nil 'move)
- (match-beginning 0)
- (point)))
- (let ((nntp-server-buffer (or buffer nntp-server-buffer)))
- (set-buffer nntp-server-buffer)
- (erase-buffer)
- (insert-buffer-substring nnmbox-mbox-buffer start stop)
- (goto-char (point-min))
- (while (looking-at "From ")
- (delete-char 5)
- (insert "X-From-Line: ")
- (forward-line 1))
- (if (numberp article)
- (cons nnmbox-current-group article)
- (nnmbox-article-group-number nil)))))))
+ (save-excursion
+ (when (nnmbox-find-article article)
+ (let (start stop)
+ (re-search-backward (concat "^" message-unix-mail-delimiter) nil t)
+ (setq start (point))
+ (forward-line 1)
+ (setq stop (if (re-search-forward (concat "^"
+ message-unix-mail-delimiter)
+ nil 'move)
+ (match-beginning 0)
+ (point)))
+ (let ((nntp-server-buffer (or buffer nntp-server-buffer)))
+ (set-buffer nntp-server-buffer)
+ (erase-buffer)
+ (insert-buffer-substring nnmbox-mbox-buffer start stop)
+ (goto-char (point-min))
+ (while (looking-at "From ")
+ (delete-char 5)
+ (insert "X-From-Line: ")
+ (forward-line 1))
+ (if (numberp article)
+ (cons nnmbox-current-group article)
+ (nnmbox-article-group-number nil))))))))
(deffoo nnmbox-request-group (group &optional server dont-check info)
(nnmbox-possibly-change-newsgroup nil server)
@@ -255,14 +256,14 @@
(if (setq is-old
(nnmail-expired-article-p
newsgroup
- (buffer-substring
- (point) (progn (end-of-line) (point))) force))
+ (buffer-substring (point) (line-end-position))
+ force))
(progn
(unless (eq nnmail-expiry-target 'delete)
(with-temp-buffer
(nnmbox-request-article (car articles)
- newsgroup server
- (current-buffer))
+ newsgroup server
+ (current-buffer))
(let ((nnml-current-directory nil))
(nnmail-expiry-target-group
nnmail-expiry-target newsgroup)))
diff --git a/lisp/gnus/nnrss.el b/lisp/gnus/nnrss.el
index b1e5c4cc9fd..80bb7c4f7df 100644
--- a/lisp/gnus/nnrss.el
+++ b/lisp/gnus/nnrss.el
@@ -933,30 +933,30 @@ whether they are `offsite' or `onsite'."
rss-offsite-in rdf-offsite-in xml-offsite-in)))
(defun nnrss-discover-feed (url)
- "Given a page, find an RSS feed using Mark Pilgrim's
-`ultra-liberal rss locator'."
-
+ "Given a page, find an RSS feed.
+Use Mark Pilgrim's `ultra-liberal rss locator'."
(let ((parsed-page (nnrss-fetch url)))
-
-;; 1. if this url is the rss, use it.
+ ;; 1. if this url is the rss, use it.
(if (nnrss-rss-p parsed-page)
(let ((rss-ns (nnrss-get-namespace-prefix parsed-page "http://purl.org/rss/1.0/")))
(nnrss-rss-title-description rss-ns parsed-page url))
-;; 2. look for the <link rel="alternate"
-;; type="application/rss+xml" and use that if it is there.
+ ;; 2. look for the <link rel="alternate"
+ ;; type="application/rss+xml" and use that if it is there.
(let ((links (nnrss-get-rsslinks parsed-page)))
(if links
(let* ((xml (nnrss-fetch
(cdr (assoc 'href (cadar links)))))
- (rss-ns (nnrss-get-namespace-prefix xml "http://purl.org/rss/1.0/")))
- (nnrss-rss-title-description rss-ns xml (cdr (assoc 'href (cadar links)))))
-
-;; 3. look for links on the site in the following order:
-;; - onsite links ending in .rss, .rdf, or .xml
-;; - onsite links containing any of the above
-;; - offsite links ending in .rss, .rdf, or .xml
-;; - offsite links containing any of the above
+ (rss-ns (nnrss-get-namespace-prefix
+ xml "http://purl.org/rss/1.0/")))
+ (nnrss-rss-title-description
+ rss-ns xml (cdr (assoc 'href (cadar links)))))
+
+ ;; 3. look for links on the site in the following order:
+ ;; - onsite links ending in .rss, .rdf, or .xml
+ ;; - onsite links containing any of the above
+ ;; - offsite links ending in .rss, .rdf, or .xml
+ ;; - offsite links containing any of the above
(let* ((base-uri (progn (string-match ".*://[^/]+/?" url)
(match-string 0 url)))
(hrefs (nnrss-order-hrefs
@@ -969,9 +969,9 @@ whether they are `offsite' or `onsite'."
(setq rss-link (nnrss-rss-title-description
rss-ns href-data (car hrefs))))
(setq hrefs (cdr hrefs)))))
- (if rss-link rss-link
-
-;; 4. check syndic8
+ (if rss-link
+ rss-link
+ ;; 4. check syndic8
(nnrss-find-rss-via-syndic8 url))))))))
(defun nnrss-find-rss-via-syndic8 (url)
diff --git a/lisp/gnus/rfc2047.el b/lisp/gnus/rfc2047.el
index a9498d46e79..ebf597423b8 100644
--- a/lisp/gnus/rfc2047.el
+++ b/lisp/gnus/rfc2047.el
@@ -235,85 +235,96 @@ Should be called narrowed to the head of the message."
(interactive "*")
(save-excursion
(goto-char (point-min))
- (let (alist elem method)
+ (let (alist elem method charsets)
(while (not (eobp))
(save-restriction
(rfc2047-narrow-to-field)
(setq method nil
- alist rfc2047-header-encoding-alist)
- (while (setq elem (pop alist))
- (when (or (and (stringp (car elem))
- (looking-at (car elem)))
- (eq (car elem) t))
- (setq alist nil
- method (cdr elem))))
- (if (not (rfc2047-encodable-p))
- (prog2
- (when (eq method 'address-mime)
- (rfc2047-quote-special-characters-in-quoted-strings))
- (if (and (eq (mm-body-7-or-8) '8bit)
- (mm-multibyte-p)
- (mm-coding-system-p
- (car message-posting-charset)))
- ;; 8 bit must be decoded.
- (mm-encode-coding-region
- (point-min) (point-max)
- (mm-charset-to-coding-system
- (car message-posting-charset))))
- ;; No encoding necessary, but folding is nice
- (when nil
- (rfc2047-fold-region
- (save-excursion
- (goto-char (point-min))
- (skip-chars-forward "^:")
- (when (looking-at ": ")
- (forward-char 2))
- (point))
- (point-max))))
- ;; We found something that may perhaps be encoded.
- (re-search-forward "^[^:]+: *" nil t)
- (cond
- ((eq method 'address-mime)
- (rfc2047-encode-region (point) (point-max)))
- ((eq method 'mime)
- (let ((rfc2047-encoding-type 'mime))
- (rfc2047-encode-region (point) (point-max))))
- ((eq method 'default)
- (if (and (featurep 'mule)
- (if (boundp 'enable-multibyte-characters)
- (default-value 'enable-multibyte-characters))
- mail-parse-charset)
- (mm-encode-coding-region (point) (point-max)
- mail-parse-charset)))
- ;; We get this when CC'ing messages to newsgroups with
- ;; 8-bit names. The group name mail copy just got
- ;; unconditionally encoded. Previously, it would ask
- ;; whether to encode, which was quite confusing for the
- ;; user. If the new behavior is wrong, tell me. I have
- ;; left the old code commented out below.
- ;; -- Per Abrahamsen <abraham@dina.kvl.dk> Date: 2001-10-07.
- ;; Modified by Dave Love, with the commented-out code changed
- ;; in accordance with changes elsewhere.
- ((null method)
- (rfc2047-encode-region (point) (point-max)))
-;;; ((null method)
-;;; (if (or (message-options-get
-;;; 'rfc2047-encode-message-header-encode-any)
-;;; (message-options-set
-;;; 'rfc2047-encode-message-header-encode-any
-;;; (y-or-n-p
-;;; "Some texts are not encoded. Encode anyway?")))
-;;; (rfc2047-encode-region (point-min) (point-max))
-;;; (error "Cannot send unencoded text")))
- ((mm-coding-system-p method)
- (if (or (and (featurep 'mule)
- (if (boundp 'enable-multibyte-characters)
- (default-value 'enable-multibyte-characters)))
- (featurep 'file-coding))
- (mm-encode-coding-region (point) (point-max) method)))
- ;; Hm.
- (t)))
- (goto-char (point-max)))))))
+ alist rfc2047-header-encoding-alist
+ charsets (mm-find-mime-charset-region (point-min) (point-max)))
+ ;; M$ Outlook boycotts decoding of a header if it consists
+ ;; of two or more encoded words and those charsets differ;
+ ;; it seems to decode all words in a header from a charset
+ ;; found first in the header. So, we unify the charsets into
+ ;; a single one used for encoding the whole text in a header.
+ (let ((mm-coding-system-priorities
+ (if (= (length charsets) 1)
+ (cons (mm-charset-to-coding-system (car charsets))
+ mm-coding-system-priorities)
+ mm-coding-system-priorities)))
+ (while (setq elem (pop alist))
+ (when (or (and (stringp (car elem))
+ (looking-at (car elem)))
+ (eq (car elem) t))
+ (setq alist nil
+ method (cdr elem))))
+ (if (not (rfc2047-encodable-p))
+ (prog2
+ (when (eq method 'address-mime)
+ (rfc2047-quote-special-characters-in-quoted-strings))
+ (if (and (eq (mm-body-7-or-8) '8bit)
+ (mm-multibyte-p)
+ (mm-coding-system-p
+ (car message-posting-charset)))
+ ;; 8 bit must be decoded.
+ (mm-encode-coding-region
+ (point-min) (point-max)
+ (mm-charset-to-coding-system
+ (car message-posting-charset))))
+ ;; No encoding necessary, but folding is nice
+ (when nil
+ (rfc2047-fold-region
+ (save-excursion
+ (goto-char (point-min))
+ (skip-chars-forward "^:")
+ (when (looking-at ": ")
+ (forward-char 2))
+ (point))
+ (point-max))))
+ ;; We found something that may perhaps be encoded.
+ (re-search-forward "^[^:]+: *" nil t)
+ (cond
+ ((eq method 'address-mime)
+ (rfc2047-encode-region (point) (point-max)))
+ ((eq method 'mime)
+ (let ((rfc2047-encoding-type 'mime))
+ (rfc2047-encode-region (point) (point-max))))
+ ((eq method 'default)
+ (if (and (featurep 'mule)
+ (if (boundp 'enable-multibyte-characters)
+ (default-value 'enable-multibyte-characters))
+ mail-parse-charset)
+ (mm-encode-coding-region (point) (point-max)
+ mail-parse-charset)))
+ ;; We get this when CC'ing messages to newsgroups with
+ ;; 8-bit names. The group name mail copy just got
+ ;; unconditionally encoded. Previously, it would ask
+ ;; whether to encode, which was quite confusing for the
+ ;; user. If the new behavior is wrong, tell me. I have
+ ;; left the old code commented out below.
+ ;; -- Per Abrahamsen <abraham@dina.kvl.dk> Date: 2001-10-07.
+ ;; Modified by Dave Love, with the commented-out code changed
+ ;; in accordance with changes elsewhere.
+ ((null method)
+ (rfc2047-encode-region (point) (point-max)))
+;;; ((null method)
+;;; (if (or (message-options-get
+;;; 'rfc2047-encode-message-header-encode-any)
+;;; (message-options-set
+;;; 'rfc2047-encode-message-header-encode-any
+;;; (y-or-n-p
+;;; "Some texts are not encoded. Encode anyway?")))
+;;; (rfc2047-encode-region (point-min) (point-max))
+;;; (error "Cannot send unencoded text")))
+ ((mm-coding-system-p method)
+ (if (or (and (featurep 'mule)
+ (if (boundp 'enable-multibyte-characters)
+ (default-value 'enable-multibyte-characters)))
+ (featurep 'file-coding))
+ (mm-encode-coding-region (point) (point-max) method)))
+ ;; Hm.
+ (t)))
+ (goto-char (point-max))))))))
;; Fixme: This, and the require below may not be the Right Thing, but
;; should be safe just before release. -- fx 2001-02-08
diff --git a/lisp/ibuf-ext.el b/lisp/ibuf-ext.el
index de36c6c86ce..1ba0b0f0779 100644
--- a/lisp/ibuf-ext.el
+++ b/lisp/ibuf-ext.el
@@ -1050,7 +1050,7 @@ currently used by buffers."
"Toggle current view to buffers with filename matching QUALIFIER."
(:description "filename"
:reader (read-from-minibuffer "Filter by filename (regexp): "))
- (ibuffer-awhen (buffer-local-value 'buffer-file-name buf)
+ (ibuffer-awhen (with-current-buffer buf (ibuffer-buffer-file-name))
(string-match qualifier it)))
;;;###autoload (autoload 'ibuffer-filter-by-size-gt "ibuf-ext")
diff --git a/lisp/ibuffer.el b/lisp/ibuffer.el
index a4f18201a3f..09d7c143346 100644
--- a/lisp/ibuffer.el
+++ b/lisp/ibuffer.el
@@ -2631,29 +2631,7 @@ will be inserted before the group at point."
;;; Start of automatically extracted autoloads.
-;;;### (autoloads (ibuffer-do-occur ibuffer-mark-dired-buffers ibuffer-mark-read-only-buffers
-;;;;;; ibuffer-mark-special-buffers ibuffer-mark-old-buffers ibuffer-mark-compressed-file-buffers
-;;;;;; ibuffer-mark-help-buffers ibuffer-mark-dissociated-buffers
-;;;;;; ibuffer-mark-unsaved-buffers ibuffer-mark-modified-buffers
-;;;;;; ibuffer-mark-by-mode ibuffer-mark-by-file-name-regexp ibuffer-mark-by-mode-regexp
-;;;;;; ibuffer-mark-by-name-regexp ibuffer-copy-filename-as-kill
-;;;;;; ibuffer-diff-with-file ibuffer-jump-to-buffer ibuffer-do-kill-lines
-;;;;;; ibuffer-backwards-next-marked ibuffer-forward-next-marked
-;;;;;; ibuffer-add-to-tmp-show ibuffer-add-to-tmp-hide ibuffer-bs-show
-;;;;;; ibuffer-invert-sorting ibuffer-toggle-sorting-mode ibuffer-switch-to-saved-filters
-;;;;;; ibuffer-add-saved-filters ibuffer-delete-saved-filters ibuffer-save-filters
-;;;;;; ibuffer-or-filter ibuffer-negate-filter ibuffer-exchange-filters
-;;;;;; ibuffer-decompose-filter ibuffer-pop-filter ibuffer-filter-disable
-;;;;;; ibuffer-switch-to-saved-filter-groups ibuffer-delete-saved-filter-groups
-;;;;;; ibuffer-save-filter-groups ibuffer-yank-filter-group ibuffer-yank
-;;;;;; ibuffer-kill-line ibuffer-kill-filter-group ibuffer-jump-to-filter-group
-;;;;;; ibuffer-clear-filter-groups ibuffer-decompose-filter-group
-;;;;;; ibuffer-pop-filter-group ibuffer-set-filter-groups-by-mode
-;;;;;; ibuffer-filters-to-filter-group ibuffer-included-in-filters-p
-;;;;;; ibuffer-backward-filter-group ibuffer-forward-filter-group
-;;;;;; ibuffer-toggle-filter-group ibuffer-mouse-toggle-filter-group
-;;;;;; ibuffer-interactive-filter-by-mode ibuffer-mouse-filter-by-mode
-;;;;;; ibuffer-auto-mode) "ibuf-ext" "ibuf-ext.el" "2c628e6cde385119c5f7b43cc1efe1a1")
+;;;### (autoloads nil "ibuf-ext" "ibuf-ext.el" "d06b2735a74954e0c6922a811de7608c")
;;; Generated autoloads from ibuf-ext.el
(autoload 'ibuffer-auto-mode "ibuf-ext" "\
diff --git a/lisp/mh-e/mh-e.el b/lisp/mh-e/mh-e.el
index 303d817dede..752e2c5e9c6 100644
--- a/lisp/mh-e/mh-e.el
+++ b/lisp/mh-e/mh-e.el
@@ -1019,6 +1019,7 @@ windows in the frame are removed."
(when delete-other-windows-flag
(delete-other-windows)))
+;; FIXME: Maybe out of date? --xfq
(if (boundp 'customize-package-emacs-version-alist)
(add-to-list 'customize-package-emacs-version-alist
'(MH-E ("6.0" . "22.1") ("6.1" . "22.1") ("7.0" . "22.1")
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index 8bcf3afae05..e07d28a54d0 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -568,6 +568,17 @@ for use at QPOS."
(cl-assert (string-prefix-p prefix completion 'ignore-case) t)
(let* ((new (substring completion (length prefix)))
(qnew (funcall qfun new))
+ (qprefix
+ (if (not completion-ignore-case)
+ qprefix
+ ;; Make qprefix inherit the case from `completion'.
+ (let* ((rest (substring completion
+ 0 (length prefix)))
+ (qrest (funcall qfun rest)))
+ (if (completion--string-equal-p qprefix qrest)
+ (propertize qrest 'face
+ 'completions-common-part)
+ qprefix))))
(qcompletion (concat qprefix qnew)))
;; FIXME: Similarly here, Cygwin's mapping trips this
;; assertion.
diff --git a/lisp/net/browse-url.el b/lisp/net/browse-url.el
index feae435c779..70173dbc0b3 100644
--- a/lisp/net/browse-url.el
+++ b/lisp/net/browse-url.el
@@ -816,8 +816,8 @@ first, if that exists."
;; When connected to various displays, be careful to use the display of
;; the currently selected frame, rather than the original start display,
;; which may not even exist any more.
- (if (stringp (frame-parameter (selected-frame) 'display))
- (setenv "DISPLAY" (frame-parameter (selected-frame) 'display)))
+ (if (stringp (frame-parameter nil 'display))
+ (setenv "DISPLAY" (frame-parameter nil 'display)))
(if (and (consp function)
(not (functionp function)))
;; The `function' can be an alist; look down it for first match
diff --git a/lisp/net/eww.el b/lisp/net/eww.el
index d65932ae7c9..70c11c3201f 100644
--- a/lisp/net/eww.el
+++ b/lisp/net/eww.el
@@ -309,7 +309,7 @@ word(s) will be searched for via `eww-search-prefix'."
(goto-char (point-min))))
(defun eww-setup-buffer ()
- (pop-to-buffer (get-buffer-create "*eww*"))
+ (switch-to-buffer (get-buffer-create "*eww*"))
(let ((inhibit-read-only t))
(remove-overlays)
(erase-buffer))
diff --git a/lisp/net/network-stream.el b/lisp/net/network-stream.el
index fd21997ba28..ab7d02cc802 100644
--- a/lisp/net/network-stream.el
+++ b/lisp/net/network-stream.el
@@ -128,6 +128,9 @@ values:
:use-starttls-if-possible is a boolean that says to do opportunistic
STARTTLS upgrades even if Emacs doesn't have built-in TLS functionality.
+:nogreeting is a boolean that can be used to inhibit waiting for
+a greeting from the server.
+
:nowait is a boolean that says the connection should be made
asynchronously, if possible."
(unless (featurep 'make-network-process)
@@ -211,7 +214,8 @@ STARTTLS upgrades even if Emacs doesn't have built-in TLS functionality.
;; Return (STREAM GREETING CAPABILITIES RESULTING-TYPE)
(stream (make-network-process :name name :buffer buffer
:host host :service service))
- (greeting (network-stream-get-response stream start eoc))
+ (greeting (and (not (plist-get parameters :nogreeting))
+ (network-stream-get-response stream start eoc)))
(capabilities (network-stream-command stream capability-command
eo-capa))
(resulting-type 'plain)
diff --git a/lisp/net/shr.el b/lisp/net/shr.el
index 6ddf8d2af90..89791511e09 100644
--- a/lisp/net/shr.el
+++ b/lisp/net/shr.el
@@ -143,7 +143,7 @@ cid: URL as the argument.")
(define-key map [tab] 'shr-next-link)
(define-key map [backtab] 'shr-previous-link)
(define-key map [follow-link] 'mouse-face)
- (define-key map [mouse-2] 'shr-mouse-browse-url)
+ (define-key map [mouse-2] 'shr-browse-url)
(define-key map "I" 'shr-insert-image)
(define-key map "w" 'shr-copy-url)
(define-key map "u" 'shr-copy-url)
@@ -664,10 +664,11 @@ size, and full-buffer size."
(mouse-set-point ev)
(shr-browse-url))
-(defun shr-browse-url (&optional external)
+(defun shr-browse-url (&optional external mouse-event)
"Browse the URL under point.
If EXTERNAL, browse the URL using `shr-external-browser'."
- (interactive "P")
+ (interactive (list current-prefix-arg last-nonmenu-event))
+ (mouse-set-point mouse-event)
(let ((url (get-text-property (point) 'shr-url)))
(cond
((not url)
@@ -832,6 +833,8 @@ START, and END. Note that START and END should be markers."
start (point)
(list 'shr-url url
'help-echo (if title (format "%s (%s)" url title) url)
+ 'follow-link t
+ 'mouse-face 'highlight
'keymap shr-map)))
(defun shr-encode-url (url)
diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el
index 82b017fa230..33e9e5aa44b 100644
--- a/lisp/net/tramp-adb.el
+++ b/lisp/net/tramp-adb.el
@@ -85,53 +85,74 @@
(cons 'tramp-adb-file-name-p 'tramp-adb-file-name-handler))
(defconst tramp-adb-file-name-handler-alist
- '((directory-file-name . tramp-handle-directory-file-name)
+ '((access-file . ignore)
+ (add-name-to-file . tramp-adb-handle-copy-file)
+ ;; `byte-compiler-base-file-name' performed by default handler.
+ ;; `copy-directory' performed by default handler.
+ (copy-file . tramp-adb-handle-copy-file)
+ (delete-directory . tramp-adb-handle-delete-directory)
+ (delete-file . tramp-adb-handle-delete-file)
+ ;; `diff-latest-backup-file' performed by default handler.
+ (directory-file-name . tramp-handle-directory-file-name)
+ (directory-files . tramp-handle-directory-files)
+ (directory-files-and-attributes
+ . tramp-adb-handle-directory-files-and-attributes)
+ (dired-call-process . ignore)
+ (dired-compress-file . ignore)
(dired-uncache . tramp-handle-dired-uncache)
+ (expand-file-name . tramp-adb-handle-expand-file-name)
+ (file-accessible-directory-p . tramp-handle-file-accessible-directory-p)
+ (file-acl . ignore)
+ (file-attributes . tramp-adb-handle-file-attributes)
+ (file-directory-p . tramp-adb-handle-file-directory-p)
+ ;; `file-equal-p' performed by default handler.
+ ;; FIXME: This is too sloppy.
+ (file-executable-p . tramp-handle-file-exists-p)
+ (file-exists-p . tramp-handle-file-exists-p)
+ ;; `file-in-directory-p' performed by default handler.
+ (file-local-copy . tramp-adb-handle-file-local-copy)
+ (file-modes . tramp-handle-file-modes)
+ (file-name-all-completions . tramp-adb-handle-file-name-all-completions)
(file-name-as-directory . tramp-handle-file-name-as-directory)
(file-name-completion . tramp-handle-file-name-completion)
- (file-name-all-completions . tramp-adb-handle-file-name-all-completions)
- (file-attributes . tramp-adb-handle-file-attributes)
(file-name-directory . tramp-handle-file-name-directory)
(file-name-nondirectory . tramp-handle-file-name-nondirectory)
- (file-truename . tramp-adb-handle-file-truename)
+ ;; `file-name-sans-versions' performed by default handler.
(file-newer-than-file-p . tramp-handle-file-newer-than-file-p)
- (file-name-as-directory . tramp-handle-file-name-as-directory)
+ (file-notify-add-watch . tramp-handle-file-notify-add-watch)
+ (file-notify-rm-watch . tramp-handle-file-notify-rm-watch)
+ (file-ownership-preserved-p . ignore)
+ (file-readable-p . tramp-handle-file-exists-p)
(file-regular-p . tramp-handle-file-regular-p)
(file-remote-p . tramp-handle-file-remote-p)
- (file-accessible-directory-p . tramp-handle-file-accessible-directory-p)
- (file-directory-p . tramp-adb-handle-file-directory-p)
+ (file-selinux-context . ignore)
(file-symlink-p . tramp-handle-file-symlink-p)
- ;; FIXME: This is too sloppy.
- (file-executable-p . tramp-handle-file-exists-p)
- (file-exists-p . tramp-handle-file-exists-p)
- (file-readable-p . tramp-handle-file-exists-p)
+ (file-truename . tramp-adb-handle-file-truename)
(file-writable-p . tramp-adb-handle-file-writable-p)
- (file-local-copy . tramp-adb-handle-file-local-copy)
- (file-modes . tramp-handle-file-modes)
- (file-notify-add-watch . tramp-handle-file-notify-add-watch)
- (file-notify-rm-watch . ignore)
- (expand-file-name . tramp-adb-handle-expand-file-name)
(find-backup-file-name . tramp-handle-find-backup-file-name)
- (directory-files . tramp-handle-directory-files)
- (directory-files-and-attributes
- . tramp-adb-handle-directory-files-and-attributes)
- (make-directory . tramp-adb-handle-make-directory)
- (delete-directory . tramp-adb-handle-delete-directory)
- (delete-file . tramp-adb-handle-delete-file)
- (load . tramp-handle-load)
+ ;; `find-file-noselect' performed by default handler.
+ ;; `get-file-buffer' performed by default handler.
(insert-directory . tramp-adb-handle-insert-directory)
(insert-file-contents . tramp-handle-insert-file-contents)
- (substitute-in-file-name . tramp-handle-substitute-in-file-name)
- (unhandled-file-name-directory . tramp-handle-unhandled-file-name-directory)
- (vc-registered . ignore) ;no vc control files on Android devices
- (write-region . tramp-adb-handle-write-region)
+ (load . tramp-handle-load)
+ ;; `make-auto-save-file-name' performed by default handler.
+ (make-directory . tramp-adb-handle-make-directory)
+ (make-directory-internal . ignore)
+ (make-symbolic-link . ignore)
+ (process-file . tramp-adb-handle-process-file)
+ (rename-file . tramp-adb-handle-rename-file)
+ (set-file-acl . ignore)
(set-file-modes . tramp-adb-handle-set-file-modes)
+ (set-file-selinux-context . ignore)
(set-file-times . tramp-adb-handle-set-file-times)
- (copy-file . tramp-adb-handle-copy-file)
- (rename-file . tramp-adb-handle-rename-file)
- (process-file . tramp-adb-handle-process-file)
+ (set-visited-file-modtime . tramp-handle-set-visited-file-modtime)
(shell-command . tramp-adb-handle-shell-command)
- (start-file-process . tramp-adb-handle-start-file-process))
+ (start-file-process . tramp-adb-handle-start-file-process)
+ (substitute-in-file-name . tramp-handle-substitute-in-file-name)
+ (unhandled-file-name-directory . tramp-handle-unhandled-file-name-directory)
+ (vc-registered . ignore)
+ (verify-visited-file-modtime . tramp-handle-verify-visited-file-modtime)
+ (write-region . tramp-adb-handle-write-region))
"Alist of handler functions for Tramp ADB method.")
;; It must be a `defsubst' in order to push the whole code into
@@ -599,6 +620,9 @@ But handle the case, if the \"test\" command is not available."
(tramp-error v 'file-error "Cannot write: `%s' filename"))
(delete-file tmpfile)))
+ (when (or (eq visit t) (stringp visit))
+ (set-visited-file-modtime))
+
(unless (equal curbuf (current-buffer))
(tramp-error
v 'file-error
diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el
index e25c9bd4caf..5bb30b04643 100644
--- a/lisp/net/tramp-gvfs.el
+++ b/lisp/net/tramp-gvfs.el
@@ -403,10 +403,10 @@ Every entry is a list (NAME ADDRESS).")
;; New handlers should be added here.
(defconst tramp-gvfs-file-name-handler-alist
- '(
- (access-file . ignore)
+ '((access-file . ignore)
(add-name-to-file . tramp-gvfs-handle-copy-file)
;; `byte-compiler-base-file-name' performed by default handler.
+ ;; `copy-directory' performed by default handler.
(copy-file . tramp-gvfs-handle-copy-file)
(delete-directory . tramp-gvfs-handle-delete-directory)
(delete-file . tramp-gvfs-handle-delete-file)
@@ -418,14 +418,15 @@ Every entry is a list (NAME ADDRESS).")
(dired-call-process . ignore)
(dired-compress-file . ignore)
(dired-uncache . tramp-handle-dired-uncache)
- ;; `executable-find' is not official yet. performed by default handler.
(expand-file-name . tramp-gvfs-handle-expand-file-name)
(file-accessible-directory-p . tramp-handle-file-accessible-directory-p)
(file-acl . ignore)
(file-attributes . tramp-gvfs-handle-file-attributes)
(file-directory-p . tramp-gvfs-handle-file-directory-p)
+ ;; `file-equal-p' performed by default handler.
(file-executable-p . tramp-gvfs-handle-file-executable-p)
(file-exists-p . tramp-handle-file-exists-p)
+ ;; `file-in-directory-p' performed by default handler.
(file-local-copy . tramp-gvfs-handle-file-local-copy)
(file-modes . tramp-handle-file-modes)
(file-name-all-completions . tramp-gvfs-handle-file-name-all-completions)
@@ -435,8 +436,8 @@ Every entry is a list (NAME ADDRESS).")
(file-name-nondirectory . tramp-handle-file-name-nondirectory)
;; `file-name-sans-versions' performed by default handler.
(file-newer-than-file-p . tramp-handle-file-newer-than-file-p)
- (file-notify-add-watch . tramp-handle-file-notify-add-watch)
- (file-notify-rm-watch . ignore)
+ (file-notify-add-watch . tramp-gvfs-handle-file-notify-add-watch)
+ (file-notify-rm-watch . tramp-handle-file-notify-rm-watch)
(file-ownership-preserved-p . ignore)
(file-readable-p . tramp-gvfs-handle-file-readable-p)
(file-regular-p . tramp-handle-file-regular-p)
@@ -451,6 +452,7 @@ Every entry is a list (NAME ADDRESS).")
(insert-directory . tramp-gvfs-handle-insert-directory)
(insert-file-contents . tramp-gvfs-handle-insert-file-contents)
(load . tramp-handle-load)
+ ;; `make-auto-save-file-name' performed by default handler.
(make-directory . tramp-gvfs-handle-make-directory)
(make-directory-internal . ignore)
(make-symbolic-link . ignore)
@@ -459,15 +461,15 @@ Every entry is a list (NAME ADDRESS).")
(set-file-acl . ignore)
(set-file-modes . ignore)
(set-file-selinux-context . ignore)
- (set-visited-file-modtime . tramp-gvfs-handle-set-visited-file-modtime)
+ (set-file-times . ignore)
+ (set-visited-file-modtime . tramp-handle-set-visited-file-modtime)
(shell-command . ignore)
(start-file-process . ignore)
(substitute-in-file-name . tramp-handle-substitute-in-file-name)
(unhandled-file-name-directory . tramp-handle-unhandled-file-name-directory)
(vc-registered . ignore)
- ;; `verify-visited-file-modtime' performed by default handler.
- (write-region . tramp-gvfs-handle-write-region)
-)
+ (verify-visited-file-modtime . tramp-handle-verify-visited-file-modtime)
+ (write-region . tramp-gvfs-handle-write-region))
"Alist of handler functions for Tramp GVFS method.
Operations not mentioned here will be handled by the default Emacs primitives.")
@@ -555,28 +557,6 @@ will be traced by Tramp with trace level 6."
(tramp-compat-font-lock-add-keywords
'emacs-lisp-mode '("\\<with-tramp-dbus-call-method\\>"))
-(defmacro with-tramp-gvfs-error-message (filename handler &rest args)
- "Apply a Tramp GVFS `handler'.
-In case of an error, modify the error message by replacing
-`filename' with its GVFS mounted name."
- `(let ((fuse-file-name (regexp-quote (tramp-gvfs-fuse-file-name ,filename)))
- elt)
- (condition-case err
- (tramp-compat-funcall ,handler ,@args)
- (error
- (setq elt (cdr err))
- (while elt
- (when (and (stringp (car elt))
- (string-match fuse-file-name (car elt)))
- (setcar elt (replace-match ,filename t t (car elt))))
- (setq elt (cdr elt)))
- (signal (car err) (cdr err))))))
-
-(put 'with-tramp-gvfs-error-message 'lisp-indent-function 2)
-(put 'with-tramp-gvfs-error-message 'edebug-form-spec '(form symbolp body))
-(tramp-compat-font-lock-add-keywords
- 'emacs-lisp-mode '("\\<with-tramp-gvfs-error-message\\>"))
-
(defvar tramp-gvfs-dbus-event-vector nil
"Current Tramp file name to be used, as vector.
It is needed when D-Bus signals or errors arrive, because there
@@ -943,6 +923,64 @@ is no information where to trace the message.")
v (concat localname filename)
"file-name-all-completions" result))))))))
+(defun tramp-gvfs-handle-file-notify-add-watch (file-name flags callback)
+ "Like `file-notify-add-watch' for Tramp files."
+ (setq file-name (expand-file-name file-name))
+ (with-parsed-tramp-file-name file-name nil
+ (let ((p (start-process
+ "gvfs-monitor-file" (generate-new-buffer " *gvfs-monitor-file*")
+ "gvfs-monitor-file" (tramp-gvfs-url-file-name file-name))))
+ (if (not (processp p))
+ (tramp-error
+ v 'file-notify-error "gvfs-monitor-file failed to start")
+ (tramp-compat-set-process-query-on-exit-flag p nil)
+ (set-process-filter p 'tramp-gvfs-file-gvfs-monitor-file-process-filter)
+ (with-current-buffer (process-buffer p)
+ (setq default-directory (file-name-directory file-name)))
+ p))))
+
+(defun tramp-gvfs-file-gvfs-monitor-file-process-filter (proc string)
+ "Read output from \"gvfs-monitor-file\" and add corresponding file-notify events."
+ (let* ((rest-string (tramp-compat-process-get proc 'rest-string))
+ (dd (with-current-buffer (process-buffer proc) default-directory))
+ (ddu (regexp-quote (tramp-gvfs-url-file-name dd))))
+ (when rest-string
+ (tramp-message proc 10 "Previous string:\n%s" rest-string))
+ (tramp-message proc 6 "%S\n%s" proc string)
+ (setq string (concat rest-string string)
+ ;; Attribute change is returned in unused wording.
+ string (replace-regexp-in-string
+ "ATTRIB CHANGED" "ATTRIBUTE_CHANGED" string))
+
+ (while (string-match
+ (concat "^[\n\r]*"
+ "File Monitor Event:[\n\r]+"
+ "File = \\([^\n\r]+\\)[\n\r]+"
+ "Event = \\([^[:blank:]]+\\)[\n\r]+")
+ string)
+ (let ((action (intern-soft
+ (replace-regexp-in-string
+ "_" "-" (downcase (match-string 2 string)))))
+ (file (match-string 1 string)))
+ (setq string (replace-match "" nil nil string))
+ ;; File names are returned as URL paths. We must convert them.
+ (when (string-match ddu file)
+ (setq file (replace-match dd nil nil file)))
+ (while (string-match "%\\([0-9A-F]\\{2\\}\\)" file)
+ (setq file
+ (replace-match
+ (char-to-string (string-to-number (match-string 1 file) 16))
+ nil nil file)))
+ ;; Usually, we would add an Emacs event now. Unfortunately,
+ ;; `unread-command-events' does not accept several events at
+ ;; once. Therefore, we apply the callback directly.
+ (tramp-compat-funcall 'file-notify-callback (list proc action file))))
+
+ ;; Save rest of the string.
+ (when (zerop (length string)) (setq string nil))
+ (when string (tramp-message proc 10 "Rest string:\n%s" string))
+ (tramp-compat-process-put proc 'rest-string string)))
+
(defun tramp-gvfs-handle-file-readable-p (filename)
"Like `file-readable-p' for Tramp files."
(with-parsed-tramp-file-name filename nil
@@ -1054,22 +1092,6 @@ is no information where to trace the message.")
(tramp-flush-file-property v (file-name-directory localname))
(tramp-flush-file-property v localname))))))
-(defun tramp-gvfs-handle-set-visited-file-modtime (&optional time-list)
- "Like `set-visited-file-modtime' for Tramp files."
- (unless (buffer-file-name)
- (error "Can't set-visited-file-modtime: buffer `%s' not visiting a file"
- (buffer-name)))
- (unless time-list
- (let ((f (buffer-file-name)))
- (with-parsed-tramp-file-name f nil
- (let ((remote-file-name-inhibit-cache t)
- (attr (file-attributes f)))
- ;; '(-1 65535) means file doesn't exists yet.
- (setq time-list (or (nth 5 attr) '(-1 65535)))))))
- ;; We use '(0 0) as a don't-know value.
- (unless (not (equal time-list '(0 0)))
- (tramp-run-real-handler 'set-visited-file-modtime (list time-list))))
-
(defun tramp-gvfs-handle-write-region
(start end filename &optional append visit lockname confirm)
"Like `write-region' for Tramp files."
@@ -1082,7 +1104,7 @@ is no information where to trace the message.")
(let ((tmpfile (tramp-compat-make-temp-file filename)))
(write-region start end tmpfile)
(condition-case nil
- (rename-file tmpfile filename)
+ (rename-file tmpfile filename 'ok-if-already-exists)
(error
(delete-file tmpfile)
(tramp-error
@@ -1137,24 +1159,6 @@ is no information where to trace the message.")
(dbus-unescape-from-identifier
(replace-regexp-in-string "^.*/\\([^/]+\\)$" "\\1" object-path)))
-(defun tramp-gvfs-fuse-file-name (filename)
- "Return FUSE file name, which is directly accessible."
- (with-parsed-tramp-file-name (expand-file-name filename) nil
- (tramp-gvfs-maybe-open-connection v)
- (let ((prefix (tramp-get-file-property v "/" "prefix" ""))
- (fuse-mountpoint
- (tramp-get-file-property v "/" "fuse-mountpoint" nil)))
- (unless fuse-mountpoint
- (tramp-error
- v 'file-error "There is no FUSE mount point for `%s'" filename))
- ;; We must hide the prefix, if any.
- (when (string-match (concat "^" (regexp-quote prefix)) localname)
- (setq localname (replace-match "" t t localname)))
- (tramp-message
- v 10 "remote file `%s' is local file `%s'"
- filename (concat fuse-mountpoint localname))
- (concat fuse-mountpoint localname))))
-
(defun tramp-bluez-address (device)
"Return bluetooth device address from a given bluetooth DEVICE name."
(when (stringp device)
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el
index 441849fd2af..f9e68d0dad0 100644
--- a/lisp/net/tramp-sh.el
+++ b/lisp/net/tramp-sh.el
@@ -801,73 +801,78 @@ existence, and file readability. Input shall be read via
here-document, otherwise the command could exceed maximum length
of command line.")
-;; New handlers should be added here. The following operations can be
-;; handled using the normal primitives: file-name-sans-versions,
-;; get-file-buffer.
+;; New handlers should be added here.
(defconst tramp-sh-file-name-handler-alist
- '((load . tramp-handle-load)
- (make-symbolic-link . tramp-sh-handle-make-symbolic-link)
- (file-name-as-directory . tramp-handle-file-name-as-directory)
- (file-name-directory . tramp-handle-file-name-directory)
- (file-name-nondirectory . tramp-handle-file-name-nondirectory)
- (file-truename . tramp-sh-handle-file-truename)
- (file-exists-p . tramp-sh-handle-file-exists-p)
- (file-accessible-directory-p . tramp-handle-file-accessible-directory-p)
- (file-directory-p . tramp-sh-handle-file-directory-p)
- (file-executable-p . tramp-sh-handle-file-executable-p)
- (file-readable-p . tramp-sh-handle-file-readable-p)
- (file-regular-p . tramp-handle-file-regular-p)
- (file-symlink-p . tramp-handle-file-symlink-p)
- (file-writable-p . tramp-sh-handle-file-writable-p)
- (file-ownership-preserved-p . tramp-sh-handle-file-ownership-preserved-p)
- (file-newer-than-file-p . tramp-sh-handle-file-newer-than-file-p)
- (file-attributes . tramp-sh-handle-file-attributes)
- (file-modes . tramp-handle-file-modes)
- (directory-files . tramp-handle-directory-files)
- (directory-files-and-attributes
- . tramp-sh-handle-directory-files-and-attributes)
- (file-name-all-completions . tramp-sh-handle-file-name-all-completions)
- (file-name-completion . tramp-handle-file-name-completion)
+ '(;; `access-file' performed by default handler.
(add-name-to-file . tramp-sh-handle-add-name-to-file)
- (copy-file . tramp-sh-handle-copy-file)
+ ;; `byte-compiler-base-file-name' performed by default handler.
(copy-directory . tramp-sh-handle-copy-directory)
- (rename-file . tramp-sh-handle-rename-file)
- (set-file-modes . tramp-sh-handle-set-file-modes)
- (set-file-times . tramp-sh-handle-set-file-times)
- (make-directory . tramp-sh-handle-make-directory)
+ (copy-file . tramp-sh-handle-copy-file)
(delete-directory . tramp-sh-handle-delete-directory)
(delete-file . tramp-sh-handle-delete-file)
+ ;; `diff-latest-backup-file' performed by default handler.
(directory-file-name . tramp-handle-directory-file-name)
- ;; `executable-find' is not official yet.
- (executable-find . tramp-sh-handle-executable-find)
- (start-file-process . tramp-sh-handle-start-file-process)
- (process-file . tramp-sh-handle-process-file)
- (shell-command . tramp-handle-shell-command)
- (insert-directory . tramp-sh-handle-insert-directory)
+ (directory-files . tramp-handle-directory-files)
+ (directory-files-and-attributes
+ . tramp-sh-handle-directory-files-and-attributes)
+ ;; `dired-call-process' performed by default handler.
+ (dired-compress-file . tramp-sh-handle-dired-compress-file)
+ (dired-recursive-delete-directory
+ . tramp-sh-handle-dired-recursive-delete-directory)
+ (dired-uncache . tramp-handle-dired-uncache)
(expand-file-name . tramp-sh-handle-expand-file-name)
- (substitute-in-file-name . tramp-handle-substitute-in-file-name)
+ (file-accessible-directory-p . tramp-handle-file-accessible-directory-p)
+ (file-acl . tramp-sh-handle-file-acl)
+ (file-attributes . tramp-sh-handle-file-attributes)
+ (file-directory-p . tramp-sh-handle-file-directory-p)
+ ;; `file-equal-p' performed by default handler.
+ (file-executable-p . tramp-sh-handle-file-executable-p)
+ (file-exists-p . tramp-sh-handle-file-exists-p)
+ ;; `file-in-directory-p' performed by default handler.
(file-local-copy . tramp-sh-handle-file-local-copy)
+ (file-modes . tramp-handle-file-modes)
+ (file-name-all-completions . tramp-sh-handle-file-name-all-completions)
+ (file-name-as-directory . tramp-handle-file-name-as-directory)
+ (file-name-completion . tramp-handle-file-name-completion)
+ (file-name-directory . tramp-handle-file-name-directory)
+ (file-name-nondirectory . tramp-handle-file-name-nondirectory)
+ ;; `file-name-sans-versions' performed by default handler.
+ (file-newer-than-file-p . tramp-sh-handle-file-newer-than-file-p)
+ (file-notify-add-watch . tramp-sh-handle-file-notify-add-watch)
+ (file-notify-rm-watch . tramp-handle-file-notify-rm-watch)
+ (file-ownership-preserved-p . tramp-sh-handle-file-ownership-preserved-p)
+ (file-readable-p . tramp-sh-handle-file-readable-p)
+ (file-regular-p . tramp-handle-file-regular-p)
(file-remote-p . tramp-handle-file-remote-p)
+ (file-selinux-context . tramp-sh-handle-file-selinux-context)
+ (file-symlink-p . tramp-handle-file-symlink-p)
+ (file-truename . tramp-sh-handle-file-truename)
+ (file-writable-p . tramp-sh-handle-file-writable-p)
+ (find-backup-file-name . tramp-handle-find-backup-file-name)
+ ;; `find-file-noselect' performed by default handler.
+ ;; `get-file-buffer' performed by default handler.
+ (insert-directory . tramp-sh-handle-insert-directory)
(insert-file-contents . tramp-handle-insert-file-contents)
(insert-file-contents-literally
. tramp-sh-handle-insert-file-contents-literally)
- (write-region . tramp-sh-handle-write-region)
- (find-backup-file-name . tramp-handle-find-backup-file-name)
+ (load . tramp-handle-load)
(make-auto-save-file-name . tramp-sh-handle-make-auto-save-file-name)
- (unhandled-file-name-directory . tramp-handle-unhandled-file-name-directory)
- (dired-compress-file . tramp-sh-handle-dired-compress-file)
- (dired-recursive-delete-directory
- . tramp-sh-handle-dired-recursive-delete-directory)
- (dired-uncache . tramp-handle-dired-uncache)
- (set-visited-file-modtime . tramp-sh-handle-set-visited-file-modtime)
- (verify-visited-file-modtime . tramp-sh-handle-verify-visited-file-modtime)
- (file-selinux-context . tramp-sh-handle-file-selinux-context)
- (set-file-selinux-context . tramp-sh-handle-set-file-selinux-context)
- (file-acl . tramp-sh-handle-file-acl)
+ (make-directory . tramp-sh-handle-make-directory)
+ (make-symbolic-link . tramp-sh-handle-make-symbolic-link)
+ (process-file . tramp-sh-handle-process-file)
+ (rename-file . tramp-sh-handle-rename-file)
(set-file-acl . tramp-sh-handle-set-file-acl)
+ (set-file-modes . tramp-sh-handle-set-file-modes)
+ (set-file-selinux-context . tramp-sh-handle-set-file-selinux-context)
+ (set-file-times . tramp-sh-handle-set-file-times)
+ (set-visited-file-modtime . tramp-sh-handle-set-visited-file-modtime)
+ (shell-command . tramp-handle-shell-command)
+ (start-file-process . tramp-sh-handle-start-file-process)
+ (substitute-in-file-name . tramp-handle-substitute-in-file-name)
+ (unhandled-file-name-directory . tramp-handle-unhandled-file-name-directory)
(vc-registered . tramp-sh-handle-vc-registered)
- (file-notify-add-watch . tramp-sh-handle-file-notify-add-watch)
- (file-notify-rm-watch . tramp-sh-handle-file-notify-rm-watch))
+ (verify-visited-file-modtime . tramp-sh-handle-verify-visited-file-modtime)
+ (write-region . tramp-sh-handle-write-region))
"Alist of handler functions.
Operations not mentioned here will be handled by the normal Emacs functions.")
@@ -2284,9 +2289,7 @@ The method used must be an out-of-band method."
(tramp-get-method-parameter method 'tramp-copy-env))))
;; Check for program.
- (unless (let ((default-directory
- (tramp-compat-temporary-file-directory)))
- (executable-find copy-program))
+ (unless (executable-find copy-program)
(tramp-error
v 'file-error "Cannot find copy program: %s" copy-program))
@@ -2667,11 +2670,6 @@ the result will be a local, non-Tramp, filename."
;;; Remote commands:
-(defun tramp-sh-handle-executable-find (command)
- "Like `executable-find' for Tramp files."
- (with-parsed-tramp-file-name default-directory nil
- (tramp-find-executable v command (tramp-get-remote-path v) t)))
-
(defun tramp-process-sentinel (proc event)
"Flush file caches."
(unless (memq (process-status proc) '(run open))
@@ -3430,8 +3428,8 @@ Fall back to normal file name handler if no Tramp handler exists."
(file-remote-p default-directory)))
(rest-string (tramp-compat-process-get proc 'rest-string)))
(when rest-string
- (tramp-message proc 10 (format "Previous string:\n%s" rest-string)))
- (tramp-message proc 6 (format "%S\n%s" proc string))
+ (tramp-message proc 10 "Previous string:\n%s" rest-string))
+ (tramp-message proc 6 "%S\n%s" proc string)
(setq string (concat rest-string string)
;; Attribute change is returned in unused wording.
string (replace-regexp-in-string
@@ -3463,12 +3461,12 @@ Fall back to normal file name handler if no Tramp handler exists."
;; Save rest of the string.
(when (zerop (length string)) (setq string nil))
- (when string (tramp-message proc 10 (format "Rest string:\n%s" string)))
+ (when string (tramp-message proc 10 "Rest string:\n%s" string))
(tramp-compat-process-put proc 'rest-string string)))
(defun tramp-sh-file-inotifywait-process-filter (proc string)
"Read output from \"inotifywait\" and add corresponding file-notify events."
- (tramp-message proc 6 (format "%S\n%s" proc string))
+ (tramp-message proc 6 "%S\n%s" proc string)
(dolist (line (split-string string "[\n\r]+" 'omit-nulls))
;; Check, whether there is a problem.
(unless
@@ -3492,15 +3490,6 @@ Fall back to normal file name handler if no Tramp handler exists."
;; once. Therefore, we apply the callback directly.
(tramp-compat-funcall 'file-notify-callback object))))
-(defvar file-notify-descriptors)
-(defun tramp-sh-handle-file-notify-rm-watch (proc)
- "Like `file-notify-rm-watch' for Tramp files."
- ;; The descriptor must be a process object.
- (unless (and (processp proc) (gethash proc file-notify-descriptors))
- (tramp-error proc 'file-notify-error "Not a valid descriptor %S" proc))
- (tramp-message proc 6 (format "Kill %S" proc))
- (kill-process proc))
-
;;; Internal Functions:
(defun tramp-maybe-send-script (vec script name)
@@ -3618,7 +3607,7 @@ This function expects to be in the right *tramp* buffer."
I.e., for each directory in `tramp-remote-path', it is tested
whether it exists and if so, it is added to the environment
variable PATH."
- (tramp-message vec 5 (format "Setting $PATH environment variable"))
+ (tramp-message vec 5 "Setting $PATH environment variable")
(tramp-send-command
vec (format "PATH=%s; export PATH"
(mapconcat 'identity (tramp-get-remote-path vec) ":"))))
diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el
index fee34f856dd..29847556dfe 100644
--- a/lisp/net/tramp-smb.el
+++ b/lisp/net/tramp-smb.el
@@ -177,8 +177,7 @@ See `tramp-actions-before-shell' for more info.")
;; New handlers should be added here.
(defconst tramp-smb-file-name-handler-alist
- '(
- ;; `access-file' performed by default handler.
+ '(;; `access-file' performed by default handler.
(add-name-to-file . tramp-smb-handle-add-name-to-file)
;; `byte-compiler-base-file-name' performed by default handler.
(copy-directory . tramp-smb-handle-copy-directory)
@@ -198,8 +197,10 @@ See `tramp-actions-before-shell' for more info.")
(file-acl . tramp-smb-handle-file-acl)
(file-attributes . tramp-smb-handle-file-attributes)
(file-directory-p . tramp-smb-handle-file-directory-p)
+ ;; `file-equal-p' performed by default handler.
(file-executable-p . tramp-handle-file-exists-p)
(file-exists-p . tramp-handle-file-exists-p)
+ ;; `file-in-directory-p' performed by default handler.
(file-local-copy . tramp-smb-handle-file-local-copy)
(file-modes . tramp-handle-file-modes)
(file-name-all-completions . tramp-smb-handle-file-name-all-completions)
@@ -210,7 +211,7 @@ See `tramp-actions-before-shell' for more info.")
;; `file-name-sans-versions' performed by default handler.
(file-newer-than-file-p . tramp-handle-file-newer-than-file-p)
(file-notify-add-watch . tramp-handle-file-notify-add-watch)
- (file-notify-rm-watch . ignore)
+ (file-notify-rm-watch . tramp-handle-file-notify-rm-watch)
(file-ownership-preserved-p . ignore)
(file-readable-p . tramp-handle-file-exists-p)
(file-regular-p . tramp-handle-file-regular-p)
@@ -225,6 +226,7 @@ See `tramp-actions-before-shell' for more info.")
(insert-directory . tramp-smb-handle-insert-directory)
(insert-file-contents . tramp-handle-insert-file-contents)
(load . tramp-handle-load)
+ ;; `make-auto-save-file-name' performed by default handler.
(make-directory . tramp-smb-handle-make-directory)
(make-directory-internal . tramp-smb-handle-make-directory-internal)
(make-symbolic-link . tramp-smb-handle-make-symbolic-link)
@@ -234,15 +236,14 @@ See `tramp-actions-before-shell' for more info.")
(set-file-modes . tramp-smb-handle-set-file-modes)
(set-file-selinux-context . ignore)
(set-file-times . ignore)
- (set-visited-file-modtime . ignore)
+ (set-visited-file-modtime . tramp-handle-set-visited-file-modtime)
(shell-command . tramp-handle-shell-command)
(start-file-process . tramp-smb-handle-start-file-process)
(substitute-in-file-name . tramp-smb-handle-substitute-in-file-name)
(unhandled-file-name-directory . tramp-handle-unhandled-file-name-directory)
(vc-registered . ignore)
- (verify-visited-file-modtime . ignore)
- (write-region . tramp-smb-handle-write-region)
-)
+ (verify-visited-file-modtime . tramp-handle-verify-visited-file-modtime)
+ (write-region . tramp-smb-handle-write-region))
"Alist of handler functions for Tramp SMB method.
Operations not mentioned here will be handled by the default Emacs primitives.")
@@ -1786,9 +1787,7 @@ Returns nil if an error message has appeared."
(tramp-get-buffer vec)
;; Check for program.
- (unless (let ((default-directory
- (tramp-compat-temporary-file-directory)))
- (executable-find tramp-smb-winexe-program))
+ (unless (executable-find tramp-smb-winexe-program)
(tramp-error
vec 'file-error "Cannot find program: %s" tramp-smb-winexe-program))
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index 48e13004c36..8ce5f2eae9b 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -1975,11 +1975,11 @@ ARGS are the arguments OPERATION has been called with."
'dired-compress-file 'dired-uncache
'file-accessible-directory-p 'file-attributes
'file-directory-p 'file-executable-p 'file-exists-p
- 'file-local-copy 'file-remote-p 'file-modes
+ 'file-local-copy 'file-modes
'file-name-as-directory 'file-name-directory
'file-name-nondirectory 'file-name-sans-versions
'file-ownership-preserved-p 'file-readable-p
- 'file-regular-p 'file-symlink-p 'file-truename
+ 'file-regular-p 'file-remote-p 'file-symlink-p 'file-truename
'file-writable-p 'find-backup-file-name 'find-file-noselect
'get-file-buffer 'insert-directory 'insert-file-contents
'load 'make-directory 'make-directory-internal
@@ -2008,7 +2008,7 @@ ARGS are the arguments OPERATION has been called with."
;; Emacs 23+ only.
'copy-directory
;; Emacs 24+ only.
- 'file-in-directory-p 'file-equal-p
+ 'file-equal-p 'file-in-directory-p
;; XEmacs only.
'dired-make-relative-symlink
'vm-imap-move-mail 'vm-pop-move-mail 'vm-spool-move-mail))
@@ -3287,14 +3287,78 @@ beginning of local filename are not substituted."
;; for backward compatibility.
(expand-file-name "~/"))
+(defun tramp-handle-set-visited-file-modtime (&optional time-list)
+ "Like `set-visited-file-modtime' for Tramp files."
+ (unless (buffer-file-name)
+ (error "Can't set-visited-file-modtime: buffer `%s' not visiting a file"
+ (buffer-name)))
+ (unless time-list
+ (let ((remote-file-name-inhibit-cache t))
+ ;; '(-1 65535) means file doesn't exists yet.
+ (setq time-list
+ (or (nth 5 (file-attributes (buffer-file-name))) '(-1 65535)))))
+ ;; We use '(0 0) as a don't-know value.
+ (unless (equal time-list '(0 0))
+ (tramp-run-real-handler 'set-visited-file-modtime (list time-list))))
+
+(defun tramp-handle-verify-visited-file-modtime (&optional buf)
+ "Like `verify-visited-file-modtime' for Tramp files.
+At the time `verify-visited-file-modtime' calls this function, we
+already know that the buffer is visiting a file and that
+`visited-file-modtime' does not return 0. Do not call this
+function directly, unless those two cases are already taken care
+of."
+ (with-current-buffer (or buf (current-buffer))
+ (let ((f (buffer-file-name)))
+ ;; There is no file visiting the buffer, or the buffer has no
+ ;; recorded last modification time, or there is no established
+ ;; connection.
+ (if (or (not f)
+ (eq (visited-file-modtime) 0)
+ (not (tramp-file-name-handler 'file-remote-p f nil 'connected)))
+ t
+ (with-parsed-tramp-file-name f nil
+ (let* ((remote-file-name-inhibit-cache t)
+ (attr (file-attributes f))
+ (modtime (nth 5 attr))
+ (mt (visited-file-modtime)))
+
+ (cond
+ ;; File exists, and has a known modtime.
+ ((and attr (not (equal modtime '(0 0))))
+ (< (abs (tramp-time-diff
+ modtime
+ ;; For compatibility, deal with both the old
+ ;; (HIGH . LOW) and the new (HIGH LOW) return
+ ;; values of `visited-file-modtime'.
+ (if (atom (cdr mt))
+ (list (car mt) (cdr mt))
+ mt)))
+ 2))
+ ;; Modtime has the don't know value.
+ (attr t)
+ ;; If file does not exist, say it is not modified if and
+ ;; only if that agrees with the buffer's record.
+ (t (equal mt '(-1 65535))))))))))
+
(defun tramp-handle-file-notify-add-watch (filename flags callback)
"Like `file-notify-add-watch' for Tramp files."
- ;; This is the default handler. Some packages might have its own one.
+ ;; This is the default handler. tramp-gvfs.el and tramp-sh.el have
+ ;; its own one.
(setq filename (expand-file-name filename))
(with-parsed-tramp-file-name filename nil
(tramp-error
v 'file-notify-error "File notification not supported for `%s'" filename)))
+(defvar file-notify-descriptors)
+(defun tramp-handle-file-notify-rm-watch (proc)
+ "Like `file-notify-rm-watch' for Tramp files."
+ ;; The descriptor must be a process object.
+ (unless (and (processp proc) (gethash proc file-notify-descriptors))
+ (tramp-error proc 'file-notify-error "Not a valid descriptor %S" proc))
+ (tramp-message proc 6 "Kill %S" proc)
+ (kill-process proc))
+
;;; Functions for establishing connection:
;; The following functions are actions to be taken when seeing certain
@@ -3951,16 +4015,12 @@ This is needed because for some Emacs flavors Tramp has
defadvised `call-process' to behave like `process-file'. The
Lisp error raised when PROGRAM is nil is trapped also, returning 1.
Furthermore, traces are written with verbosity of 6."
- (let ((default-directory
- (if (file-remote-p default-directory)
- (tramp-compat-temporary-file-directory)
- default-directory)))
- (tramp-message
- (vector tramp-current-method tramp-current-user tramp-current-host nil nil)
- 6 "%s %s %s" program infile args)
- (if (executable-find program)
- (apply 'call-process program infile destination display args)
- 1)))
+ (tramp-message
+ (vector tramp-current-method tramp-current-user tramp-current-host nil nil)
+ 6 "%s %s %s" program infile args)
+ (if (executable-find program)
+ (apply 'call-process program infile destination display args)
+ 1))
;;;###tramp-autoload
(defun tramp-read-passwd (proc &optional prompt)
diff --git a/lisp/server.el b/lisp/server.el
index 05ac345d904..8a2a466a315 100644
--- a/lisp/server.el
+++ b/lisp/server.el
@@ -1611,7 +1611,7 @@ With ARG non-nil, silently save all file-visiting buffers, then kill.
If emacsclient was started with a list of filenames to edit, then
only these files will be asked to be saved."
- (let ((proc (frame-parameter (selected-frame) 'client)))
+ (let ((proc (frame-parameter nil 'client)))
(cond ((eq proc 'nowait)
;; Nowait frames have no client buffer list.
(if (cdr (frame-list))
diff --git a/lisp/speedbar.el b/lisp/speedbar.el
index 9daa77b740f..2f995219193 100644
--- a/lisp/speedbar.el
+++ b/lisp/speedbar.el
@@ -250,7 +250,7 @@ frame."
(defcustom speedbar-query-confirmation-method 'all
"Query control for file operations.
-The 'always flag means to always query before file operations.
+The 'all flag means to always query before file operations.
The 'none-but-delete flag means to not query before any file
operations, except before a file deletion."
:group 'speedbar
diff --git a/lisp/textmodes/reftex-toc.el b/lisp/textmodes/reftex-toc.el
index 248e36a5299..b7d57733467 100644
--- a/lisp/textmodes/reftex-toc.el
+++ b/lisp/textmodes/reftex-toc.el
@@ -229,7 +229,7 @@ When called with a raw C-u prefix, rescan the document first."
(car (reftex-where-am-I))))
(unsplittable (if (fboundp 'frame-property)
(frame-property (selected-frame) 'unsplittable)
- (frame-parameter (selected-frame) 'unsplittable)))
+ (frame-parameter nil 'unsplittable)))
offset toc-window)
(if (setq toc-window (get-buffer-window
@@ -587,7 +587,7 @@ With prefix arg 1, restrict index to the section at point."
(let ((unsplittable
(if (fboundp 'frame-property)
(frame-property (selected-frame) 'unsplittable)
- (frame-parameter (selected-frame) 'unsplittable)))
+ (frame-parameter nil 'unsplittable)))
(reftex-rebuilding-toc t))
(if unsplittable
(switch-to-buffer
diff --git a/lisp/url/ChangeLog b/lisp/url/ChangeLog
index 254ea5db4e4..120d00002e4 100644
--- a/lisp/url/ChangeLog
+++ b/lisp/url/ChangeLog
@@ -1,3 +1,8 @@
+2013-07-31 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * url-handlers.el (url-file-name-completion)
+ (url-file-name-all-completions): Don't signal errors (bug#14806).
+
2013-07-22 Stefan Monnier <monnier@iro.umontreal.ca>
* url-http.el (status): Remove, unused.
diff --git a/lisp/url/url-handlers.el b/lisp/url/url-handlers.el
index ae807d6eab9..e9bd1628c99 100644
--- a/lisp/url/url-handlers.el
+++ b/lisp/url/url-handlers.el
@@ -311,11 +311,17 @@ They count bytes from the beginning of the body."
(put 'insert-file-contents 'url-file-handlers 'url-insert-file-contents)
(defun url-file-name-completion (url directory &optional predicate)
- (error "Unimplemented"))
+ ;; Even if it's not implemented, it's not an error to ask for completion,
+ ;; in case it's available (bug#14806).
+ ;; (error "Unimplemented")
+ url)
(put 'file-name-completion 'url-file-handlers 'url-file-name-completion)
(defun url-file-name-all-completions (file directory)
- (error "Unimplemented"))
+ ;; Even if it's not implemented, it's not an error to ask for completion,
+ ;; in case it's available (bug#14806).
+ ;; (error "Unimplemented")
+ nil)
(put 'file-name-all-completions
'url-file-handlers 'url-file-name-all-completions)
diff --git a/lisp/vc/log-view.el b/lisp/vc/log-view.el
index de103c0cdb6..be985866532 100644
--- a/lisp/vc/log-view.el
+++ b/lisp/vc/log-view.el
@@ -562,19 +562,7 @@ file(s)."
(interactive
(list (if (use-region-p) (region-beginning) (point))
(if (use-region-p) (region-end) (point))))
- (let ((fr (log-view-current-tag beg))
- (to (log-view-current-tag end)))
- (when (string-equal fr to)
- (save-excursion
- (goto-char end)
- (log-view-msg-next)
- (setq to (log-view-current-tag))))
- (vc-diff-internal
- t (list log-view-vc-backend
- (if log-view-per-file-logs
- (list (log-view-current-file))
- log-view-vc-fileset))
- to fr)))
+ (log-view-diff-common beg end))
(defun log-view-diff-changeset (beg end)
"Get the diff between two revisions.
@@ -589,20 +577,29 @@ considered file(s)."
(interactive
(list (if (use-region-p) (region-beginning) (point))
(if (use-region-p) (region-end) (point))))
- (when (eq (vc-call-backend log-view-vc-backend 'revision-granularity) 'file)
+ (log-view-diff-common beg end t))
+
+(defun log-view-diff-common (beg end &optional whole-changeset)
+ (when (and whole-changeset
+ (eq (vc-call-backend log-view-vc-backend 'revision-granularity)
+ 'file))
(error "The %s backend does not support changeset diffs" log-view-vc-backend))
- (let ((fr (log-view-current-tag beg))
- (to (log-view-current-tag end)))
+ (let ((to (log-view-current-tag beg))
+ (fr (log-view-current-tag end)))
(when (string-equal fr to)
;; TO and FR are the same, look at the previous revision.
- (setq to (vc-call-backend log-view-vc-backend 'previous-revision nil fr)))
+ (setq fr (vc-call-backend log-view-vc-backend 'previous-revision nil fr)))
(vc-diff-internal
- t
- ;; We want to see the diff for all the files in the changeset, so
- ;; pass NIL for the file list. The value passed here should
- ;; follow what `vc-deduce-fileset' returns.
- (list log-view-vc-backend nil)
- to fr)))
+ t (list log-view-vc-backend
+ ;; The value passed here should follow what
+ ;; `vc-deduce-fileset' returns. If we want to see the
+ ;; diff for all the files in the changeset, pass NIL for
+ ;; the file list.
+ (unless whole-changeset
+ (if log-view-per-file-logs
+ (list (log-view-current-file))
+ log-view-vc-fileset)))
+ fr to)))
(provide 'log-view)
diff --git a/lisp/vc/vc-dir.el b/lisp/vc/vc-dir.el
index 441b3725968..5ddcfd57748 100644
--- a/lisp/vc/vc-dir.el
+++ b/lisp/vc/vc-dir.el
@@ -282,7 +282,7 @@ See `run-hooks'."
(define-key map "Q" 'vc-dir-query-replace-regexp)
(define-key map (kbd "M-s a C-s") 'vc-dir-isearch)
(define-key map (kbd "M-s a M-C-s") 'vc-dir-isearch-regexp)
- (define-key map "I" 'vc-dir-ignore)
+ (define-key map "G" 'vc-dir-ignore)
;; Hook up the menu.
(define-key map [menu-bar vc-dir-mode]
diff --git a/lisp/vc/vc-hooks.el b/lisp/vc/vc-hooks.el
index 284481ee524..ae9aa0118ae 100644
--- a/lisp/vc/vc-hooks.el
+++ b/lisp/vc/vc-hooks.el
@@ -918,6 +918,7 @@ current, and kill the buffer that visits the link."
(define-key map "c" 'vc-rollback)
(define-key map "d" 'vc-dir)
(define-key map "g" 'vc-annotate)
+ (define-key map "G" 'vc-ignore)
(define-key map "h" 'vc-insert-headers)
(define-key map "i" 'vc-register)
(define-key map "l" 'vc-print-log)
@@ -1002,6 +1003,9 @@ current, and kill the buffer that visits the link."
(bindings--define-key map [vc-register]
'(menu-item "Register" vc-register
:help "Register file set into a version control system"))
+ (bindings--define-key map [vc-ignore]
+ '(menu-item "Ignore File..." vc-ignore
+ :help "Ignore a file under current version control system"))
(bindings--define-key map [vc-dir]
'(menu-item "VC Dir" vc-dir
:help "Show the VC status of files in a directory"))
diff --git a/lisp/whitespace.el b/lisp/whitespace.el
index 801cdc52047..b462cf0b811 100644
--- a/lisp/whitespace.el
+++ b/lisp/whitespace.el
@@ -1471,6 +1471,12 @@ documentation."
;; PROBLEM 6: 8 or more SPACEs after TAB
(whitespace-cleanup-region (point-min) (point-max)))))
+(defun whitespace-ensure-local-variables ()
+ "Set `whitespace-indent-tabs-mode' and `whitespace-tab-width' locally."
+ (set (make-local-variable 'whitespace-indent-tabs-mode)
+ indent-tabs-mode)
+ (set (make-local-variable 'whitespace-tab-width)
+ tab-width))
;;;###autoload
(defun whitespace-cleanup-region (start end)
@@ -1517,6 +1523,7 @@ documentation."
;; read-only buffer
(whitespace-warn-read-only "cleanup region")
;; non-read-only buffer
+ (whitespace-ensure-local-variables)
(let ((rstart (min start end))
(rend (copy-marker (max start end)))
(indent-tabs-mode whitespace-indent-tabs-mode)
@@ -2095,7 +2102,6 @@ resultant list will be returned."
(defvar whitespace-display-table-was-local nil
"Used to remember whether a buffer initially had a local display table.")
-
(defun whitespace-turn-on ()
"Turn on whitespace visualization."
;; prepare local hooks
@@ -2108,10 +2114,7 @@ resultant list will be returned."
(if (listp whitespace-style)
whitespace-style
(list whitespace-style)))
- (set (make-local-variable 'whitespace-indent-tabs-mode)
- indent-tabs-mode)
- (set (make-local-variable 'whitespace-tab-width)
- tab-width)
+ (whitespace-ensure-local-variables)
;; turn on whitespace
(when whitespace-active-style
(whitespace-color-on)
diff --git a/src/ChangeLog b/src/ChangeLog
index bfe4dfaf39a..69e00cadbe9 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,191 @@
+2013-08-03 Paul Eggert <eggert@cs.ucla.edu>
+
+ * composite.h: Minor fixups.
+ (composition_registered_p): Rename from COMPOSITION_REGISTERD_P
+ to fix a misspelling, and change it to an inline function while
+ we're at it (it need not be a macro). All uses changed.
+ (composition_method, composition_valid_p):
+ Rewrite to avoid assignments in if-conditions.
+
+2013-08-03 Dmitry Antipov <dmantipov@yandex.ru>
+
+ Do not use global Lisp_Object in composition macros.
+ * composite.h (composition_temp): Remove declaration.
+ (COMPOSITION_METHOD, COMPOSITION_VALID_P): Replace with...
+ (composition_method, composition_valid_p): ...inline functions.
+ (compose_region): Remove the leftover.
+ * composite.c (composition_temp): Remove.
+ (run_composition_function, update_compositions)
+ (composition_compute_stop_pos, composition_adjust_point)
+ (Ffind_composition_internal):
+ * coding.c (handle_composition_annotation):
+ * xdisp.c (handle_composition_prop, check_point_in_composition):
+ Related users changed.
+
+2013-08-03 Dmitry Antipov <dmantipov@yandex.ru>
+
+ Drop FRAME_PTR typedef.
+ * composite.c, font.c, font.h, fontset.c, fontset.h, frame.c, frame.h:
+ * ftfont.c, ftxfont.c, gtkutil.c, gtkutil.h, image.c, keyboard.c:
+ * menu.c, menu.h, msdos.c, nsfns.m, nsfont.m, nsmenu.m, nsterm.h:
+ * nsterm.m, scroll.c, term.c, w32fns.c, w32font.c, w32font.h:
+ * w32inevt.c, w32inevt.h, w32menu.c, w32notify.c, w32term.c, w32term.h:
+ * w32uniscribe.c, w32xfns.c, widget.c, window.c, xdisp.c, xfaces.c:
+ * xfns.c, xfont.c, xftfont.c, xmenu.c, xselect.c, xterm.c:
+ All related users changed.
+
+2013-08-02 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * eval.c (default_toplevel_binding): New function.
+ (Fdefvar): Use it.
+ (unbind_to, backtrace_eval_unrewind): Do a bit of CSE simplification.
+ (Fdefault_toplevel_value, Fset_default_toplevel_value): New subrs.
+ (syms_of_eval): Export them.
+ * data.c (Fdefault_value): Micro cleanup.
+ * term.c (init_tty): Use "false".
+
+2013-08-02 Dmitry Antipov <dmantipov@yandex.ru>
+
+ Fix X GC leak in GTK and raw (no toolkit) X ports.
+ * xterm.c (x_free_frame_resources): If white and black relief
+ GCs are allocated, always free them here.
+ * xfns.c (x_make_gc): Omit redundant initialization.
+ * widget.c (create_frame_gcs): Remove the leftover.
+ (EmacsFrameDestroy): Do nothing because all GCs are now freed
+ in x_free_frame_resources.
+
+2013-08-02 Jan Djärv <jan.h.d@swipnet.se>
+
+ * nsterm.m (windowWillResize:toSize:): Only change title if
+ ! maximizing_resize && FULLSCREEN_NONE (Bug#15005). strdup title before
+ modifying it.
+ (viewDidEndLiveResize): New method.
+
+ * nsterm.h (EmacsView): Add maximizing_resize, put it and old_title
+ inside NS_IMPL_COCOA.
+
+2013-08-02 Dmitry Antipov <dmantipov@yandex.ru>
+
+ * insdel.c (adjust_after_replace, replace_range, del_range_2):
+ Do not check whether undo is enabled because record_insert and
+ record_delete does that themselves.
+
+2013-08-02 Dmitry Antipov <dmantipov@yandex.ru>
+
+ * xterm.h (struct x_output) [HAVE_X_I18N]: Remove xic_base_fontname
+ member which is not really used any more.
+ (FRAME_XIC_BASE_FONTNAME): Remove.
+ * xfns.c (xic_free_fontset): Adjust user.
+ * xmenu.c (mouse_position_for_popup, x_activate_menubar)
+ (update_frame_menubar, set_frame_menubar, free_frame_menubar)
+ (create_and_show_popup_menu, xmenu_show, create_and_show_dialog)
+ (xdialog_show): Use eassert for debugging check.
+ * w32term.c (x_unfocus_frame): Remove unused dummy function.
+
+2013-08-01 Paul Eggert <eggert@cs.ucla.edu>
+
+ * fileio.c, fns.c (merge): Move extern decl from here ...
+ * lisp.h (merge): ... to here.
+
+2013-08-01 Dmitry Antipov <dmantipov@yandex.ru>
+
+ Fix last font-related change.
+ * w32font.h (w32font_list_internal, w32font_match_internal):
+ Fix prototype.
+ * w32uniscribe.c (uniscribe_list, uniscribe_match):
+ (uniscribe_list_family): Adjust to match font API change.
+ MS-Windows breakage reported by Juanma Barranquero <lekktu@gmail.com>
+ at http://lists.gnu.org/archive/html/emacs-devel/2013-08/msg00006.html.
+
+2013-08-01 Dmitry Antipov <dmantipov@yandex.ru>
+
+ * frame.h (FRAME_MOUSE_UPDATE):
+ * nsterm.m (ns_frame_up_to_date): Omit redundant check
+ whether hlinfo->mouse_face_mouse_frame is non-NULL.
+
+2013-08-01 Dmitry Antipov <dmantipov@yandex.ru>
+
+ Avoid redundant Lisp_Object <-> struct frame conversions in font API.
+ * font.h (struct font_driver): Change list, match, and list_family
+ functions to accept struct frame * as first arg.
+ * font.c (font_score, font_compare, font_sort_entities): Remove
+ prototypes.
+ (font_sort_entities, font_list_entities, font_select_entity):
+ (font_find_for_lface, Flist_fonts, Ffont_family_list): Adjust to
+ match font API change.
+ * xfont.c (xfont_list, xfont_match, xfont_list_family):
+ * ftfont.c (ftfont_list, ftfont_match, ftfont_list_family):
+ * ftxfont.c (ftxfont_list, ftxfont_match):
+ * xftfont.c (xftfont_list, xftfont_match):
+ * nsfont.m (nsfont_list, nsfont_match, nsfont_list_family):
+ * w32font.c (w32font_list, w32font_match, w32font_list):
+ (w32font_list_internal, w32_font_match_internal): Likewise.
+ * xfaces.c (Fx_family_fonts): Adjust user.
+
+2013-08-01 Dmitry Antipov <dmantipov@yandex.ru>
+
+ Do not use pure Xism x_wm_set_icon_position in non-X ports.
+ * frame.c (x_set_frame_parameters): Call to x_wm_set_icon_position
+ only if HAVE_X_WINDOWS is in use.
+ * frame.h (x_set_frame_parameters): Move under HAVE_X_WINDOWS.
+ * nsterm.m (x_wm_set_icon_position): Remove no-op.
+ * w32term.c (x_wm_set_icon_position): Likewise.
+ * w32fns.c (x_icon): Adjust user.
+
+2013-08-01 Dmitry Antipov <dmantipov@yandex.ru>
+
+ * xterm.c (last_mouse_press_frame): Remove the
+ leftover which is not really used any more.
+ (handle_one_xevent, syms_of_xterm): Adjust users.
+ (x_flush): Call XFlush once per each X display, not frame.
+ This is better because this code always unconditionally skips
+ non-X frames in Vframe_list and issues the only XFlush if we
+ have more than one X frame on the same X display.
+ (any_help_event_p, x_draw_glyph_string_background, x_display_ok):
+ Use bool for booleans.
+ (x_draw_glyph_string_background, cvt_string_to_pixel):
+ (cvt_pixel_dtor): Drop unnecessary prototypes.
+ * xterm.h (x_display_ok): Adjust prototype.
+
+2013-07-31 Dmitry Antipov <dmantipov@yandex.ru>
+
+ Drop unnecessary functions that deals with frame pixel size.
+ * frame.h, msdos.h, w32term.h, xterm.h (x_pixel_width)
+ (x_pixel_height): Drop prototypes.
+ * msdos.c, nsfns.m, w32fns.c, xfns.c (x_pixel_width)
+ (x_pixel_height): Drop implementations.
+ * frame.c (Fframe_pixel_height): Use FRAME_PIXEL_HEIGHT
+ which should be always valid for window frame.
+ (Frame_pixel_width): Likewise with FRAME_PIXEL_WIDTH.
+ * w32menu.c (Fx_popup_dialog):
+ * xmenu.c (Fx_popup_dialog): Likewise for both.
+
+2013-07-31 Dmitry Antipov <dmantipov@yandex.ru>
+
+ * frame.c (Fmake_terminal_frame): Use store_in_alist to setup
+ frame parameters and call to Fmodify_frame_parameters just once.
+ (Fset_frame_height, Fset_frame_width): Mention nil frame in docstring.
+ (Fset_frame_size, Fset_frame_position): Use decode_live_frame
+ and mention nil frame in docstring.
+
+2013-07-31 Dmitry Antipov <dmantipov@yandex.ru>
+
+ * frame.c (make_frame, x_set_frame_parameters): Use bool for boolean.
+ (x_figure_window_size): Likewise. Adjust to return long.
+ (syms_of_frame): Do not DEFSYM Qterminal_live_p.
+ (toplevel): Move Qterminal_live_p to...
+ * terminal.c (toplevel): ...here, make it static, and...
+ (syms_of_terminal): ...DEFSYM here.
+ * frame.h (Qterminal_live_p): Remove declaration.
+ (make_frame, x_figure_window_size): Adjust prototype.
+ * nsfns.m (Fx_create_frame): Use long for window flags.
+
+2013-07-30 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix tempfile bug on platforms lacking mkostemp and mkstemp (Bug#14986).
+ * callproc.c (create_temp_file) [! (HAVE_MKOSTEMP || HAVE_MKSTEMP)]:
+ Do not assume that emacs_close (INT_MAX) is a no-op.
+
2013-07-30 Dmitry Antipov <dmantipov@yandex.ru>
* xfaces.c (make_face_cache): For struct face_cache, prefer
@@ -325,7 +513,7 @@
code a bit. It makes no difference on POSIXish platforms but
apparently it fixes a bug on w32.
- Fix bug where insert-file-contents closes a file twice. (Bug#14839).
+ Fix bug where insert-file-contents closes a file twice (Bug#14839).
* fileio.c (close_file_unwind): Don't close if FD is negative;
this can happen when unwinding a zapped file descriptor.
(Finsert_file_contents): Unwind-protect the fd before the point marker,
@@ -478,7 +666,7 @@
(make_lispy_focus_in, make_lispy_focus_out): Declare and define.
(kbd_buffer_get_event): For FOCUS_IN, make a focus_in event if no
switch frame event is made. Check ! NILP (event->arg) if X11 (moved
- from xterm.c). Make focus_out event for FOCUS_OUT_EVENT if NS or X11
+ from xterm.c). Make focus_out event for FOCUS_OUT_EVENT if NS or X11
and there is a focused frame.
(head_table): Add focus-in and focus-out.
(keys_of_keyboard): Add focus-in and focus-out to Vspecial_event_map,
@@ -851,7 +1039,7 @@
(emacswrite_sig, emacs_perror): New functions.
* xrdb.c (fatal): Don't invoke perror, since errno might be garbage.
-2013-07-08 Magnus Henoch <magnus.henoch@gmail.com> (tiny change).
+2013-07-08 Magnus Henoch <magnus.henoch@gmail.com> (tiny change)
* image.c (imagemagick_load_image): Do not use MagickExportImagePixels
on NS even if it is present. Pixmap on NS is a void*.
@@ -1526,7 +1714,7 @@
Now static.
* lisp.h: Remove the abovementioned defns and decls.
- Use functions, not macros, for XINT etc. (Bug#11935).
+ Use functions, not macros, for XINT etc (Bug#11935).
In lisp.h, prefer functions to function-like macros, and
constants to object-like macros, when either will do. This:
. simplifies use, as there's no more need to worry about
diff --git a/src/callproc.c b/src/callproc.c
index 91f29bd589b..450fc57f929 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -1018,13 +1018,14 @@ create_temp_file (ptrdiff_t nargs, Lisp_Object *args)
#else
errno = EEXIST;
mktemp (tempfile);
- /* INT_MAX denotes success, because close (INT_MAX) does nothing. */
- fd = *tempfile ? INT_MAX : -1;
+ fd = *tempfile ? 0 : -1;
#endif
if (fd < 0)
report_file_error ("Failed to open temporary file using pattern",
pattern);
+#if defined HAVE_MKOSTEMP || defined HAVE_MKSTEMP
emacs_close (fd);
+#endif
}
record_unwind_protect (delete_temp_file, filename_string);
diff --git a/src/coding.c b/src/coding.c
index 0cdd8f9cd9e..5b637627763 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -7497,7 +7497,7 @@ handle_composition_annotation (ptrdiff_t pos, ptrdiff_t limit,
/* We found a composition. Store the corresponding
annotation data in BUF. */
int *head = buf;
- enum composition_method method = COMPOSITION_METHOD (prop);
+ enum composition_method method = composition_method (prop);
int nchars = COMPOSITION_LENGTH (prop);
ADD_COMPOSITION_DATA (buf, nchars, 0, method);
diff --git a/src/composite.c b/src/composite.c
index 99b5da22af5..28942fe4f74 100644
--- a/src/composite.c
+++ b/src/composite.c
@@ -160,10 +160,6 @@ static Lisp_Object Qauto_composition_function;
auto-compositions. */
#define MAX_AUTO_COMPOSITION_LOOKBACK 3
-/* Temporary variable used in macros COMPOSITION_XXX. */
-Lisp_Object composition_temp;
-
-
/* Return COMPOSITION-ID of a composition at buffer position
CHARPOS/BYTEPOS and length NCHARS. The `composition' property of
the sequence is PROP. STRING, if non-nil, is a string that
@@ -478,11 +474,11 @@ run_composition_function (ptrdiff_t from, ptrdiff_t to, Lisp_Object prop)
valid too. */
if (from > BEGV
&& find_composition (from - 1, -1, &start, &end, &prop, Qnil)
- && !COMPOSITION_VALID_P (start, end, prop))
+ && !composition_valid_p (start, end, prop))
from = start;
if (to < ZV
&& find_composition (to, -1, &start, &end, &prop, Qnil)
- && !COMPOSITION_VALID_P (start, end, prop))
+ && !composition_valid_p (start, end, prop))
to = end;
if (!NILP (Ffboundp (func)))
call2 (func, make_number (from), make_number (to));
@@ -524,7 +520,7 @@ update_compositions (ptrdiff_t from, ptrdiff_t to, int check_mask)
latter to the copy of it. */
if (from > BEGV
&& find_composition (from - 1, -1, &start, &end, &prop, Qnil)
- && COMPOSITION_VALID_P (start, end, prop))
+ && composition_valid_p (start, end, prop))
{
min_pos = start;
if (end > to)
@@ -538,7 +534,7 @@ update_compositions (ptrdiff_t from, ptrdiff_t to, int check_mask)
}
else if (from < ZV
&& find_composition (from, -1, &start, &from, &prop, Qnil)
- && COMPOSITION_VALID_P (start, from, prop))
+ && composition_valid_p (start, from, prop))
{
if (from > to)
max_pos = from;
@@ -553,7 +549,7 @@ update_compositions (ptrdiff_t from, ptrdiff_t to, int check_mask)
(to - 1). */
while (from < to - 1
&& find_composition (from, to, &start, &from, &prop, Qnil)
- && COMPOSITION_VALID_P (start, from, prop)
+ && composition_valid_p (start, from, prop)
&& from < to - 1)
run_composition_function (start, from, prop);
}
@@ -562,7 +558,7 @@ update_compositions (ptrdiff_t from, ptrdiff_t to, int check_mask)
{
if (from < to
&& find_composition (to - 1, -1, &start, &end, &prop, Qnil)
- && COMPOSITION_VALID_P (start, end, prop))
+ && composition_valid_p (start, end, prop))
{
/* TO should be also at composition boundary. But,
insertion or deletion will make two compositions adjacent
@@ -580,7 +576,7 @@ update_compositions (ptrdiff_t from, ptrdiff_t to, int check_mask)
}
else if (to < ZV
&& find_composition (to, -1, &start, &end, &prop, Qnil)
- && COMPOSITION_VALID_P (start, end, prop))
+ && composition_valid_p (start, end, prop))
{
run_composition_function (start, end, prop);
max_pos = end;
@@ -901,7 +897,7 @@ autocmp_chars (Lisp_Object rule, ptrdiff_t charpos, ptrdiff_t bytepos,
Lisp_Object string)
{
ptrdiff_t count = SPECPDL_INDEX ();
- FRAME_PTR f = XFRAME (win->frame);
+ struct frame *f = XFRAME (win->frame);
Lisp_Object pos = make_number (charpos);
ptrdiff_t to;
ptrdiff_t pt = PT, pt_byte = PT_BYTE;
@@ -1012,7 +1008,7 @@ composition_compute_stop_pos (struct composition_it *cmp_it, ptrdiff_t charpos,
if (charpos < endpos
&& find_composition (charpos, endpos, &start, &end, &prop, string)
&& start >= charpos
- && COMPOSITION_VALID_P (start, end, prop))
+ && composition_valid_p (start, end, prop))
{
cmp_it->stop_pos = endpos = start;
cmp_it->ch = -1;
@@ -1672,7 +1668,7 @@ composition_adjust_point (ptrdiff_t last_pt, ptrdiff_t new_pt)
/* At first check the static composition. */
if (get_property_and_range (new_pt, Qcomposition, &val, &beg, &end, Qnil)
- && COMPOSITION_VALID_P (beg, end, val))
+ && composition_valid_p (beg, end, val))
{
if (beg < new_pt /* && end > new_pt <- It's always the case. */
&& (last_pt <= beg || last_pt >= end))
@@ -1872,12 +1868,12 @@ See `find-composition' for more details. */)
&& (e <= XINT (pos) ? e > end : s < start))
return list3 (make_number (s), make_number (e), gstring);
}
- if (!COMPOSITION_VALID_P (start, end, prop))
+ if (!composition_valid_p (start, end, prop))
return list3 (make_number (start), make_number (end), Qnil);
if (NILP (detail_p))
return list3 (make_number (start), make_number (end), Qt);
- if (COMPOSITION_REGISTERD_P (prop))
+ if (composition_registered_p (prop))
id = COMPOSITION_ID (prop);
else
{
@@ -1890,7 +1886,7 @@ See `find-composition' for more details. */)
if (id >= 0)
{
Lisp_Object components, relative_p, mod_func;
- enum composition_method method = COMPOSITION_METHOD (prop);
+ enum composition_method method = composition_method (prop);
int width = composition_table[id]->width;
components = Fcopy_sequence (COMPOSITION_COMPONENTS (prop));
diff --git a/src/composite.h b/src/composite.h
index 603291044bc..53665b36bd1 100644
--- a/src/composite.h
+++ b/src/composite.h
@@ -49,69 +49,41 @@ enum composition_method {
/* Maximum number of components a single composition can have. */
#define MAX_COMPOSITION_COMPONENTS 16
-/* These macros access information about a composition that
+/* These operations access information about a composition that
has `composition' property PROP. PROP is:
((LENGTH . COMPONENTS) . MODIFICATION-FUNC)
or
(COMPOSITION-ID . (LENGTH COMPONENTS . MODIFICATION-FUNC))
They don't check validity of PROP. */
-/* Temporary variable used only in the following macros. */
-extern Lisp_Object composition_temp;
-
-/* Return 1 if the composition is already registered. */
-#define COMPOSITION_REGISTERD_P(prop) INTEGERP (XCAR (prop))
+/* Return true if PROP is already registered. */
+COMPOSITE_INLINE bool
+composition_registered_p (Lisp_Object prop)
+{
+ return INTEGERP (XCAR (prop));
+}
/* Return ID number of the already registered composition. */
#define COMPOSITION_ID(prop) XINT (XCAR (prop))
/* Return length of the composition. */
#define COMPOSITION_LENGTH(prop) \
- (COMPOSITION_REGISTERD_P (prop) \
+ (composition_registered_p (prop) \
? XINT (XCAR (XCDR (prop))) \
: XINT (XCAR (XCAR (prop))))
/* Return components of the composition. */
#define COMPOSITION_COMPONENTS(prop) \
- (COMPOSITION_REGISTERD_P (prop) \
+ (composition_registered_p (prop) \
? XCAR (XCDR (XCDR (prop))) \
: XCDR (XCAR (prop)))
/* Return modification function of the composition. */
#define COMPOSITION_MODIFICATION_FUNC(prop) \
- (COMPOSITION_REGISTERD_P (prop) \
+ (composition_registered_p (prop) \
? XCDR (XCDR (XCDR (prop))) \
: CONSP (prop) ? XCDR (prop) : Qnil)
-/* Return the method of composition. */
-#define COMPOSITION_METHOD(prop) \
- (COMPOSITION_REGISTERD_P (prop) \
- ? composition_table[COMPOSITION_ID (prop)]->method \
- : (composition_temp = XCDR (XCAR (prop)), \
- (NILP (composition_temp) \
- ? COMPOSITION_RELATIVE \
- : (INTEGERP (composition_temp) || STRINGP (composition_temp)) \
- ? COMPOSITION_WITH_ALTCHARS \
- : COMPOSITION_WITH_RULE_ALTCHARS)))
-
-/* Return 1 if the composition is valid. It is valid if length of
- the composition equals to (END - START). */
-#define COMPOSITION_VALID_P(start, end, prop) \
- (CONSP (prop) \
- && (COMPOSITION_REGISTERD_P (prop) \
- ? (COMPOSITION_ID (prop) >= 0 \
- && COMPOSITION_ID (prop) <= n_compositions \
- && CONSP (XCDR (prop))) \
- : (composition_temp = XCAR (prop), \
- (CONSP (composition_temp) \
- && (composition_temp = XCDR (composition_temp), \
- (NILP (composition_temp) \
- || STRINGP (composition_temp) \
- || VECTORP (composition_temp) \
- || INTEGERP (composition_temp) \
- || CONSP (composition_temp)))))) \
- && (end - start) == COMPOSITION_LENGTH (prop))
-
/* Return the Nth glyph of composition specified by CMP. CMP is a
pointer to `struct composition'. */
#define COMPOSITION_GLYPH(cmp, n) \
@@ -227,12 +199,48 @@ extern bool find_composition (ptrdiff_t, ptrdiff_t, ptrdiff_t *, ptrdiff_t *,
Lisp_Object *, Lisp_Object);
extern void update_compositions (ptrdiff_t, ptrdiff_t, int);
extern void make_composition_value_copy (Lisp_Object);
-extern void compose_region (int, int, Lisp_Object, Lisp_Object,
- Lisp_Object);
extern void syms_of_composite (void);
extern void compose_text (ptrdiff_t, ptrdiff_t, Lisp_Object, Lisp_Object,
Lisp_Object);
+/* Return the method of a composition with property PROP. */
+
+COMPOSITE_INLINE enum composition_method
+composition_method (Lisp_Object prop)
+{
+ if (composition_registered_p (prop))
+ return composition_table[COMPOSITION_ID (prop)]->method;
+ else
+ {
+ Lisp_Object temp = XCDR (XCAR (prop));
+ return (NILP (temp)
+ ? COMPOSITION_RELATIVE
+ : INTEGERP (temp) || STRINGP (temp)
+ ? COMPOSITION_WITH_ALTCHARS
+ : COMPOSITION_WITH_RULE_ALTCHARS);
+ }
+}
+
+/* Given offsets START and END, return true if PROP is a valid composition
+ property with length END - START. */
+
+COMPOSITE_INLINE bool
+composition_valid_p (ptrdiff_t start, ptrdiff_t end, Lisp_Object prop)
+{
+ return (CONSP (prop)
+ && (composition_registered_p (prop)
+ ? (COMPOSITION_ID (prop) >= 0
+ && COMPOSITION_ID (prop) <= n_compositions
+ && CONSP (XCDR (prop)))
+ : (CONSP (XCAR (prop))
+ && (NILP (XCDR (XCAR (prop)))
+ || STRINGP (XCDR (XCAR (prop)))
+ || VECTORP (XCDR (XCAR (prop)))
+ || INTEGERP (XCDR (XCAR (prop)))
+ || CONSP (XCDR (XCAR (prop))))))
+ && COMPOSITION_LENGTH (prop) == end - start);
+}
+
/* Macros for lispy glyph-string. This is completely different from
struct glyph_string. */
diff --git a/src/data.c b/src/data.c
index f04d6da618f..d1e43ac1b5f 100644
--- a/src/data.c
+++ b/src/data.c
@@ -1384,9 +1384,7 @@ for this variable. The default value is meaningful for variables with
local bindings in certain buffers. */)
(Lisp_Object symbol)
{
- register Lisp_Object value;
-
- value = default_value (symbol);
+ Lisp_Object value = default_value (symbol);
if (!EQ (value, Qunbound))
return value;
diff --git a/src/eval.c b/src/eval.c
index cb716690e3c..8ee259110f4 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -658,6 +658,51 @@ The return value is BASE-VARIABLE. */)
return base_variable;
}
+static union specbinding *
+default_toplevel_binding (Lisp_Object symbol)
+{
+ union specbinding *binding = NULL;
+ union specbinding *pdl = specpdl_ptr;
+ while (pdl > specpdl)
+ {
+ switch ((--pdl)->kind)
+ {
+ case SPECPDL_LET_DEFAULT:
+ case SPECPDL_LET:
+ if (EQ (specpdl_symbol (pdl), symbol))
+ binding = pdl;
+ break;
+ }
+ }
+ return binding;
+}
+
+DEFUN ("default-toplevel-value", Fdefault_toplevel_value, Sdefault_toplevel_value, 1, 1, 0,
+ doc: /* Return SYMBOL's toplevel default value.
+"Toplevel" means outside of any let binding. */)
+ (Lisp_Object symbol)
+{
+ union specbinding *binding = default_toplevel_binding (symbol);
+ Lisp_Object value
+ = binding ? specpdl_old_value (binding) : Fdefault_value (symbol);
+ if (!EQ (value, Qunbound))
+ return value;
+ xsignal1 (Qvoid_variable, symbol);
+}
+
+DEFUN ("set-default-toplevel-value", Fset_default_toplevel_value,
+ Sset_default_toplevel_value, 2, 2, 0,
+ doc: /* Set SYMBOL's toplevel default value to VALUE.
+"Toplevel" means outside of any let binding. */)
+ (Lisp_Object symbol, Lisp_Object value)
+{
+ union specbinding *binding = default_toplevel_binding (symbol);
+ if (binding)
+ set_specpdl_old_value (binding, value);
+ else
+ Fset_default (symbol, value);
+ return Qnil;
+}
DEFUN ("defvar", Fdefvar, Sdefvar, 1, UNEVALLED, 0,
doc: /* Define SYMBOL as a variable, and return SYMBOL.
@@ -706,18 +751,10 @@ usage: (defvar SYMBOL &optional INITVALUE DOCSTRING) */)
else
{ /* Check if there is really a global binding rather than just a let
binding that shadows the global unboundness of the var. */
- union specbinding *pdl = specpdl_ptr;
- while (pdl > specpdl)
+ union specbinding *binding = default_toplevel_binding (sym);
+ if (binding && EQ (specpdl_old_value (binding), Qunbound))
{
- if ((--pdl)->kind >= SPECPDL_LET
- && EQ (specpdl_symbol (pdl), sym)
- && EQ (specpdl_old_value (pdl), Qunbound))
- {
- message_with_string
- ("Warning: defvar ignored because %s is let-bound",
- SYMBOL_NAME (sym), 1);
- break;
- }
+ set_specpdl_old_value (binding, eval_sub (XCAR (tail)));
}
}
tail = XCDR (tail);
@@ -3311,19 +3348,21 @@ unbind_to (ptrdiff_t count, Lisp_Object value)
case SPECPDL_BACKTRACE:
break;
case SPECPDL_LET:
- /* If variable has a trivial value (no forwarding), we can
- just set it. No need to check for constant symbols here,
- since that was already done by specbind. */
- if (XSYMBOL (specpdl_symbol (specpdl_ptr))->redirect
- == SYMBOL_PLAINVAL)
- SET_SYMBOL_VAL (XSYMBOL (specpdl_symbol (specpdl_ptr)),
- specpdl_old_value (specpdl_ptr));
- else
- /* NOTE: we only ever come here if make_local_foo was used for
- the first time on this var within this let. */
- Fset_default (specpdl_symbol (specpdl_ptr),
- specpdl_old_value (specpdl_ptr));
- break;
+ { /* If variable has a trivial value (no forwarding), we can
+ just set it. No need to check for constant symbols here,
+ since that was already done by specbind. */
+ struct Lisp_Symbol *sym = XSYMBOL (specpdl_symbol (specpdl_ptr));
+ if (sym->redirect == SYMBOL_PLAINVAL)
+ {
+ SET_SYMBOL_VAL (sym, specpdl_old_value (specpdl_ptr));
+ break;
+ }
+ else
+ { /* FALLTHROUGH!!
+ NOTE: we only ever come here if make_local_foo was used for
+ the first time on this var within this let. */
+ }
+ }
case SPECPDL_LET_DEFAULT:
Fset_default (specpdl_symbol (specpdl_ptr),
specpdl_old_value (specpdl_ptr));
@@ -3511,24 +3550,23 @@ backtrace_eval_unrewind (int distance)
case SPECPDL_BACKTRACE:
break;
case SPECPDL_LET:
- /* If variable has a trivial value (no forwarding), we can
- just set it. No need to check for constant symbols here,
- since that was already done by specbind. */
- if (XSYMBOL (specpdl_symbol (tmp))->redirect
- == SYMBOL_PLAINVAL)
- {
- struct Lisp_Symbol *sym = XSYMBOL (specpdl_symbol (tmp));
- Lisp_Object old_value = specpdl_old_value (tmp);
- set_specpdl_old_value (tmp, SYMBOL_VAL (sym));
- SET_SYMBOL_VAL (sym, old_value);
- break;
- }
- else
- {
- /* FALLTHROUGH!
- NOTE: we only ever come here if make_local_foo was used for
- the first time on this var within this let. */
- }
+ { /* If variable has a trivial value (no forwarding), we can
+ just set it. No need to check for constant symbols here,
+ since that was already done by specbind. */
+ struct Lisp_Symbol *sym = XSYMBOL (specpdl_symbol (tmp));
+ if (sym->redirect == SYMBOL_PLAINVAL)
+ {
+ Lisp_Object old_value = specpdl_old_value (tmp);
+ set_specpdl_old_value (tmp, SYMBOL_VAL (sym));
+ SET_SYMBOL_VAL (sym, old_value);
+ break;
+ }
+ else
+ { /* FALLTHROUGH!!
+ NOTE: we only ever come here if make_local_foo was used for
+ the first time on this var within this let. */
+ }
+ }
case SPECPDL_LET_DEFAULT:
{
Lisp_Object sym = specpdl_symbol (tmp);
@@ -3796,6 +3834,8 @@ alist of active lexical bindings. */);
defsubr (&Ssetq);
defsubr (&Squote);
defsubr (&Sfunction);
+ defsubr (&Sdefault_toplevel_value);
+ defsubr (&Sset_default_toplevel_value);
defsubr (&Sdefvar);
defsubr (&Sdefvaralias);
defsubr (&Sdefconst);
diff --git a/src/fileio.c b/src/fileio.c
index c47b3533145..59e84053773 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -5096,8 +5096,6 @@ This calls `write-region-annotate-functions' at the start, and
return Qnil;
}
-Lisp_Object merge (Lisp_Object, Lisp_Object, Lisp_Object);
-
DEFUN ("car-less-than-car", Fcar_less_than_car, Scar_less_than_car, 2, 2, 0,
doc: /* Return t if (car A) is numerically less than (car B). */)
(Lisp_Object a, Lisp_Object b)
diff --git a/src/fns.c b/src/fns.c
index 6f81635ab9d..de90fd731fb 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -1738,8 +1738,6 @@ See also the function `nreverse', which is used more often. */)
return new;
}
-Lisp_Object merge (Lisp_Object org_l1, Lisp_Object org_l2, Lisp_Object pred);
-
DEFUN ("sort", Fsort, Ssort, 2, 2, 0,
doc: /* Sort LIST, stably, comparing elements using PREDICATE.
Returns the sorted list. LIST is modified by side effects.
diff --git a/src/font.c b/src/font.c
index 124d5f9bd9e..073487b540d 100644
--- a/src/font.c
+++ b/src/font.c
@@ -204,9 +204,9 @@ font_make_object (int size, Lisp_Object entity, int pixelsize)
-static int font_pixel_size (FRAME_PTR f, Lisp_Object);
-static Lisp_Object font_open_entity (FRAME_PTR, Lisp_Object, int);
-static Lisp_Object font_matching_entity (FRAME_PTR, Lisp_Object *,
+static int font_pixel_size (struct frame *f, Lisp_Object);
+static Lisp_Object font_open_entity (struct frame *, Lisp_Object, int);
+static Lisp_Object font_matching_entity (struct frame *, Lisp_Object *,
Lisp_Object);
static unsigned font_encode_char (Lisp_Object, int);
@@ -269,7 +269,7 @@ font_intern_prop (const char *str, ptrdiff_t len, bool force_symbol)
/* Return a pixel size of font-spec SPEC on frame F. */
static int
-font_pixel_size (FRAME_PTR f, Lisp_Object spec)
+font_pixel_size (struct frame *f, Lisp_Object spec)
{
#ifdef HAVE_WINDOW_SYSTEM
Lisp_Object size = AREF (spec, FONT_SIZE_INDEX);
@@ -2037,11 +2037,6 @@ font_otf_Anchor (OTF_Anchor *anchor)
/* Font sorting. */
-static unsigned font_score (Lisp_Object, Lisp_Object *);
-static int font_compare (const void *, const void *);
-static Lisp_Object font_sort_entities (Lisp_Object, Lisp_Object,
- Lisp_Object, int);
-
static double
font_rescale_ratio (Lisp_Object font_entity)
{
@@ -2186,14 +2181,14 @@ font_compare (const void *d1, const void *d2)
such a case. */
static Lisp_Object
-font_sort_entities (Lisp_Object list, Lisp_Object prefer, Lisp_Object frame, int best_only)
+font_sort_entities (Lisp_Object list, Lisp_Object prefer,
+ struct frame *f, int best_only)
{
Lisp_Object prefer_prop[FONT_SPEC_MAX];
int len, maxlen, i;
struct font_sort_data *data;
unsigned best_score;
Lisp_Object best_entity;
- struct frame *f = XFRAME (frame);
Lisp_Object tail, vec IF_LINT (= Qnil);
USE_SAFE_ALLOCA;
@@ -2201,7 +2196,7 @@ font_sort_entities (Lisp_Object list, Lisp_Object prefer, Lisp_Object frame, int
prefer_prop[i] = AREF (prefer, i);
if (FLOATP (prefer_prop[FONT_SIZE_INDEX]))
prefer_prop[FONT_SIZE_INDEX]
- = make_number (font_pixel_size (XFRAME (frame), prefer));
+ = make_number (font_pixel_size (f, prefer));
if (NILP (XCDR (list)))
{
@@ -2502,14 +2497,14 @@ font_match_p (Lisp_Object spec, Lisp_Object font)
is a number frames sharing this cache, and FONT-CACHE-DATA is a
cons (FONT-SPEC FONT-ENTITY ...). */
-static void font_prepare_cache (FRAME_PTR, struct font_driver *);
-static void font_finish_cache (FRAME_PTR, struct font_driver *);
-static Lisp_Object font_get_cache (FRAME_PTR, struct font_driver *);
-static void font_clear_cache (FRAME_PTR, Lisp_Object,
+static void font_prepare_cache (struct frame *, struct font_driver *);
+static void font_finish_cache (struct frame *, struct font_driver *);
+static Lisp_Object font_get_cache (struct frame *, struct font_driver *);
+static void font_clear_cache (struct frame *, Lisp_Object,
struct font_driver *);
static void
-font_prepare_cache (FRAME_PTR f, struct font_driver *driver)
+font_prepare_cache (struct frame *f, struct font_driver *driver)
{
Lisp_Object cache, val;
@@ -2531,7 +2526,7 @@ font_prepare_cache (FRAME_PTR f, struct font_driver *driver)
static void
-font_finish_cache (FRAME_PTR f, struct font_driver *driver)
+font_finish_cache (struct frame *f, struct font_driver *driver)
{
Lisp_Object cache, val, tmp;
@@ -2552,7 +2547,7 @@ font_finish_cache (FRAME_PTR f, struct font_driver *driver)
static Lisp_Object
-font_get_cache (FRAME_PTR f, struct font_driver *driver)
+font_get_cache (struct frame *f, struct font_driver *driver)
{
Lisp_Object val = driver->get_cache (f);
Lisp_Object type = driver->type;
@@ -2567,7 +2562,7 @@ font_get_cache (FRAME_PTR f, struct font_driver *driver)
static void
-font_clear_cache (FRAME_PTR f, Lisp_Object cache, struct font_driver *driver)
+font_clear_cache (struct frame *f, Lisp_Object cache, struct font_driver *driver)
{
Lisp_Object tail, elt;
Lisp_Object tail2, entity;
@@ -2692,9 +2687,8 @@ font_delete_unmatched (Lisp_Object vec, Lisp_Object spec, int size)
same font-driver. */
Lisp_Object
-font_list_entities (Lisp_Object frame, Lisp_Object spec)
+font_list_entities (struct frame *f, Lisp_Object spec)
{
- FRAME_PTR f = XFRAME (frame);
struct font_driver_list *driver_list = f->font_driver_list;
Lisp_Object ftype, val;
Lisp_Object list = Qnil;
@@ -2738,7 +2732,7 @@ font_list_entities (Lisp_Object frame, Lisp_Object spec)
{
Lisp_Object copy;
- val = driver_list->driver->list (frame, scratch_font_spec);
+ val = driver_list->driver->list (f, scratch_font_spec);
if (NILP (val))
val = zero_vector;
else
@@ -2766,14 +2760,12 @@ font_list_entities (Lisp_Object frame, Lisp_Object spec)
font-related attributes. */
static Lisp_Object
-font_matching_entity (FRAME_PTR f, Lisp_Object *attrs, Lisp_Object spec)
+font_matching_entity (struct frame *f, Lisp_Object *attrs, Lisp_Object spec)
{
struct font_driver_list *driver_list = f->font_driver_list;
Lisp_Object ftype, size, entity;
- Lisp_Object frame;
Lisp_Object work = copy_font_spec (spec);
- XSETFRAME (frame, f);
ftype = AREF (spec, FONT_TYPE_INDEX);
size = AREF (spec, FONT_SIZE_INDEX);
@@ -2797,7 +2789,7 @@ font_matching_entity (FRAME_PTR f, Lisp_Object *attrs, Lisp_Object spec)
entity = XCDR (entity);
else
{
- entity = driver_list->driver->match (frame, work);
+ entity = driver_list->driver->match (f, work);
copy = copy_font_spec (work);
ASET (copy, FONT_TYPE_INDEX, driver_list->driver->type);
XSETCDR (cache, Fcons (Fcons (copy, entity), XCDR (cache)));
@@ -2814,7 +2806,7 @@ font_matching_entity (FRAME_PTR f, Lisp_Object *attrs, Lisp_Object spec)
opened font object. */
static Lisp_Object
-font_open_entity (FRAME_PTR f, Lisp_Object entity, int pixel_size)
+font_open_entity (struct frame *f, Lisp_Object entity, int pixel_size)
{
struct font_driver_list *driver_list;
Lisp_Object objlist, size, val, font_object;
@@ -2892,7 +2884,7 @@ font_open_entity (FRAME_PTR f, Lisp_Object entity, int pixel_size)
/* Close FONT_OBJECT that is opened on frame F. */
static void
-font_close_object (FRAME_PTR f, Lisp_Object font_object)
+font_close_object (struct frame *f, Lisp_Object font_object)
{
struct font *font = XFONT_OBJECT (font_object);
@@ -2912,7 +2904,7 @@ font_close_object (FRAME_PTR f, Lisp_Object font_object)
FONT is a font-entity and it must be opened to check. */
int
-font_has_char (FRAME_PTR f, Lisp_Object font, int c)
+font_has_char (struct frame *f, Lisp_Object font, int c)
{
struct font *fontp;
@@ -3039,12 +3031,12 @@ font_clear_prop (Lisp_Object *attrs, enum font_property_index prop)
supports C and is the best match for ATTRS and PIXEL_SIZE. */
static Lisp_Object
-font_select_entity (Lisp_Object frame, Lisp_Object entities, Lisp_Object *attrs, int pixel_size, int c)
+font_select_entity (struct frame *f, Lisp_Object entities,
+ Lisp_Object *attrs, int pixel_size, int c)
{
Lisp_Object font_entity;
Lisp_Object prefer;
int i;
- FRAME_PTR f = XFRAME (frame);
if (NILP (XCDR (entities))
&& ASIZE (XCAR (entities)) == 1)
@@ -3075,7 +3067,7 @@ font_select_entity (Lisp_Object frame, Lisp_Object entities, Lisp_Object *attrs,
FONT_SET_STYLE (prefer, FONT_WIDTH_INDEX, attrs[LFACE_SWIDTH_INDEX]);
ASET (prefer, FONT_SIZE_INDEX, make_number (pixel_size));
- return font_sort_entities (entities, prefer, frame, c);
+ return font_sort_entities (entities, prefer, f, c);
}
/* Return a font-entity that satisfies SPEC and is the best match for
@@ -3083,10 +3075,10 @@ font_select_entity (Lisp_Object frame, Lisp_Object entities, Lisp_Object *attrs,
character that the entity must support. */
Lisp_Object
-font_find_for_lface (FRAME_PTR f, Lisp_Object *attrs, Lisp_Object spec, int c)
+font_find_for_lface (struct frame *f, Lisp_Object *attrs, Lisp_Object spec, int c)
{
Lisp_Object work;
- Lisp_Object frame, entities, val;
+ Lisp_Object entities, val;
Lisp_Object foundry[3], *family, registry[3], adstyle[3];
int pixel_size;
int i, j, k, l;
@@ -3118,7 +3110,6 @@ font_find_for_lface (FRAME_PTR f, Lisp_Object *attrs, Lisp_Object spec, int c)
work = copy_font_spec (spec);
ASET (work, FONT_TYPE_INDEX, AREF (spec, FONT_TYPE_INDEX));
- XSETFRAME (frame, f);
pixel_size = font_pixel_size (f, spec);
if (pixel_size == 0 && INTEGERP (attrs[LFACE_HEIGHT_INDEX]))
{
@@ -3212,10 +3203,10 @@ font_find_for_lface (FRAME_PTR f, Lisp_Object *attrs, Lisp_Object spec, int c)
for (l = 0; SYMBOLP (adstyle[l]); l++)
{
ASET (work, FONT_ADSTYLE_INDEX, adstyle[l]);
- entities = font_list_entities (frame, work);
+ entities = font_list_entities (f, work);
if (! NILP (entities))
{
- val = font_select_entity (frame, entities,
+ val = font_select_entity (f, entities,
attrs, pixel_size, c);
if (! NILP (val))
return val;
@@ -3231,7 +3222,7 @@ font_find_for_lface (FRAME_PTR f, Lisp_Object *attrs, Lisp_Object spec, int c)
Lisp_Object
-font_open_for_lface (FRAME_PTR f, Lisp_Object entity, Lisp_Object *attrs, Lisp_Object spec)
+font_open_for_lface (struct frame *f, Lisp_Object entity, Lisp_Object *attrs, Lisp_Object spec)
{
int size;
@@ -3278,7 +3269,7 @@ font_open_for_lface (FRAME_PTR f, Lisp_Object entity, Lisp_Object *attrs, Lisp_O
font-object. */
Lisp_Object
-font_load_for_lface (FRAME_PTR f, Lisp_Object *attrs, Lisp_Object spec)
+font_load_for_lface (struct frame *f, Lisp_Object *attrs, Lisp_Object spec)
{
Lisp_Object entity, name;
@@ -3307,7 +3298,7 @@ font_load_for_lface (FRAME_PTR f, Lisp_Object *attrs, Lisp_Object spec)
/* Make FACE on frame F ready to use the font opened for FACE. */
void
-font_prepare_for_face (FRAME_PTR f, struct face *face)
+font_prepare_for_face (struct frame *f, struct face *face)
{
if (face->font->driver->prepare_face)
face->font->driver->prepare_face (f, face);
@@ -3317,7 +3308,7 @@ font_prepare_for_face (FRAME_PTR f, struct face *face)
/* Make FACE on frame F stop using the font opened for FACE. */
void
-font_done_for_face (FRAME_PTR f, struct face *face)
+font_done_for_face (struct frame *f, struct face *face)
{
if (face->font->driver->done_face)
face->font->driver->done_face (f, face);
@@ -3329,7 +3320,7 @@ font_done_for_face (FRAME_PTR f, struct face *face)
font is found, return Qnil. */
Lisp_Object
-font_open_by_spec (FRAME_PTR f, Lisp_Object spec)
+font_open_by_spec (struct frame *f, Lisp_Object spec)
{
Lisp_Object attrs[LFACE_VECTOR_SIZE];
@@ -3353,7 +3344,7 @@ font_open_by_spec (FRAME_PTR f, Lisp_Object spec)
found, return Qnil. */
Lisp_Object
-font_open_by_name (FRAME_PTR f, Lisp_Object name)
+font_open_by_name (struct frame *f, Lisp_Object name)
{
Lisp_Object args[2];
Lisp_Object spec, ret;
@@ -3383,7 +3374,7 @@ font_open_by_name (FRAME_PTR f, Lisp_Object name)
(e.g. syms_of_xfont). */
void
-register_font_driver (struct font_driver *driver, FRAME_PTR f)
+register_font_driver (struct font_driver *driver, struct frame *f)
{
struct font_driver_list *root = f ? f->font_driver_list : font_driver_list;
struct font_driver_list *prev, *list;
@@ -3411,7 +3402,7 @@ register_font_driver (struct font_driver *driver, FRAME_PTR f)
}
void
-free_font_driver_list (FRAME_PTR f)
+free_font_driver_list (struct frame *f)
{
struct font_driver_list *list, *next;
@@ -3433,7 +3424,7 @@ free_font_driver_list (FRAME_PTR f)
F. */
Lisp_Object
-font_update_drivers (FRAME_PTR f, Lisp_Object new_drivers)
+font_update_drivers (struct frame *f, Lisp_Object new_drivers)
{
Lisp_Object active_drivers = Qnil;
struct font_driver_list *list;
@@ -3522,7 +3513,7 @@ font_update_drivers (FRAME_PTR f, Lisp_Object new_drivers)
}
int
-font_put_frame_data (FRAME_PTR f, struct font_driver *driver, void *data)
+font_put_frame_data (struct frame *f, struct font_driver *driver, void *data)
{
struct font_data_list *list, *prev;
@@ -3556,7 +3547,7 @@ font_put_frame_data (FRAME_PTR f, struct font_driver *driver, void *data)
void *
-font_get_frame_data (FRAME_PTR f, struct font_driver *driver)
+font_get_frame_data (struct frame *f, struct font_driver *driver)
{
struct font_data_list *list;
@@ -3630,7 +3621,7 @@ static Lisp_Object
font_at (int c, ptrdiff_t pos, struct face *face, struct window *w,
Lisp_Object string)
{
- FRAME_PTR f;
+ struct frame *f;
bool multibyte;
Lisp_Object font_object;
@@ -4110,12 +4101,10 @@ control the order of the returned list. Fonts are sorted by
how close they are to PREFER. */)
(Lisp_Object font_spec, Lisp_Object frame, Lisp_Object num, Lisp_Object prefer)
{
+ struct frame *f = decode_live_frame (frame);
Lisp_Object vec, list;
EMACS_INT n = 0;
- if (NILP (frame))
- frame = selected_frame;
- CHECK_LIVE_FRAME (frame);
CHECK_FONT_SPEC (font_spec);
if (! NILP (num))
{
@@ -4127,7 +4116,7 @@ how close they are to PREFER. */)
if (! NILP (prefer))
CHECK_FONT_SPEC (prefer);
- list = font_list_entities (frame, font_spec);
+ list = font_list_entities (f, font_spec);
if (NILP (list))
return Qnil;
if (NILP (XCDR (list))
@@ -4135,7 +4124,7 @@ how close they are to PREFER. */)
return list1 (AREF (XCAR (list), 0));
if (! NILP (prefer))
- vec = font_sort_entities (list, prefer, frame, 0);
+ vec = font_sort_entities (list, prefer, f, 0);
else
vec = font_vconcat_entity_vectors (list);
if (n == 0 || n >= ASIZE (vec))
@@ -4163,13 +4152,11 @@ If FRAME is omitted or nil, the selected frame is used. */)
struct font_driver_list *driver_list;
Lisp_Object list = Qnil;
- XSETFRAME (frame, f);
-
for (driver_list = f->font_driver_list; driver_list;
driver_list = driver_list->next)
if (driver_list->driver->list_family)
{
- Lisp_Object val = driver_list->driver->list_family (frame);
+ Lisp_Object val = driver_list->driver->list_family (f);
Lisp_Object tail = list;
for (; CONSP (val); val = XCDR (val))
@@ -4247,7 +4234,7 @@ DEFUN ("clear-font-cache", Fclear_font_cache, Sclear_font_cache, 0, 0, 0,
FOR_EACH_FRAME (list, frame)
{
- FRAME_PTR f = XFRAME (frame);
+ struct frame *f = XFRAME (frame);
struct font_driver_list *driver_list = f->font_driver_list;
for (; driver_list; driver_list = driver_list->next)
@@ -4795,7 +4782,7 @@ Type C-l to recover what previously shown. */)
(Lisp_Object font_object, Lisp_Object string)
{
Lisp_Object frame = selected_frame;
- FRAME_PTR f = XFRAME (frame);
+ struct frame *f = XFRAME (frame);
struct font *font;
struct face *face;
int i, len, width;
diff --git a/src/font.h b/src/font.h
index ffed0461ff7..daeb320c1ab 100644
--- a/src/font.h
+++ b/src/font.h
@@ -504,7 +504,7 @@ struct font_driver
/* Return a cache of font-entities on frame F. The cache must be a
cons whose cdr part is the actual cache area. */
- Lisp_Object (*get_cache) (FRAME_PTR F);
+ Lisp_Object (*get_cache) (struct frame *f);
/* List fonts exactly matching with FONT_SPEC on FRAME. The value
is a list of font-entities. The font properties to be considered
@@ -527,7 +527,7 @@ struct font_driver
This and the following `match' are the only APIs that allocate
font-entities. */
- Lisp_Object (*list) (Lisp_Object frame, Lisp_Object font_spec);
+ Lisp_Object (*list) (struct frame *frame, Lisp_Object font_spec);
/* Return a font-entity most closely matching with FONT_SPEC on
FRAME. Which font property to consider, and how to calculate the
@@ -536,12 +536,12 @@ struct font_driver
The properties that the font-entity has is the same as `list'
method. */
- Lisp_Object (*match) (Lisp_Object frame, Lisp_Object font_spec);
+ Lisp_Object (*match) (struct frame *f, Lisp_Object spec);
/* Optional.
List available families. The value is a list of family names
(symbols). */
- Lisp_Object (*list_family) (Lisp_Object frame);
+ Lisp_Object (*list_family) (struct frame *f);
/* Optional (if FONT_EXTRA_INDEX is not Lisp_Save_Value).
Free FONT_EXTRA_INDEX field of FONT_ENTITY. */
@@ -549,21 +549,21 @@ struct font_driver
/* Open a font specified by FONT_ENTITY on frame F. If the font is
scalable, open it with PIXEL_SIZE. */
- Lisp_Object (*open) (FRAME_PTR f, Lisp_Object font_entity,
+ Lisp_Object (*open) (struct frame *f, Lisp_Object font_entity,
int pixel_size);
/* Close FONT on frame F. */
- void (*close) (FRAME_PTR f, struct font *font);
+ void (*close) (struct frame *f, struct font *font);
/* Optional (if FACE->extra is not used).
Prepare FACE for displaying characters by FONT on frame F by
storing some data in FACE->extra. If successful, return 0.
Otherwise, return -1. */
- int (*prepare_face) (FRAME_PTR f, struct face *face);
+ int (*prepare_face) (struct frame *f, struct face *face);
/* Optional.
Done FACE for displaying characters by FACE->font on frame F. */
- void (*done_face) (FRAME_PTR f, struct face *face);
+ void (*done_face) (struct frame *f, struct face *face);
/* Optional.
If FONT (FONT-ENTITY or FONT-OBJECT) has a glyph for character C
@@ -646,12 +646,12 @@ struct font_driver
Make the font driver ready for frame F. Usually this function
makes some data specific to F and stores it in F by calling
font_put_frame_data (). */
- int (*start_for_frame) (FRAME_PTR f);
+ int (*start_for_frame) (struct frame *f);
/* Optional.
End using the driver for frame F. Usually this function free
some data stored for F. */
- int (*end_for_frame) (FRAME_PTR f);
+ int (*end_for_frame) (struct frame *f);
/* Optional.
@@ -674,7 +674,7 @@ struct font_driver
If FONT is usable on frame F, return 0. Otherwise return -1.
This method is used only for debugging. If this method is NULL,
Emacs assumes that the font is usable on any frame. */
- int (*check) (FRAME_PTR F, struct font *font);
+ int (*check) (struct frame *f, struct font *font);
/* Optional.
@@ -698,8 +698,8 @@ struct font_driver
/* Chain of font drivers. There's one global font driver list
- (font_driver_list in font.c). In addition, each frame has its own
- font driver list at FRAME_PTR->font_driver_list. */
+ (font_driver_list in font.c). In addition, each frame has
+ its own font driver list at F->font_driver_list. */
struct font_driver_list
{
@@ -713,8 +713,8 @@ struct font_driver_list
};
-/* Chain of arbitrary data specific to each font driver. Each frame
- has its own font data list at FRAME_PTR->font_data_list. */
+/* Chain of arbitrary data specific to each font driver.
+ Each frame has its own font data list at F->font_data_list. */
struct font_data_list
{
@@ -742,28 +742,27 @@ extern Lisp_Object font_style_symbolic (Lisp_Object font,
bool for_face);
extern bool font_match_p (Lisp_Object spec, Lisp_Object font);
-extern Lisp_Object font_list_entities (Lisp_Object frame,
- Lisp_Object spec);
+extern Lisp_Object font_list_entities (struct frame *, Lisp_Object);
extern Lisp_Object font_get_name (Lisp_Object font_object);
extern Lisp_Object font_spec_from_name (Lisp_Object font_name);
extern Lisp_Object font_get_frame (Lisp_Object font_object);
-extern int font_has_char (FRAME_PTR, Lisp_Object, int);
+extern int font_has_char (struct frame *, Lisp_Object, int);
extern void font_clear_prop (Lisp_Object *attrs,
enum font_property_index prop);
-extern Lisp_Object font_find_for_lface (FRAME_PTR f, Lisp_Object *lface,
+extern Lisp_Object font_find_for_lface (struct frame *f, Lisp_Object *lface,
Lisp_Object spec, int c);
-extern Lisp_Object font_open_for_lface (FRAME_PTR f, Lisp_Object entity,
+extern Lisp_Object font_open_for_lface (struct frame *f, Lisp_Object entity,
Lisp_Object *lface,
Lisp_Object spec);
-extern Lisp_Object font_load_for_lface (FRAME_PTR f, Lisp_Object *lface,
+extern Lisp_Object font_load_for_lface (struct frame *f, Lisp_Object *lface,
Lisp_Object spec);
-extern void font_prepare_for_face (FRAME_PTR f, struct face *face);
-extern void font_done_for_face (FRAME_PTR f, struct face *face);
+extern void font_prepare_for_face (struct frame *f, struct face *face);
+extern void font_done_for_face (struct frame *f, struct face *face);
-extern Lisp_Object font_open_by_spec (FRAME_PTR f, Lisp_Object spec);
-extern Lisp_Object font_open_by_name (FRAME_PTR f, Lisp_Object name);
+extern Lisp_Object font_open_by_spec (struct frame *f, Lisp_Object spec);
+extern Lisp_Object font_open_by_name (struct frame *f, Lisp_Object name);
extern Lisp_Object font_intern_prop (const char *str, ptrdiff_t len,
bool force_symbol);
@@ -778,9 +777,9 @@ extern ptrdiff_t font_unparse_xlfd (Lisp_Object font, int pixel_size,
char *name, int bytes);
extern int font_unparse_fcname (Lisp_Object font, int pixel_size,
char *name, int bytes);
-extern void register_font_driver (struct font_driver *driver, FRAME_PTR f);
-extern void free_font_driver_list (FRAME_PTR f);
-extern Lisp_Object font_update_drivers (FRAME_PTR f, Lisp_Object list);
+extern void register_font_driver (struct font_driver *driver, struct frame *f);
+extern void free_font_driver_list (struct frame *f);
+extern Lisp_Object font_update_drivers (struct frame *f, Lisp_Object list);
extern Lisp_Object font_range (ptrdiff_t, ptrdiff_t, ptrdiff_t *,
struct window *, struct face *,
Lisp_Object);
@@ -789,10 +788,10 @@ extern void font_fill_lglyph_metrics (Lisp_Object, Lisp_Object);
extern Lisp_Object font_put_extra (Lisp_Object font, Lisp_Object prop,
Lisp_Object val);
-extern int font_put_frame_data (FRAME_PTR f,
+extern int font_put_frame_data (struct frame *f,
struct font_driver *driver,
void *data);
-extern void *font_get_frame_data (FRAME_PTR f,
+extern void *font_get_frame_data (struct frame *f,
struct font_driver *driver);
extern void font_filter_properties (Lisp_Object font,
diff --git a/src/fontset.c b/src/fontset.c
index 6a6a434add0..0bf716bf1b2 100644
--- a/src/fontset.c
+++ b/src/fontset.c
@@ -539,8 +539,9 @@ fontset_find_font (Lisp_Object fontset, int c, struct face *face, int id,
{
Lisp_Object vec, font_group;
int i, charset_matched = 0, found_index;
- FRAME_PTR f = (FRAMEP (FONTSET_FRAME (fontset))
- ? XFRAME (FONTSET_FRAME (fontset)) : XFRAME (selected_frame));
+ struct frame *f = (FRAMEP (FONTSET_FRAME (fontset))
+ ? XFRAME (FONTSET_FRAME (fontset))
+ : XFRAME (selected_frame));
Lisp_Object rfont_def;
font_group = fontset_get_font_group (fontset, fallback ? -1 : c);
@@ -859,7 +860,7 @@ fontset_ascii (int id)
}
static void
-free_realized_fontset (FRAME_PTR f, Lisp_Object fontset)
+free_realized_fontset (struct frame *f, Lisp_Object fontset)
{
#if 0
Lisp_Object tail;
@@ -877,7 +878,7 @@ free_realized_fontset (FRAME_PTR f, Lisp_Object fontset)
free_realized_face. */
void
-free_face_fontset (FRAME_PTR f, struct face *face)
+free_face_fontset (struct frame *f, struct face *face)
{
Lisp_Object fontset;
@@ -930,7 +931,7 @@ face_suitable_for_char_p (struct face *face, int c)
the macro FACE_FOR_CHAR. */
int
-face_for_char (FRAME_PTR f, struct face *face, int c, int pos, Lisp_Object object)
+face_for_char (struct frame *f, struct face *face, int c, int pos, Lisp_Object object)
{
Lisp_Object fontset, rfont_def, charset;
int face_id;
@@ -1048,7 +1049,7 @@ font_for_char (struct face *face, int c, int pos, Lisp_Object object)
Called from realize_x_face. */
int
-make_fontset_for_ascii_face (FRAME_PTR f, int base_fontset_id, struct face *face)
+make_fontset_for_ascii_face (struct frame *f, int base_fontset_id, struct face *face)
{
Lisp_Object base_fontset, fontset, frame;
@@ -1227,7 +1228,7 @@ If REGEXPP is non-nil, PATTERN is a regular expression. */)
/* Return a list of base fontset names matching PATTERN on frame F. */
Lisp_Object
-list_fontsets (FRAME_PTR f, Lisp_Object pattern, int size)
+list_fontsets (struct frame *f, Lisp_Object pattern, int size)
{
Lisp_Object frame, regexp, val;
int id;
@@ -1284,7 +1285,7 @@ free_realized_fontsets (Lisp_Object base)
for (tail = FONTSET_FACE_ALIST (this); CONSP (tail);
tail = XCDR (tail))
{
- FRAME_PTR f = XFRAME (FONTSET_FRAME (this));
+ struct frame *f = XFRAME (FONTSET_FRAME (this));
int face_id = XINT (XCDR (XCAR (tail)));
struct face *face = FACE_FROM_ID (f, face_id);
@@ -1612,7 +1613,7 @@ appended. By default, FONT-SPEC overrides the previous settings. */)
name = FONTSET_NAME (fontset);
FOR_EACH_FRAME (tail, fr)
{
- FRAME_PTR f = XFRAME (fr);
+ struct frame *f = XFRAME (fr);
Lisp_Object font_object;
struct face *face;
@@ -2140,7 +2141,7 @@ dump_fontset (Lisp_Object fontset)
frame = FONTSET_FRAME (fontset);
if (FRAMEP (frame))
{
- FRAME_PTR f = XFRAME (frame);
+ struct frame *f = XFRAME (frame);
if (FRAME_LIVE_P (f))
ASET (vec, 1,
diff --git a/src/fontset.h b/src/fontset.h
index 926520c8001..fd16c7178f5 100644
--- a/src/fontset.h
+++ b/src/fontset.h
@@ -28,12 +28,12 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
struct face;
-extern void free_face_fontset (FRAME_PTR, struct face *);
-extern int face_for_char (FRAME_PTR, struct face *, int,
+extern void free_face_fontset (struct frame *, struct face *);
+extern int face_for_char (struct frame *, struct face *, int,
int, Lisp_Object);
extern Lisp_Object font_for_char (struct face *, int, int, Lisp_Object);
-extern int make_fontset_for_ascii_face (FRAME_PTR, int, struct face *);
+extern int make_fontset_for_ascii_face (struct frame *, int, struct face *);
extern int fontset_from_font (Lisp_Object);
extern int fs_query_fontset (Lisp_Object, int);
extern Lisp_Object list_fontsets (struct frame *, Lisp_Object, int);
diff --git a/src/frame.c b/src/frame.c
index f8b7201e984..14fc15c4717 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -69,7 +69,6 @@ Lisp_Object Qnoelisp;
static Lisp_Object Qx_frame_parameter;
Lisp_Object Qx_resource_name;
Lisp_Object Qterminal;
-Lisp_Object Qterminal_live_p;
/* Frame parameters (set or reported). */
@@ -310,7 +309,7 @@ predicates which report frame's specific UI-related capabilities. */)
}
struct frame *
-make_frame (int mini_p)
+make_frame (bool mini_p)
{
Lisp_Object frame;
register struct frame *f;
@@ -725,16 +724,13 @@ affects all frames on the same terminal device. */)
adjust_glyphs (f);
calculate_costs (f);
XSETFRAME (frame, f);
+
+ store_in_alist (&parms, Qtty_type, build_string (t->display_info.tty->type));
+ store_in_alist (&parms, Qtty,
+ (t->display_info.tty->name
+ ? build_string (t->display_info.tty->name)
+ : Qnil));
Fmodify_frame_parameters (frame, parms);
- Fmodify_frame_parameters
- (frame, list1 (Fcons (Qtty_type,
- build_string (t->display_info.tty->type))));
- if (t->display_info.tty->name != NULL)
- Fmodify_frame_parameters
- (frame, list1 (Fcons (Qtty,
- build_string (t->display_info.tty->name))));
- else
- Fmodify_frame_parameters (frame, list1 (Fcons (Qtty, Qnil)));
/* Make the frame face alist be frame-specific, so that each
frame could change its face definitions independently. */
@@ -1097,7 +1093,7 @@ Otherwise, include all frames. */)
(Exception: if F is the terminal frame, and we are using X, return 1.) */
static int
-other_visible_frames (FRAME_PTR f)
+other_visible_frames (struct frame *f)
{
Lisp_Object frames, this;
@@ -1471,7 +1467,7 @@ passing the normal return value to that function as an argument,
and returns whatever that function returns. */)
(void)
{
- FRAME_PTR f;
+ struct frame *f;
Lisp_Object lispy_dummy;
Lisp_Object x, y, retval;
struct gcpro gcpro1;
@@ -1517,7 +1513,7 @@ to read the mouse position, it returns the selected frame for FRAME
and nil for X and Y. */)
(void)
{
- FRAME_PTR f;
+ struct frame *f;
Lisp_Object lispy_dummy;
Lisp_Object x, y;
@@ -2365,7 +2361,7 @@ to `frame-height'). */)
#ifdef HAVE_WINDOW_SYSTEM
if (FRAME_WINDOW_P (f))
- return make_number (x_pixel_height (f));
+ return make_number (FRAME_PIXEL_HEIGHT (f));
else
#endif
return make_number (FRAME_LINES (f));
@@ -2382,7 +2378,7 @@ If FRAME is omitted or nil, the selected frame is used. */)
#ifdef HAVE_WINDOW_SYSTEM
if (FRAME_WINDOW_P (f))
- return make_number (x_pixel_width (f));
+ return make_number (FRAME_PIXEL_WIDTH (f));
else
#endif
return make_number (FRAME_COLS (f));
@@ -2407,8 +2403,9 @@ is used. */)
DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
doc: /* Specify that the frame FRAME has LINES lines.
-Optional third arg non-nil means that redisplay should use LINES lines
-but that the idea of the actual height of the frame should not be changed. */)
+If FRAME is nil, the selected frame is used. Optional third arg
+non-nil means that redisplay should use LINES lines but that the
+idea of the actual height of the frame should not be changed. */)
(Lisp_Object frame, Lisp_Object lines, Lisp_Object pretend)
{
register struct frame *f = decode_live_frame (frame);
@@ -2431,8 +2428,9 @@ but that the idea of the actual height of the frame should not be changed. */)
DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
doc: /* Specify that the frame FRAME has COLS columns.
-Optional third arg non-nil means that redisplay should use COLS columns
-but that the idea of the actual width of the frame should not be changed. */)
+If FRAME is nil, the selected frame is used. Optional third arg
+non-nil means that redisplay should use COLS columns but that the
+idea of the actual width of the frame should not be changed. */)
(Lisp_Object frame, Lisp_Object cols, Lisp_Object pretend)
{
register struct frame *f = decode_live_frame (frame);
@@ -2454,15 +2452,14 @@ but that the idea of the actual width of the frame should not be changed. */)
}
DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
- doc: /* Sets size of FRAME to COLS by ROWS, measured in characters. */)
+ doc: /* Sets size of FRAME to COLS by ROWS, measured in characters.
+If FRAME is nil, the selected frame is used. */)
(Lisp_Object frame, Lisp_Object cols, Lisp_Object rows)
{
- register struct frame *f;
+ register struct frame *f = decode_live_frame (frame);
- CHECK_LIVE_FRAME (frame);
CHECK_TYPE_RANGED_INTEGER (int, cols);
CHECK_TYPE_RANGED_INTEGER (int, rows);
- f = XFRAME (frame);
/* I think this should be done with a hook. */
#ifdef HAVE_WINDOW_SYSTEM
@@ -2484,17 +2481,16 @@ DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
DEFUN ("set-frame-position", Fset_frame_position,
Sset_frame_position, 3, 3, 0,
doc: /* Sets position of FRAME in pixels to XOFFSET by YOFFSET.
-This is actually the position of the upper left corner of the frame.
-Negative values for XOFFSET or YOFFSET are interpreted relative to
-the rightmost or bottommost possible position (that stays within the screen). */)
+If FRAME is nil, the selected frame is used. XOFFSET and YOFFSET are
+actually the position of the upper left corner of the frame. Negative
+values for XOFFSET or YOFFSET are interpreted relative to the rightmost
+or bottommost possible position (that stays within the screen). */)
(Lisp_Object frame, Lisp_Object xoffset, Lisp_Object yoffset)
{
- register struct frame *f;
+ register struct frame *f = decode_live_frame (frame);
- CHECK_LIVE_FRAME (frame);
CHECK_TYPE_RANGED_INTEGER (int, xoffset);
CHECK_TYPE_RANGED_INTEGER (int, yoffset);
- f = XFRAME (frame);
/* I think this should be done with a hook. */
#ifdef HAVE_WINDOW_SYSTEM
@@ -2614,7 +2610,7 @@ x_fullscreen_adjust (struct frame *f, int *width, int *height, int *top_pos, int
to store the new value in the parameter alist. */
void
-x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist)
+x_set_frame_parameters (struct frame *f, Lisp_Object alist)
{
Lisp_Object tail;
@@ -2633,9 +2629,9 @@ x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist)
Lisp_Object *parms;
Lisp_Object *values;
ptrdiff_t i, p;
- int left_no_change = 0, top_no_change = 0;
- int icon_left_no_change = 0, icon_top_no_change = 0;
- int size_changed = 0;
+ bool left_no_change = 0, top_no_change = 0;
+ bool icon_left_no_change = 0, icon_top_no_change = 0;
+ bool size_changed = 0;
struct gcpro gcpro1, gcpro2;
i = 0;
@@ -2871,10 +2867,11 @@ x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist)
/* Actually set that position, and convert to absolute. */
x_set_offset (f, leftpos, toppos, -1);
}
-
+#ifdef HAVE_X_WINDOWS
if ((!NILP (icon_left) || !NILP (icon_top))
&& ! (icon_left_no_change && icon_top_no_change))
x_wm_set_icon_position (f, XINT (icon_left), XINT (icon_top));
+#endif /* HAVE_X_WINDOWS */
}
UNGCPRO;
@@ -3351,7 +3348,7 @@ x_set_scroll_bar_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
/* Return non-nil if frame F wants a bitmap icon. */
Lisp_Object
-x_icon_type (FRAME_PTR f)
+x_icon_type (struct frame *f)
{
Lisp_Object tem;
@@ -3939,8 +3936,8 @@ On Nextstep, this just calls `ns-parse-geometry'. */)
#define DEFAULT_ROWS 35
#define DEFAULT_COLS 80
-int
-x_figure_window_size (struct frame *f, Lisp_Object parms, int toolbar_p)
+long
+x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p)
{
register Lisp_Object tem0, tem1, tem2;
long window_prompting = 0;
@@ -4291,7 +4288,6 @@ syms_of_frame (void)
DEFSYM (Qx_frame_parameter, "x-frame-parameter");
DEFSYM (Qterminal, "terminal");
- DEFSYM (Qterminal_live_p, "terminal-live-p");
DEFSYM (Qgeometry, "geometry");
DEFSYM (Qworkarea, "workarea");
diff --git a/src/frame.h b/src/frame.h
index 31d3e73c3c3..33e4bb71d7a 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -591,8 +591,6 @@ default_pixels_per_inch_y (void)
/* Return a pointer to the image cache of frame F. */
#define FRAME_IMAGE_CACHE(F) ((F)->terminal->image_cache)
-typedef struct frame *FRAME_PTR;
-
#define XFRAME(p) \
(eassert (FRAMEP (p)), (struct frame *) XUNTAG (p, Lisp_Vectorlike))
#define XSETFRAME(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_FRAME))
@@ -929,10 +927,9 @@ typedef struct frame *FRAME_PTR;
if (frame == hlinfo->mouse_face_mouse_frame) \
{ \
block_input (); \
- if (hlinfo->mouse_face_mouse_frame) \
- note_mouse_highlight (hlinfo->mouse_face_mouse_frame, \
- hlinfo->mouse_face_mouse_x, \
- hlinfo->mouse_face_mouse_y); \
+ note_mouse_highlight (hlinfo->mouse_face_mouse_frame, \
+ hlinfo->mouse_face_mouse_x, \
+ hlinfo->mouse_face_mouse_y); \
unblock_input (); \
} \
} while (0)
@@ -952,7 +949,7 @@ typedef struct frame *FRAME_PTR;
extern Lisp_Object Qframep, Qframe_live_p;
extern Lisp_Object Qtty, Qtty_type;
extern Lisp_Object Qtty_color_mode;
-extern Lisp_Object Qterminal, Qterminal_live_p;
+extern Lisp_Object Qterminal;
extern Lisp_Object Qnoelisp;
extern struct frame *last_nonminibuf_frame;
@@ -962,7 +959,7 @@ extern struct frame *decode_window_system_frame (Lisp_Object);
extern struct frame *decode_live_frame (Lisp_Object);
extern struct frame *decode_any_frame (Lisp_Object);
extern struct frame *make_initial_frame (void);
-extern struct frame *make_frame (int);
+extern struct frame *make_frame (bool);
#ifdef HAVE_WINDOW_SYSTEM
extern struct frame *make_minibuffer_frame (void);
extern struct frame *make_frame_without_minibuffer (Lisp_Object,
@@ -1207,8 +1204,7 @@ extern Lisp_Object Qrun_hook_with_args;
extern void x_set_scroll_bar_default_width (struct frame *);
extern void x_set_offset (struct frame *, int, int, int);
-extern void x_wm_set_icon_position (struct frame *, int, int);
-extern void x_wm_set_size_hint (FRAME_PTR f, long flags, bool user_position);
+extern void x_wm_set_size_hint (struct frame *f, long flags, bool user_position);
extern Lisp_Object x_new_font (struct frame *, Lisp_Object, int);
@@ -1242,7 +1238,7 @@ extern void x_set_scroll_bar_width (struct frame *, Lisp_Object,
extern Lisp_Object x_icon_type (struct frame *);
-extern int x_figure_window_size (struct frame *, Lisp_Object, int);
+extern long x_figure_window_size (struct frame *, Lisp_Object, bool);
extern void x_set_alpha (struct frame *, Lisp_Object, Lisp_Object);
@@ -1264,8 +1260,6 @@ extern void x_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y);
extern void x_make_frame_visible (struct frame *f);
extern void x_make_frame_invisible (struct frame *f);
extern void x_iconify_frame (struct frame *f);
-extern int x_pixel_width (struct frame *f);
-extern int x_pixel_height (struct frame *f);
extern void x_set_frame_alpha (struct frame *f);
extern void x_set_menu_bar_lines (struct frame *, Lisp_Object, Lisp_Object);
extern void x_set_tool_bar_lines (struct frame *f,
@@ -1280,9 +1274,12 @@ extern void x_set_menu_bar_lines (struct frame *,
extern void free_frame_menubar (struct frame *);
extern void x_free_frame_resources (struct frame *);
-#if defined HAVE_X_WINDOWS && !defined USE_X_TOOLKIT
+#if defined HAVE_X_WINDOWS
+extern void x_wm_set_icon_position (struct frame *, int, int);
+#if !defined USE_X_TOOLKIT
extern char *x_get_resource_string (const char *, const char *);
#endif
+#endif
extern void x_query_colors (struct frame *f, XColor *, int);
extern void x_query_color (struct frame *f, XColor *);
diff --git a/src/ftfont.c b/src/ftfont.c
index 10090cb3bda..3636f86f5c4 100644
--- a/src/ftfont.c
+++ b/src/ftfont.c
@@ -493,12 +493,12 @@ ftfont_get_otf (struct ftfont_info *ftfont_info)
}
#endif /* HAVE_LIBOTF */
-static Lisp_Object ftfont_get_cache (FRAME_PTR);
-static Lisp_Object ftfont_list (Lisp_Object, Lisp_Object);
-static Lisp_Object ftfont_match (Lisp_Object, Lisp_Object);
-static Lisp_Object ftfont_list_family (Lisp_Object);
-static Lisp_Object ftfont_open (FRAME_PTR, Lisp_Object, int);
-static void ftfont_close (FRAME_PTR, struct font *);
+static Lisp_Object ftfont_get_cache (struct frame *);
+static Lisp_Object ftfont_list (struct frame *, Lisp_Object);
+static Lisp_Object ftfont_match (struct frame *, Lisp_Object);
+static Lisp_Object ftfont_list_family (struct frame *);
+static Lisp_Object ftfont_open (struct frame *, Lisp_Object, int);
+static void ftfont_close (struct frame *, struct font *);
static int ftfont_has_char (Lisp_Object, int);
static unsigned ftfont_encode_char (struct font *, int);
static int ftfont_text_extents (struct font *, unsigned *, int,
@@ -568,7 +568,7 @@ struct font_driver ftfont_driver =
};
static Lisp_Object
-ftfont_get_cache (FRAME_PTR f)
+ftfont_get_cache (struct frame *f)
{
return freetype_font_cache;
}
@@ -884,7 +884,7 @@ ftfont_spec_pattern (Lisp_Object spec, char *otlayout, struct OpenTypeSpec **ots
}
static Lisp_Object
-ftfont_list (Lisp_Object frame, Lisp_Object spec)
+ftfont_list (struct frame *f, Lisp_Object spec)
{
Lisp_Object val = Qnil, family, adstyle;
int i;
@@ -1080,7 +1080,7 @@ ftfont_list (Lisp_Object frame, Lisp_Object spec)
}
static Lisp_Object
-ftfont_match (Lisp_Object frame, Lisp_Object spec)
+ftfont_match (struct frame *f, Lisp_Object spec)
{
Lisp_Object entity = Qnil;
FcPattern *pattern, *match = NULL;
@@ -1130,7 +1130,7 @@ ftfont_match (Lisp_Object frame, Lisp_Object spec)
}
static Lisp_Object
-ftfont_list_family (Lisp_Object frame)
+ftfont_list_family (struct frame *f)
{
Lisp_Object list = Qnil;
FcPattern *pattern = NULL;
@@ -1173,7 +1173,7 @@ ftfont_list_family (Lisp_Object frame)
static Lisp_Object
-ftfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size)
+ftfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
{
struct ftfont_info *ftfont_info;
struct font *font;
@@ -1317,7 +1317,7 @@ ftfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size)
}
static void
-ftfont_close (FRAME_PTR f, struct font *font)
+ftfont_close (struct frame *f, struct font *font)
{
struct ftfont_info *ftfont_info = (struct ftfont_info *) font;
Lisp_Object val, cache;
diff --git a/src/ftxfont.c b/src/ftxfont.c
index 8c56ee05adc..63d03b0e244 100644
--- a/src/ftxfont.c
+++ b/src/ftxfont.c
@@ -57,7 +57,7 @@ struct ftxfont_frame_data
/* Return an array of 6 GCs for antialiasing. */
static GC *
-ftxfont_get_gcs (FRAME_PTR f, long unsigned int foreground, long unsigned int background)
+ftxfont_get_gcs (struct frame *f, long unsigned int foreground, long unsigned int background)
{
XColor color;
XGCValues xgcv;
@@ -134,7 +134,7 @@ ftxfont_get_gcs (FRAME_PTR f, long unsigned int foreground, long unsigned int ba
}
static int
-ftxfont_draw_bitmap (FRAME_PTR f, GC gc_fore, GC *gcs, struct font *font,
+ftxfont_draw_bitmap (struct frame *f, GC gc_fore, GC *gcs, struct font *font,
unsigned int code, int x, int y, XPoint *p, int size,
int *n, bool flush)
{
@@ -212,7 +212,7 @@ ftxfont_draw_bitmap (FRAME_PTR f, GC gc_fore, GC *gcs, struct font *font,
}
static void
-ftxfont_draw_background (FRAME_PTR f, struct font *font, GC gc, int x, int y,
+ftxfont_draw_background (struct frame *f, struct font *font, GC gc, int x, int y,
int width)
{
XGCValues xgcv;
@@ -226,9 +226,9 @@ ftxfont_draw_background (FRAME_PTR f, struct font *font, GC gc, int x, int y,
}
static Lisp_Object
-ftxfont_list (Lisp_Object frame, Lisp_Object spec)
+ftxfont_list (struct frame *f, Lisp_Object spec)
{
- Lisp_Object list = ftfont_driver.list (frame, spec), tail;
+ Lisp_Object list = ftfont_driver.list (f, spec), tail;
for (tail = list; CONSP (tail); tail = XCDR (tail))
ASET (XCAR (tail), FONT_TYPE_INDEX, Qftx);
@@ -236,9 +236,9 @@ ftxfont_list (Lisp_Object frame, Lisp_Object spec)
}
static Lisp_Object
-ftxfont_match (Lisp_Object frame, Lisp_Object spec)
+ftxfont_match (struct frame *f, Lisp_Object spec)
{
- Lisp_Object entity = ftfont_driver.match (frame, spec);
+ Lisp_Object entity = ftfont_driver.match (f, spec);
if (VECTORP (entity))
ASET (entity, FONT_TYPE_INDEX, Qftx);
@@ -246,7 +246,7 @@ ftxfont_match (Lisp_Object frame, Lisp_Object spec)
}
static Lisp_Object
-ftxfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size)
+ftxfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
{
Lisp_Object font_object;
struct font *font;
@@ -260,7 +260,7 @@ ftxfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size)
}
static void
-ftxfont_close (FRAME_PTR f, struct font *font)
+ftxfont_close (struct frame *f, struct font *font)
{
ftfont_driver.close (f, font);
}
@@ -269,7 +269,7 @@ static int
ftxfont_draw (struct glyph_string *s, int from, int to, int x, int y,
bool with_background)
{
- FRAME_PTR f = s->f;
+ struct frame *f = s->f;
struct face *face = s->face;
struct font *font = s->font;
XPoint p[0x700];
@@ -338,7 +338,7 @@ ftxfont_draw (struct glyph_string *s, int from, int to, int x, int y,
}
static int
-ftxfont_end_for_frame (FRAME_PTR f)
+ftxfont_end_for_frame (struct frame *f)
{
struct ftxfont_frame_data *data = font_get_frame_data (f, &ftxfont_driver);
diff --git a/src/gtkutil.c b/src/gtkutil.c
index f8ddf6a90f6..237d031295c 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -136,7 +136,7 @@ static GdkDisplay *gdpy_def;
W can be a GtkMenu or a GtkWindow widget. */
static void
-xg_set_screen (GtkWidget *w, FRAME_PTR f)
+xg_set_screen (GtkWidget *w, struct frame *f)
{
if (FRAME_X_DISPLAY (f) != DEFAULT_GDK_DISPLAY ())
{
@@ -280,7 +280,7 @@ xg_create_default_cursor (Display *dpy)
}
static GdkPixbuf *
-xg_get_pixbuf_from_pixmap (FRAME_PTR f, Pixmap pix)
+xg_get_pixbuf_from_pixmap (struct frame *f, Pixmap pix)
{
int iunused;
GdkPixbuf *tmp_buf;
@@ -311,7 +311,7 @@ xg_get_pixbuf_from_pixmap (FRAME_PTR f, Pixmap pix)
/* Apply GMASK to GPIX and return a GdkPixbuf with an alpha channel. */
static GdkPixbuf *
-xg_get_pixbuf_from_pix_and_mask (FRAME_PTR f,
+xg_get_pixbuf_from_pix_and_mask (struct frame *f,
Pixmap pix,
Pixmap mask)
{
@@ -387,7 +387,7 @@ file_for_image (Lisp_Object image)
If OLD_WIDGET is not NULL, that widget is modified. */
static GtkWidget *
-xg_get_image_for_pixmap (FRAME_PTR f,
+xg_get_image_for_pixmap (struct frame *f,
struct image *img,
GtkWidget *widget,
GtkImage *old_widget)
@@ -641,7 +641,7 @@ hierarchy_ch_cb (GtkWidget *widget,
GtkWidget *previous_toplevel,
gpointer user_data)
{
- FRAME_PTR f = (FRAME_PTR) user_data;
+ struct frame *f = (struct frame *) user_data;
struct x_output *x = f->output_data.x;
GtkWidget *top = gtk_widget_get_toplevel (x->ttip_lbl);
@@ -663,7 +663,7 @@ qttip_cb (GtkWidget *widget,
GtkTooltip *tooltip,
gpointer user_data)
{
- FRAME_PTR f = (FRAME_PTR) user_data;
+ struct frame *f = (struct frame *) user_data;
struct x_output *x = f->output_data.x;
if (x->ttip_widget == NULL)
{
@@ -707,7 +707,7 @@ qttip_cb (GtkWidget *widget,
Return true if a system tooltip is available. */
bool
-xg_prepare_tooltip (FRAME_PTR f,
+xg_prepare_tooltip (struct frame *f,
Lisp_Object string,
int *width,
int *height)
@@ -764,7 +764,7 @@ xg_prepare_tooltip (FRAME_PTR f,
xg_prepare_tooltip must have been called before this function. */
void
-xg_show_tooltip (FRAME_PTR f, int root_x, int root_y)
+xg_show_tooltip (struct frame *f, int root_x, int root_y)
{
#ifdef USE_GTK_TOOLTIP
struct x_output *x = f->output_data.x;
@@ -783,7 +783,7 @@ xg_show_tooltip (FRAME_PTR f, int root_x, int root_y)
system tooltips). */
bool
-xg_hide_tooltip (FRAME_PTR f)
+xg_hide_tooltip (struct frame *f)
{
bool ret = 0;
#ifdef USE_GTK_TOOLTIP
@@ -827,7 +827,7 @@ my_log_handler (const gchar *log_domain, GLogLevelFlags log_level,
F is the frame we shall set geometry for. */
static void
-xg_set_geometry (FRAME_PTR f)
+xg_set_geometry (struct frame *f)
{
if (f->size_hint_flags & (USPosition | PPosition))
{
@@ -865,7 +865,7 @@ xg_set_geometry (FRAME_PTR f)
and use a GtkFixed widget, this doesn't happen automatically. */
static void
-xg_clear_under_internal_border (FRAME_PTR f)
+xg_clear_under_internal_border (struct frame *f)
{
if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0)
{
@@ -903,7 +903,7 @@ xg_clear_under_internal_border (FRAME_PTR f)
PIXELWIDTH, PIXELHEIGHT is the new size in pixels. */
void
-xg_frame_resized (FRAME_PTR f, int pixelwidth, int pixelheight)
+xg_frame_resized (struct frame *f, int pixelwidth, int pixelheight)
{
int rows, columns;
@@ -939,7 +939,7 @@ xg_frame_resized (FRAME_PTR f, int pixelwidth, int pixelheight)
COLUMNS/ROWS is the size the edit area shall have after the resize. */
void
-xg_frame_set_char_size (FRAME_PTR f, int cols, int rows)
+xg_frame_set_char_size (struct frame *f, int cols, int rows)
{
int pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows)
+ FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f);
@@ -1002,7 +1002,7 @@ xg_frame_set_char_size (FRAME_PTR f, int cols, int rows)
The policy is to keep the number of editable lines. */
static void
-xg_height_or_width_changed (FRAME_PTR f)
+xg_height_or_width_changed (struct frame *f)
{
gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
FRAME_TOTAL_PIXEL_WIDTH (f),
@@ -1042,7 +1042,7 @@ xg_win_to_widget (Display *dpy, Window wdesc)
/* Set the background of widget W to PIXEL. */
static void
-xg_set_widget_bg (FRAME_PTR f, GtkWidget *w, long unsigned int pixel)
+xg_set_widget_bg (struct frame *f, GtkWidget *w, long unsigned int pixel)
{
#ifdef HAVE_GTK3
GdkRGBA bg;
@@ -1093,7 +1093,7 @@ style_changed_cb (GObject *go,
Lisp_Object rest, frame;
FOR_EACH_FRAME (rest, frame)
{
- FRAME_PTR f = XFRAME (frame);
+ struct frame *f = XFRAME (frame);
if (FRAME_LIVE_P (f)
&& FRAME_X_P (f)
&& FRAME_X_DISPLAY (f) == dpy)
@@ -1115,7 +1115,7 @@ delete_cb (GtkWidget *widget,
#ifdef HAVE_GTK3
/* The event doesn't arrive in the normal event loop. Send event
here. */
- FRAME_PTR f = (FRAME_PTR) user_data;
+ struct frame *f = (struct frame *) user_data;
struct input_event ie;
EVENT_INIT (ie);
@@ -1131,7 +1131,7 @@ delete_cb (GtkWidget *widget,
Return true if creation succeeded. */
bool
-xg_create_frame_widgets (FRAME_PTR f)
+xg_create_frame_widgets (struct frame *f)
{
GtkWidget *wtop;
GtkWidget *wvbox, *whbox;
@@ -1300,7 +1300,7 @@ xg_create_frame_widgets (FRAME_PTR f)
}
void
-xg_free_frame_widgets (FRAME_PTR f)
+xg_free_frame_widgets (struct frame *f)
{
if (FRAME_GTK_OUTER_WIDGET (f))
{
@@ -1332,7 +1332,7 @@ xg_free_frame_widgets (FRAME_PTR f)
flag (this is useful when FLAGS is 0). */
void
-x_wm_set_size_hint (FRAME_PTR f, long int flags, bool user_position)
+x_wm_set_size_hint (struct frame *f, long int flags, bool user_position)
{
/* Must use GTK routines here, otherwise GTK resets the size hints
to its own defaults. */
@@ -1432,7 +1432,7 @@ x_wm_set_size_hint (FRAME_PTR f, long int flags, bool user_position)
BG is the pixel value to change to. */
void
-xg_set_background_color (FRAME_PTR f, long unsigned int bg)
+xg_set_background_color (struct frame *f, long unsigned int bg)
{
if (FRAME_GTK_WIDGET (f))
{
@@ -1447,7 +1447,7 @@ xg_set_background_color (FRAME_PTR f, long unsigned int bg)
functions so GTK does not overwrite the icon. */
void
-xg_set_frame_icon (FRAME_PTR f, Pixmap icon_pixmap, Pixmap icon_mask)
+xg_set_frame_icon (struct frame *f, Pixmap icon_pixmap, Pixmap icon_mask)
{
GdkPixbuf *gp = xg_get_pixbuf_from_pix_and_mask (f,
icon_pixmap,
@@ -1693,7 +1693,7 @@ xg_maybe_add_timer (gpointer data)
The dialog W is not destroyed when this function returns. */
static int
-xg_dialog_run (FRAME_PTR f, GtkWidget *w)
+xg_dialog_run (struct frame *f, GtkWidget *w)
{
ptrdiff_t count = SPECPDL_INDEX ();
struct xg_dialog_data dd;
@@ -1813,7 +1813,7 @@ xg_toggle_notify_cb (GObject *gobject, GParamSpec *arg1, gpointer user_data)
Returns the created widget. */
static GtkWidget *
-xg_get_file_with_chooser (FRAME_PTR f,
+xg_get_file_with_chooser (struct frame *f,
char *prompt,
char *default_filename,
bool mustmatch_p, bool only_dir_p,
@@ -1935,7 +1935,7 @@ xg_get_file_name_from_selector (GtkWidget *w)
Returns the created widget. */
static GtkWidget *
-xg_get_file_with_selection (FRAME_PTR f,
+xg_get_file_with_selection (struct frame *f,
char *prompt,
char *default_filename,
bool mustmatch_p, bool only_dir_p,
@@ -1977,7 +1977,7 @@ xg_get_file_with_selection (FRAME_PTR f,
The returned string must be freed by the caller. */
char *
-xg_get_file_name (FRAME_PTR f,
+xg_get_file_name (struct frame *f,
char *prompt,
char *default_filename,
bool mustmatch_p,
@@ -2051,7 +2051,7 @@ extern Lisp_Object Qxft;
DEFAULT_NAME, if non-zero, is the default font name. */
Lisp_Object
-xg_get_font (FRAME_PTR f, const char *default_name)
+xg_get_font (struct frame *f, const char *default_name)
{
GtkWidget *w;
int done = 0;
@@ -2169,7 +2169,7 @@ static xg_list_node xg_menu_item_cb_list;
allocated xg_menu_cb_data if CL_DATA is NULL. */
static xg_menu_cb_data *
-make_cl_data (xg_menu_cb_data *cl_data, FRAME_PTR f, GCallback highlight_cb)
+make_cl_data (xg_menu_cb_data *cl_data, struct frame *f, GCallback highlight_cb)
{
if (! cl_data)
{
@@ -2201,7 +2201,7 @@ make_cl_data (xg_menu_cb_data *cl_data, FRAME_PTR f, GCallback highlight_cb)
static void
update_cl_data (xg_menu_cb_data *cl_data,
- FRAME_PTR f,
+ struct frame *f,
GCallback highlight_cb)
{
if (cl_data)
@@ -2251,7 +2251,7 @@ xg_mark_data (void)
FOR_EACH_FRAME (rest, frame)
{
- FRAME_PTR f = XFRAME (frame);
+ struct frame *f = XFRAME (frame);
if (FRAME_X_P (f) && FRAME_GTK_OUTER_WIDGET (f))
{
@@ -2480,7 +2480,7 @@ xg_have_tear_offs (void)
static GtkWidget *
xg_create_one_menuitem (widget_value *item,
- FRAME_PTR f,
+ struct frame *f,
GCallback select_cb,
GCallback highlight_cb,
xg_menu_cb_data *cl_data,
@@ -2551,7 +2551,7 @@ xg_create_one_menuitem (widget_value *item,
static GtkWidget *
create_menus (widget_value *data,
- FRAME_PTR f,
+ struct frame *f,
GCallback select_cb,
GCallback deactivate_cb,
GCallback highlight_cb,
@@ -2694,9 +2694,9 @@ create_menus (widget_value *data,
Returns the widget created. */
GtkWidget *
-xg_create_widget (const char *type, const char *name, FRAME_PTR f, widget_value *val,
- GCallback select_cb, GCallback deactivate_cb,
- GCallback highlight_cb)
+xg_create_widget (const char *type, const char *name, struct frame *f,
+ widget_value *val, GCallback select_cb,
+ GCallback deactivate_cb, GCallback highlight_cb)
{
GtkWidget *w = 0;
bool menu_bar_p = strcmp (type, "menubar") == 0;
@@ -2802,7 +2802,7 @@ xg_destroy_widgets (GList *list)
static void
xg_update_menubar (GtkWidget *menubar,
- FRAME_PTR f,
+ struct frame *f,
GList **list,
GList *iter,
int pos,
@@ -3119,7 +3119,7 @@ xg_update_radio_item (widget_value *val, GtkWidget *w)
static GtkWidget *
xg_update_submenu (GtkWidget *submenu,
- FRAME_PTR f,
+ struct frame *f,
widget_value *val,
GCallback select_cb,
GCallback deactivate_cb,
@@ -3261,8 +3261,8 @@ xg_update_submenu (GtkWidget *submenu,
HIGHLIGHT_CB is the callback to call when entering/leaving menu items. */
void
-xg_modify_menubar_widgets (GtkWidget *menubar, FRAME_PTR f, widget_value *val,
- bool deep_p,
+xg_modify_menubar_widgets (GtkWidget *menubar, struct frame *f,
+ widget_value *val, bool deep_p,
GCallback select_cb, GCallback deactivate_cb,
GCallback highlight_cb)
{
@@ -3336,7 +3336,7 @@ static void
menubar_map_cb (GtkWidget *w, gpointer user_data)
{
GtkRequisition req;
- FRAME_PTR f = (FRAME_PTR) user_data;
+ struct frame *f = (struct frame *) user_data;
gtk_widget_get_preferred_size (w, NULL, &req);
if (FRAME_MENUBAR_HEIGHT (f) != req.height)
{
@@ -3349,7 +3349,7 @@ menubar_map_cb (GtkWidget *w, gpointer user_data)
changed. */
void
-xg_update_frame_menubar (FRAME_PTR f)
+xg_update_frame_menubar (struct frame *f)
{
struct x_output *x = f->output_data.x;
GtkRequisition req;
@@ -3387,7 +3387,7 @@ xg_update_frame_menubar (FRAME_PTR f)
This is used when deleting a frame, and when turning off the menu bar. */
void
-free_frame_menubar (FRAME_PTR f)
+free_frame_menubar (struct frame *f)
{
struct x_output *x = f->output_data.x;
@@ -3406,7 +3406,7 @@ free_frame_menubar (FRAME_PTR f)
}
bool
-xg_event_is_for_menubar (FRAME_PTR f, XEvent *event)
+xg_event_is_for_menubar (struct frame *f, XEvent *event)
{
struct x_output *x = f->output_data.x;
GList *iter;
@@ -3619,7 +3619,7 @@ xg_gtk_scroll_destroy (GtkWidget *widget, gpointer data)
to set resources for the widget. */
void
-xg_create_scroll_bar (FRAME_PTR f,
+xg_create_scroll_bar (struct frame *f,
struct scroll_bar *bar,
GCallback scroll_callback,
GCallback end_callback,
@@ -3681,7 +3681,7 @@ xg_create_scroll_bar (FRAME_PTR f,
/* Remove the scroll bar represented by SCROLLBAR_ID from the frame F. */
void
-xg_remove_scroll_bar (FRAME_PTR f, ptrdiff_t scrollbar_id)
+xg_remove_scroll_bar (struct frame *f, ptrdiff_t scrollbar_id)
{
GtkWidget *w = xg_get_widget_from_map (scrollbar_id);
if (w)
@@ -3699,7 +3699,7 @@ xg_remove_scroll_bar (FRAME_PTR f, ptrdiff_t scrollbar_id)
WIDTH, HEIGHT is the size in pixels the bar shall have. */
void
-xg_update_scrollbar_pos (FRAME_PTR f,
+xg_update_scrollbar_pos (struct frame *f,
ptrdiff_t scrollbar_id,
int top,
int left,
@@ -3781,7 +3781,7 @@ xg_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar,
{
GtkWidget *wscroll = xg_get_widget_from_map (bar->x_window);
- FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
+ struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
if (wscroll && NILP (bar->dragging))
{
@@ -3861,7 +3861,7 @@ xg_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar,
frame. This function does additional checks. */
bool
-xg_event_is_for_scrollbar (FRAME_PTR f, XEvent *event)
+xg_event_is_for_scrollbar (struct frame *f, XEvent *event)
{
bool retval = 0;
@@ -3946,7 +3946,8 @@ xg_tool_bar_callback (GtkWidget *w, gpointer client_data)
gpointer gmod = g_object_get_data (G_OBJECT (w), XG_TOOL_BAR_LAST_MODIFIER);
intptr_t mod = (intptr_t) gmod;
- FRAME_PTR f = (FRAME_PTR) g_object_get_data (G_OBJECT (w), XG_FRAME_DATA);
+ struct frame *f = (struct frame *) g_object_get_data (G_OBJECT (w),
+ XG_FRAME_DATA);
Lisp_Object key, frame;
struct input_event event;
EVENT_INIT (event);
@@ -4149,7 +4150,7 @@ xg_tool_bar_detach_callback (GtkHandleBox *wbox,
GtkWidget *w,
gpointer client_data)
{
- FRAME_PTR f = (FRAME_PTR) client_data;
+ struct frame *f = (struct frame *) client_data;
g_object_set (G_OBJECT (w), "show-arrow", !x_gtk_whole_detached_tool_bar,
NULL);
@@ -4186,7 +4187,7 @@ xg_tool_bar_attach_callback (GtkHandleBox *wbox,
GtkWidget *w,
gpointer client_data)
{
- FRAME_PTR f = (FRAME_PTR) client_data;
+ struct frame *f = (struct frame *) client_data;
g_object_set (G_OBJECT (w), "show-arrow", TRUE, NULL);
if (f)
@@ -4224,7 +4225,8 @@ xg_tool_bar_help_callback (GtkWidget *w,
gpointer client_data)
{
intptr_t idx = (intptr_t) client_data;
- FRAME_PTR f = (FRAME_PTR) g_object_get_data (G_OBJECT (w), XG_FRAME_DATA);
+ struct frame *f = (struct frame *) g_object_get_data (G_OBJECT (w),
+ XG_FRAME_DATA);
Lisp_Object help, frame;
if (! f || ! f->n_tool_bar_items || NILP (f->tool_bar_items))
@@ -4297,7 +4299,7 @@ xg_tool_bar_item_expose_callback (GtkWidget *w,
/* Attach a tool bar to frame F. */
static void
-xg_pack_tool_bar (FRAME_PTR f, Lisp_Object pos)
+xg_pack_tool_bar (struct frame *f, Lisp_Object pos)
{
struct x_output *x = f->output_data.x;
bool into_hbox = EQ (pos, Qleft) || EQ (pos, Qright);
@@ -4354,7 +4356,7 @@ xg_pack_tool_bar (FRAME_PTR f, Lisp_Object pos)
x->toolbar_is_packed = true;
}
-static bool xg_update_tool_bar_sizes (FRAME_PTR f);
+static bool xg_update_tool_bar_sizes (struct frame *f);
static void
tb_size_cb (GtkWidget *widget,
@@ -4364,7 +4366,7 @@ tb_size_cb (GtkWidget *widget,
/* When tool bar is created it has one preferred size. But when size is
allocated between widgets, it may get another. So we must update
size hints if tool bar size changes. Seen on Fedora 18 at least. */
- FRAME_PTR f = (FRAME_PTR) user_data;
+ struct frame *f = (struct frame *) user_data;
if (xg_update_tool_bar_sizes (f))
x_wm_set_size_hint (f, 0, 0);
}
@@ -4372,7 +4374,7 @@ tb_size_cb (GtkWidget *widget,
/* Create a tool bar for frame F. */
static void
-xg_create_tool_bar (FRAME_PTR f)
+xg_create_tool_bar (struct frame *f)
{
struct x_output *x = f->output_data.x;
#if GTK_CHECK_VERSION (3, 3, 6)
@@ -4415,7 +4417,7 @@ xg_create_tool_bar (FRAME_PTR f)
Returns IMAGE if RTL is not found. */
static Lisp_Object
-find_rtl_image (FRAME_PTR f, Lisp_Object image, Lisp_Object rtl)
+find_rtl_image (struct frame *f, Lisp_Object image, Lisp_Object rtl)
{
int i;
Lisp_Object file, rtl_name;
@@ -4443,7 +4445,7 @@ find_rtl_image (FRAME_PTR f, Lisp_Object image, Lisp_Object rtl)
}
static GtkToolItem *
-xg_make_tool_item (FRAME_PTR f,
+xg_make_tool_item (struct frame *f,
GtkWidget *wimage,
GtkWidget **wbutton,
const char *label,
@@ -4606,7 +4608,7 @@ xg_tool_item_stale_p (GtkWidget *wbutton, const char *stock_name,
}
static bool
-xg_update_tool_bar_sizes (FRAME_PTR f)
+xg_update_tool_bar_sizes (struct frame *f)
{
struct x_output *x = f->output_data.x;
GtkRequisition req;
@@ -4654,7 +4656,7 @@ xg_update_tool_bar_sizes (FRAME_PTR f)
/* Update the tool bar for frame F. Add new buttons and remove old. */
void
-update_frame_tool_bar (FRAME_PTR f)
+update_frame_tool_bar (struct frame *f)
{
int i, j;
struct x_output *x = f->output_data.x;
@@ -4929,7 +4931,7 @@ update_frame_tool_bar (FRAME_PTR f)
Remove the tool bar. */
void
-free_frame_tool_bar (FRAME_PTR f)
+free_frame_tool_bar (struct frame *f)
{
struct x_output *x = f->output_data.x;
@@ -4976,7 +4978,7 @@ free_frame_tool_bar (FRAME_PTR f)
}
void
-xg_change_toolbar_position (FRAME_PTR f, Lisp_Object pos)
+xg_change_toolbar_position (struct frame *f, Lisp_Object pos)
{
struct x_output *x = f->output_data.x;
GtkWidget *top_widget = TOOLBAR_TOP_WIDGET (x);
diff --git a/src/gtkutil.h b/src/gtkutil.h
index 288b3e99299..482331a8934 100644
--- a/src/gtkutil.h
+++ b/src/gtkutil.h
@@ -55,7 +55,7 @@ typedef struct xg_menu_cb_data_
{
xg_list_node ptrs;
- FRAME_PTR f;
+ struct frame *f;
Lisp_Object menu_bar_vector;
int menu_bar_items_used;
GCallback highlight_cb;
@@ -81,46 +81,46 @@ extern void free_widget_value (struct _widget_value *);
extern bool xg_uses_old_file_dialog (void) ATTRIBUTE_CONST;
-extern char *xg_get_file_name (FRAME_PTR f,
+extern char *xg_get_file_name (struct frame *f,
char *prompt,
char *default_filename,
bool mustmatch_p,
bool only_dir_p);
-extern Lisp_Object xg_get_font (FRAME_PTR f, const char *);
+extern Lisp_Object xg_get_font (struct frame *f, const char *);
extern GtkWidget *xg_create_widget (const char *type,
const char *name,
- FRAME_PTR f,
+ struct frame *f,
struct _widget_value *val,
GCallback select_cb,
GCallback deactivate_cb,
GCallback highlight_cb);
extern void xg_modify_menubar_widgets (GtkWidget *menubar,
- FRAME_PTR f,
+ struct frame *f,
struct _widget_value *val,
bool deep_p,
GCallback select_cb,
GCallback deactivate_cb,
GCallback highlight_cb);
-extern void xg_update_frame_menubar (FRAME_PTR f);
+extern void xg_update_frame_menubar (struct frame *f);
-extern bool xg_event_is_for_menubar (FRAME_PTR f, XEvent *event);
+extern bool xg_event_is_for_menubar (struct frame *f, XEvent *event);
extern bool xg_have_tear_offs (void);
extern ptrdiff_t xg_get_scroll_id_for_window (Display *dpy, Window wid);
-extern void xg_create_scroll_bar (FRAME_PTR f,
+extern void xg_create_scroll_bar (struct frame *f,
struct scroll_bar *bar,
GCallback scroll_callback,
GCallback end_callback,
const char *scroll_bar_name);
-extern void xg_remove_scroll_bar (FRAME_PTR f, ptrdiff_t scrollbar_id);
+extern void xg_remove_scroll_bar (struct frame *f, ptrdiff_t scrollbar_id);
-extern void xg_update_scrollbar_pos (FRAME_PTR f,
+extern void xg_update_scrollbar_pos (struct frame *f,
ptrdiff_t scrollbar_id,
int top,
int left,
@@ -131,40 +131,40 @@ extern void xg_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar,
int portion,
int position,
int whole);
-extern bool xg_event_is_for_scrollbar (FRAME_PTR f, XEvent *event);
+extern bool xg_event_is_for_scrollbar (struct frame *f, XEvent *event);
extern int xg_get_default_scrollbar_width (void);
-extern void update_frame_tool_bar (FRAME_PTR f);
-extern void free_frame_tool_bar (FRAME_PTR f);
-extern void xg_change_toolbar_position (FRAME_PTR f, Lisp_Object pos);
+extern void update_frame_tool_bar (struct frame *f);
+extern void free_frame_tool_bar (struct frame *f);
+extern void xg_change_toolbar_position (struct frame *f, Lisp_Object pos);
-extern void xg_frame_resized (FRAME_PTR f,
+extern void xg_frame_resized (struct frame *f,
int pixelwidth,
int pixelheight);
-extern void xg_frame_set_char_size (FRAME_PTR f, int cols, int rows);
+extern void xg_frame_set_char_size (struct frame *f, int cols, int rows);
extern GtkWidget * xg_win_to_widget (Display *dpy, Window wdesc);
extern void xg_display_open (char *display_name, Display **dpy);
extern void xg_display_close (Display *dpy);
extern GdkCursor * xg_create_default_cursor (Display *dpy);
-extern bool xg_create_frame_widgets (FRAME_PTR f);
-extern void xg_free_frame_widgets (FRAME_PTR f);
-extern void xg_set_background_color (FRAME_PTR f, unsigned long bg);
+extern bool xg_create_frame_widgets (struct frame *f);
+extern void xg_free_frame_widgets (struct frame *f);
+extern void xg_set_background_color (struct frame *f, unsigned long bg);
extern bool xg_check_special_colors (struct frame *f,
const char *color_name,
XColor *color);
-extern void xg_set_frame_icon (FRAME_PTR f,
+extern void xg_set_frame_icon (struct frame *f,
Pixmap icon_pixmap,
Pixmap icon_mask);
-extern bool xg_prepare_tooltip (FRAME_PTR f,
+extern bool xg_prepare_tooltip (struct frame *f,
Lisp_Object string,
int *width,
int *height);
-extern void xg_show_tooltip (FRAME_PTR f, int root_x, int root_y);
-extern bool xg_hide_tooltip (FRAME_PTR f);
+extern void xg_show_tooltip (struct frame *f, int root_x, int root_y);
+extern bool xg_hide_tooltip (struct frame *f);
/* Mark all callback data that are Lisp_object:s during GC. */
diff --git a/src/image.c b/src/image.c
index 1f8cb520dca..911ca8e6681 100644
--- a/src/image.c
+++ b/src/image.c
@@ -164,20 +164,20 @@ XPutPixel (XImagePtr ximage, int x, int y, unsigned long pixel)
/* Functions to access the contents of a bitmap, given an id. */
int
-x_bitmap_height (FRAME_PTR f, ptrdiff_t id)
+x_bitmap_height (struct frame *f, ptrdiff_t id)
{
return FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].height;
}
int
-x_bitmap_width (FRAME_PTR f, ptrdiff_t id)
+x_bitmap_width (struct frame *f, ptrdiff_t id)
{
return FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].width;
}
#if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
ptrdiff_t
-x_bitmap_pixmap (FRAME_PTR f, ptrdiff_t id)
+x_bitmap_pixmap (struct frame *f, ptrdiff_t id)
{
/* HAVE_NTGUI needs the explicit cast here. */
return (ptrdiff_t) FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].pixmap;
@@ -186,7 +186,7 @@ x_bitmap_pixmap (FRAME_PTR f, ptrdiff_t id)
#ifdef HAVE_X_WINDOWS
int
-x_bitmap_mask (FRAME_PTR f, ptrdiff_t id)
+x_bitmap_mask (struct frame *f, ptrdiff_t id)
{
return FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].mask;
}
@@ -195,7 +195,7 @@ x_bitmap_mask (FRAME_PTR f, ptrdiff_t id)
/* Allocate a new bitmap record. Returns index of new record. */
static ptrdiff_t
-x_allocate_bitmap_record (FRAME_PTR f)
+x_allocate_bitmap_record (struct frame *f)
{
Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
ptrdiff_t i;
@@ -216,7 +216,7 @@ x_allocate_bitmap_record (FRAME_PTR f)
/* Add one reference to the reference count of the bitmap with id ID. */
void
-x_reference_bitmap (FRAME_PTR f, ptrdiff_t id)
+x_reference_bitmap (struct frame *f, ptrdiff_t id)
{
++FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].refcount;
}
@@ -384,7 +384,7 @@ free_bitmap_record (Display_Info *dpyinfo, Bitmap_Record *bm)
/* Remove reference to bitmap with id number ID. */
void
-x_destroy_bitmap (FRAME_PTR f, ptrdiff_t id)
+x_destroy_bitmap (struct frame *f, ptrdiff_t id)
{
Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
diff --git a/src/insdel.c b/src/insdel.c
index 15d585568a0..58c3e15c233 100644
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -1211,12 +1211,9 @@ adjust_after_replace (ptrdiff_t from, ptrdiff_t from_byte,
adjust_markers_for_insert (from, from_byte,
from + len, from_byte + len_byte, 0);
- if (! EQ (BVAR (current_buffer, undo_list), Qt))
- {
- if (nchars_del > 0)
- record_delete (from, prev_text);
- record_insert (from, len);
- }
+ if (nchars_del > 0)
+ record_delete (from, prev_text);
+ record_insert (from, len);
if (len > nchars_del)
adjust_overlays_for_insert (from, len - nchars_del);
@@ -1373,12 +1370,12 @@ replace_range (ptrdiff_t from, ptrdiff_t to, Lisp_Object new,
emacs_abort ();
#endif
- if (! EQ (BVAR (current_buffer, undo_list), Qt))
+ /* Record the insertion first, so that when we undo,
+ the deletion will be undone first. Thus, undo
+ will insert before deleting, and thus will keep
+ the markers before and after this text separate. */
+ if (!NILP (deletion))
{
- /* Record the insertion first, so that when we undo,
- the deletion will be undone first. Thus, undo
- will insert before deleting, and thus will keep
- the markers before and after this text separate. */
record_insert (from + SCHARS (deletion), inschars);
record_delete (from, deletion);
}
@@ -1718,8 +1715,7 @@ del_range_2 (ptrdiff_t from, ptrdiff_t from_byte,
so that undo handles this after reinserting the text. */
adjust_markers_for_delete (from, from_byte, to, to_byte);
- if (! EQ (BVAR (current_buffer, undo_list), Qt))
- record_delete (from, deletion);
+ record_delete (from, deletion);
MODIFF++;
CHARS_MODIFF = MODIFF;
diff --git a/src/keyboard.c b/src/keyboard.c
index 830f70bc1f5..c026b16e689 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -1281,7 +1281,7 @@ static
#endif
bool ignore_mouse_drag_p;
-static FRAME_PTR
+static struct frame *
some_mouse_moved (void)
{
Lisp_Object tail, frame;
@@ -2163,7 +2163,7 @@ show_help_echo (Lisp_Object help, Lisp_Object window, Lisp_Object object,
This causes trouble if we are trying to read a mouse motion
event (i.e., if we are inside a `track-mouse' form), so we
restore the mouse_moved flag. */
- FRAME_PTR f = NILP (do_mouse_tracking) ? NULL : some_mouse_moved ();
+ struct frame *f = NILP (do_mouse_tracking) ? NULL : some_mouse_moved ();
help = call1 (Qmouse_fixup_help_message, help);
if (f)
f->mouse_moved = 1;
@@ -4152,7 +4152,7 @@ kbd_buffer_get_event (KBOARD **kbp,
/* Try generating a mouse motion event. */
else if (!NILP (do_mouse_tracking) && some_mouse_moved ())
{
- FRAME_PTR f = some_mouse_moved ();
+ struct frame *f = some_mouse_moved ();
Lisp_Object bar_window;
enum scroll_bar_part part;
Lisp_Object x, y;
@@ -5898,7 +5898,7 @@ make_lispy_event (struct input_event *event)
case DRAG_N_DROP_EVENT:
{
- FRAME_PTR f;
+ struct frame *f;
Lisp_Object head, position;
Lisp_Object files;
@@ -5977,7 +5977,7 @@ make_lispy_event (struct input_event *event)
#ifdef HAVE_GPM
case GPM_CLICK_EVENT:
{
- FRAME_PTR f = XFRAME (event->frame_or_window);
+ struct frame *f = XFRAME (event->frame_or_window);
Lisp_Object head, position;
Lisp_Object *start_pos_ptr;
Lisp_Object start_pos;
@@ -6031,7 +6031,7 @@ make_lispy_event (struct input_event *event)
}
static Lisp_Object
-make_lispy_movement (FRAME_PTR frame, Lisp_Object bar_window, enum scroll_bar_part part,
+make_lispy_movement (struct frame *frame, Lisp_Object bar_window, enum scroll_bar_part part,
Lisp_Object x, Lisp_Object y, Time t)
{
/* Is it a scroll bar movement? */
diff --git a/src/lisp.h b/src/lisp.h
index 254ead231b9..5daddb7d335 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3302,6 +3302,7 @@ extern struct hash_table_test hashtest_eql, hashtest_equal;
extern Lisp_Object substring_both (Lisp_Object, ptrdiff_t, ptrdiff_t,
ptrdiff_t, ptrdiff_t);
+extern Lisp_Object merge (Lisp_Object, Lisp_Object, Lisp_Object);
extern Lisp_Object do_yes_or_no_p (Lisp_Object);
extern Lisp_Object concat2 (Lisp_Object, Lisp_Object);
extern Lisp_Object concat3 (Lisp_Object, Lisp_Object, Lisp_Object);
diff --git a/src/menu.c b/src/menu.c
index 6b4a22d3052..6fce5b91caf 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -867,7 +867,8 @@ update_submenu_strings (widget_value *first_wv)
VECTOR is an array of menu events for the whole menu. */
void
-find_and_call_menu_selection (FRAME_PTR f, int menu_bar_items_used, Lisp_Object vector, void *client_data)
+find_and_call_menu_selection (struct frame *f, int menu_bar_items_used,
+ Lisp_Object vector, void *client_data)
{
Lisp_Object prefix, entry;
Lisp_Object *subprefix_stack;
@@ -950,7 +951,7 @@ find_and_call_menu_selection (FRAME_PTR f, int menu_bar_items_used, Lisp_Object
/* As above, but return the menu selection instead of storing in kb buffer.
If KEYMAPS, return full prefixes to selection. */
Lisp_Object
-find_and_return_menu_selection (FRAME_PTR f, bool keymaps, void *client_data)
+find_and_return_menu_selection (struct frame *f, bool keymaps, void *client_data)
{
Lisp_Object prefix, entry;
int i;
@@ -1060,7 +1061,7 @@ no quit occurs and `x-popup-menu' returns nil. */)
Lisp_Object title;
const char *error_name = NULL;
Lisp_Object selection = Qnil;
- FRAME_PTR f = NULL;
+ struct frame *f = NULL;
Lisp_Object x, y, window;
bool keymaps = 0;
bool for_click = 0;
@@ -1116,7 +1117,7 @@ no quit occurs and `x-popup-menu' returns nil. */)
if (get_current_pos_p)
{
/* Use the mouse's current position. */
- FRAME_PTR new_f = SELECTED_FRAME ();
+ struct frame *new_f = SELECTED_FRAME ();
#ifdef HAVE_X_WINDOWS
/* Can't use mouse_position_hook for X since it returns
coordinates relative to the window the mouse is in,
diff --git a/src/menu.h b/src/menu.h
index f60873eadb3..0f94ad8000b 100644
--- a/src/menu.h
+++ b/src/menu.h
@@ -35,20 +35,20 @@ extern void list_of_panes (Lisp_Object);
|| defined (HAVE_NS)
extern void free_menubar_widget_value_tree (widget_value *);
extern void update_submenu_strings (widget_value *);
-extern void find_and_call_menu_selection (FRAME_PTR, int,
+extern void find_and_call_menu_selection (struct frame *, int,
Lisp_Object, void *);
extern widget_value *xmalloc_widget_value (void);
extern widget_value *digest_single_submenu (int, int, bool);
#endif
#ifdef HAVE_X_WINDOWS
-extern void mouse_position_for_popup (FRAME_PTR f, int *x, int *y);
+extern void mouse_position_for_popup (struct frame *f, int *x, int *y);
#endif
-extern Lisp_Object w32_menu_show (FRAME_PTR, int, int, int, int,
+extern Lisp_Object w32_menu_show (struct frame *, int, int, int, int,
Lisp_Object, const char **);
-extern Lisp_Object ns_menu_show (FRAME_PTR, int, int, bool, bool,
+extern Lisp_Object ns_menu_show (struct frame *, int, int, bool, bool,
Lisp_Object, const char **);
-extern Lisp_Object xmenu_show (FRAME_PTR, int, int, bool, bool,
+extern Lisp_Object xmenu_show (struct frame *, int, int, bool, bool,
Lisp_Object, const char **, Time);
#endif /* MENU_H */
diff --git a/src/msdos.c b/src/msdos.c
index a2bcc06ac17..88a2eb60726 100644
--- a/src/msdos.c
+++ b/src/msdos.c
@@ -298,7 +298,7 @@ mouse_button_depressed (int b, int *xp, int *yp)
}
void
-mouse_get_pos (FRAME_PTR *f, int insist, Lisp_Object *bar_window,
+mouse_get_pos (struct frame **f, int insist, Lisp_Object *bar_window,
enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y,
Time *time)
{
@@ -1158,7 +1158,7 @@ IT_display_cursor (int on)
to put the cursor at the end of the text displayed there. */
static void
-IT_cmgoto (FRAME_PTR f)
+IT_cmgoto (struct frame *f)
{
/* Only set the cursor to where it should be if the display is
already in sync with the window contents. */
@@ -1760,7 +1760,7 @@ IT_set_frame_parameters (struct frame *f, Lisp_Object alist)
}
}
-extern void init_frame_faces (FRAME_PTR);
+extern void init_frame_faces (struct frame *);
#endif /* !HAVE_X_WINDOWS */
@@ -3320,18 +3320,6 @@ XMenuDestroy (Display *foo, XMenu *menu)
xfree (menu);
menu_help_message = prev_menu_help_message = NULL;
}
-
-int
-x_pixel_width (struct frame *f)
-{
- return FRAME_COLS (f);
-}
-
-int
-x_pixel_height (struct frame *f)
-{
- return FRAME_LINES (f);
-}
#endif /* !HAVE_X_WINDOWS */
/* ----------------------- DOS / UNIX conversion --------------------- */
diff --git a/src/msdos.h b/src/msdos.h
index ee0d49464ae..6a6fe349131 100644
--- a/src/msdos.h
+++ b/src/msdos.h
@@ -74,8 +74,6 @@ struct window;
/* Defined in xfns.c; emulated on msdos.c */
extern void x_set_menu_bar_lines (struct frame *, Lisp_Object, Lisp_Object);
-extern int x_pixel_width (struct frame *);
-extern int x_pixel_height (struct frame *);
#define XFreeGC (void)
#define x_destroy_bitmap(p1,p2)
diff --git a/src/nsfns.m b/src/nsfns.m
index 121ac539646..3f43afde787 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -143,7 +143,7 @@ check_ns_display_info (Lisp_Object object)
dpyinfo = ns_display_info_for_name (object);
else
{
- FRAME_PTR f = decode_window_system_frame (object);
+ struct frame *f = decode_window_system_frame (object);
dpyinfo = FRAME_NS_DISPLAY_INFO (f);
}
@@ -431,7 +431,7 @@ x_set_icon_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
}
static void
-ns_set_name_internal (FRAME_PTR f, Lisp_Object name)
+ns_set_name_internal (struct frame *f, Lisp_Object name)
{
struct gcpro gcpro1;
Lisp_Object encoded_name, encoded_icon_name;
@@ -503,7 +503,7 @@ ns_set_name (struct frame *f, Lisp_Object name, int explicit)
specified a name for the frame; the name will override any set by the
redisplay code. */
static void
-x_explicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval)
+x_explicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
{
NSTRACE (x_explicitly_set_name);
ns_set_name (f, arg, 1);
@@ -514,7 +514,7 @@ x_explicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval)
name; names set this way will never override names set by the user's
lisp code. */
void
-x_implicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval)
+x_implicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
{
NSTRACE (x_implicitly_set_name);
@@ -857,7 +857,7 @@ ns_cursor_type_to_lisp (int arg)
/* This is the same as the xfns.c definition. */
static void
-x_set_cursor_type (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval)
+x_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
{
set_frame_cursor_types (f, arg);
@@ -1068,7 +1068,7 @@ This function is an internal primitive--use `make-frame' instead. */)
Lisp_Object frame, tem;
Lisp_Object name;
int minibuffer_only = 0;
- int window_prompting = 0;
+ long window_prompting = 0;
int width, height;
ptrdiff_t count = specpdl_ptr - specpdl;
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
@@ -2231,21 +2231,6 @@ x_get_focus_frame (struct frame *frame)
return nsfocus;
}
-
-int
-x_pixel_width (struct frame *f)
-{
- return FRAME_PIXEL_WIDTH (f);
-}
-
-
-int
-x_pixel_height (struct frame *f)
-{
- return FRAME_PIXEL_HEIGHT (f);
-}
-
-
void
x_sync (struct frame *f)
{
diff --git a/src/nsfont.m b/src/nsfont.m
index df7ef0bb0bc..ad169d7ddae 100644
--- a/src/nsfont.m
+++ b/src/nsfont.m
@@ -619,13 +619,13 @@ ns_findfonts (Lisp_Object font_spec, BOOL isMatch)
========================================================================== */
-static Lisp_Object nsfont_get_cache (FRAME_PTR frame);
-static Lisp_Object nsfont_list (Lisp_Object frame, Lisp_Object font_spec);
-static Lisp_Object nsfont_match (Lisp_Object frame, Lisp_Object font_spec);
-static Lisp_Object nsfont_list_family (Lisp_Object frame);
-static Lisp_Object nsfont_open (FRAME_PTR f, Lisp_Object font_entity,
+static Lisp_Object nsfont_get_cache (struct frame *frame);
+static Lisp_Object nsfont_list (struct frame *, Lisp_Object);
+static Lisp_Object nsfont_match (struct frame *, Lisp_Object);
+static Lisp_Object nsfont_list_family (struct frame *);
+static Lisp_Object nsfont_open (struct frame *f, Lisp_Object font_entity,
int pixel_size);
-static void nsfont_close (FRAME_PTR f, struct font *font);
+static void nsfont_close (struct frame *f, struct font *font);
static int nsfont_has_char (Lisp_Object entity, int c);
static unsigned int nsfont_encode_char (struct font *font, int c);
static int nsfont_text_extents (struct font *font, unsigned int *code,
@@ -659,7 +659,7 @@ struct font_driver nsfont_driver =
/* Return a cache of font-entities on FRAME. The cache must be a
cons whose cdr part is the actual cache area. */
static Lisp_Object
-nsfont_get_cache (FRAME_PTR frame)
+nsfont_get_cache (struct frame *frame)
{
Display_Info *dpyinfo = FRAME_NS_DISPLAY_INFO (frame);
return (dpyinfo->name_list_element);
@@ -679,9 +679,9 @@ nsfont_get_cache (FRAME_PTR frame)
weight, slant, width, size (0 if scalable),
dpi, spacing, avgwidth (0 if scalable) */
static Lisp_Object
-nsfont_list (Lisp_Object frame, Lisp_Object font_spec)
+nsfont_list (struct frame *f, Lisp_Object font_spec)
{
- return ns_findfonts (font_spec, NO);
+ return ns_findfonts (font_spec, NO);
}
@@ -690,16 +690,16 @@ nsfont_list (Lisp_Object frame, Lisp_Object font_spec)
`face-font-selection-order' is ignored here.
Properties to be considered are same as for list(). */
static Lisp_Object
-nsfont_match (Lisp_Object frame, Lisp_Object font_spec)
+nsfont_match (struct frame *f, Lisp_Object font_spec)
{
- return ns_findfonts(font_spec, YES);
+ return ns_findfonts (font_spec, YES);
}
/* List available families. The value is a list of family names
(symbols). */
static Lisp_Object
-nsfont_list_family (Lisp_Object frame)
+nsfont_list_family (struct frame *f)
{
Lisp_Object list = Qnil;
NSEnumerator *families;
@@ -724,7 +724,7 @@ nsfont_list_family (Lisp_Object frame)
/* Open a font specified by FONT_ENTITY on frame F. If the font is
scalable, open it with PIXEL_SIZE. */
static Lisp_Object
-nsfont_open (FRAME_PTR f, Lisp_Object font_entity, int pixel_size)
+nsfont_open (struct frame *f, Lisp_Object font_entity, int pixel_size)
{
BOOL synthItal;
unsigned int traits = 0;
@@ -931,7 +931,7 @@ nsfont_open (FRAME_PTR f, Lisp_Object font_entity, int pixel_size)
/* Close FONT on frame F. */
static void
-nsfont_close (FRAME_PTR f, struct font *font)
+nsfont_close (struct frame *f, struct font *font)
{
struct nsfont_info *font_info = (struct nsfont_info *)font;
int i;
diff --git a/src/nsmenu.m b/src/nsmenu.m
index 02fe0b04ca0..464be89c524 100644
--- a/src/nsmenu.m
+++ b/src/nsmenu.m
@@ -806,7 +806,7 @@ extern NSString *NSMenuDidBeginTrackingNotification;
========================================================================== */
Lisp_Object
-ns_menu_show (FRAME_PTR f, int x, int y, bool for_click, bool keymaps,
+ns_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
Lisp_Object title, const char **error)
{
EmacsMenu *pmenu;
@@ -1028,7 +1028,7 @@ ns_menu_show (FRAME_PTR f, int x, int y, bool for_click, bool keymaps,
========================================================================== */
void
-free_frame_tool_bar (FRAME_PTR f)
+free_frame_tool_bar (struct frame *f)
/* --------------------------------------------------------------------------
Under NS we just hide the toolbar until it might be needed again.
-------------------------------------------------------------------------- */
@@ -1040,7 +1040,7 @@ free_frame_tool_bar (FRAME_PTR f)
}
void
-update_frame_tool_bar (FRAME_PTR f)
+update_frame_tool_bar (struct frame *f)
/* --------------------------------------------------------------------------
Update toolbar contents
-------------------------------------------------------------------------- */
diff --git a/src/nsterm.h b/src/nsterm.h
index 745b8a4145b..1303a475547 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -109,7 +109,10 @@ typedef float EmacsCGFloat;
@interface EmacsView : NSView <NSTextInput>
#endif
{
+#ifdef NS_IMPL_COCOA
char *old_title;
+ BOOL maximizing_resize;
+#endif
BOOL windowClosing;
NSString *workingText;
BOOL processingCompose;
@@ -778,7 +781,7 @@ void ns_dump_glyphstring (struct glyph_string *s);
/* Implemented in nsterm, published in or needed from nsfns. */
extern Lisp_Object Qfontsize;
-extern Lisp_Object ns_list_fonts (FRAME_PTR f, Lisp_Object pattern,
+extern Lisp_Object ns_list_fonts (struct frame *f, Lisp_Object pattern,
int size, int maxnames);
extern void ns_clear_frame (struct frame *f);
@@ -824,11 +827,11 @@ extern void ns_release_autorelease_pool (void *);
extern const char *ns_get_defaults_value (const char *key);
/* in nsmenu */
-extern void update_frame_tool_bar (FRAME_PTR f);
-extern void free_frame_tool_bar (FRAME_PTR f);
-extern void find_and_call_menu_selection (FRAME_PTR f,
+extern void update_frame_tool_bar (struct frame *f);
+extern void free_frame_tool_bar (struct frame *f);
+extern void find_and_call_menu_selection (struct frame *f,
int menu_bar_items_used, Lisp_Object vector, void *client_data);
-extern Lisp_Object find_and_return_menu_selection (FRAME_PTR f,
+extern Lisp_Object find_and_return_menu_selection (struct frame *f,
bool keymaps,
void *client_data);
extern Lisp_Object ns_popup_dialog (Lisp_Object position, Lisp_Object contents,
diff --git a/src/nsterm.m b/src/nsterm.m
index 14706f6b91d..3672c7656da 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -1353,7 +1353,7 @@ x_set_window_size (struct frame *f, int change_grav, int cols, int rows)
static void
-ns_fullscreen_hook (FRAME_PTR f)
+ns_fullscreen_hook (struct frame *f)
{
EmacsView *view = (EmacsView *)FRAME_NS_VIEW (f);
@@ -1883,10 +1883,9 @@ ns_frame_up_to_date (struct frame *f)
{
block_input ();
ns_update_begin(f);
- if (hlinfo->mouse_face_mouse_frame)
- note_mouse_highlight (hlinfo->mouse_face_mouse_frame,
- hlinfo->mouse_face_mouse_x,
- hlinfo->mouse_face_mouse_y);
+ note_mouse_highlight (hlinfo->mouse_face_mouse_frame,
+ hlinfo->mouse_face_mouse_x,
+ hlinfo->mouse_face_mouse_y);
ns_update_end(f);
unblock_input ();
}
@@ -3863,15 +3862,6 @@ ns_judge_scroll_bars (struct frame *f)
[eview updateFrameSize: NO];
}
-
-void
-x_wm_set_icon_position (struct frame *f, int icon_x, int icon_y)
-{
- /* XXX irrelevant under NS */
-}
-
-
-
/* ==========================================================================
Initialization
@@ -5673,17 +5663,17 @@ not_in_argv (NSString *arg)
old_title = 0;
}
}
- else
+ else if (fs_state == FULLSCREEN_NONE && ! maximizing_resize)
{
char *size_title;
NSWindow *window = [self window];
if (old_title == 0)
{
- const char *t = [[[self window] title] UTF8String];
+ char *t = strdup ([[[self window] title] UTF8String]);
char *pos = strstr (t, " — ");
if (pos)
*pos = '\0';
- old_title = xstrdup (t);
+ old_title = t;
}
size_title = xmalloc (strlen (old_title) + 40);
esprintf (size_title, "%s — (%d x %d)", old_title, cols, rows);
@@ -5722,21 +5712,27 @@ not_in_argv (NSString *arg)
NSTRACE (windowDidResize);
/*fprintf (stderr,"windowDidResize: %.0f\n",[theWindow frame].size.height); */
+if (cols > 0 && rows > 0)
+ {
+ [self updateFrameSize: YES];
+ }
+
+ ns_send_appdefined (-1);
+}
+
#ifdef NS_IMPL_COCOA
+- (void)viewDidEndLiveResize
+{
+ [super viewDidEndLiveResize];
if (old_title != 0)
{
+ [[self window] setTitle: [NSString stringWithUTF8String: old_title]];
xfree (old_title);
old_title = 0;
}
-#endif /* NS_IMPL_COCOA */
-
- if (cols > 0 && rows > 0)
- {
- [self updateFrameSize: YES];
- }
-
- ns_send_appdefined (-1);
+ maximizing_resize = NO;
}
+#endif /* NS_IMPL_COCOA */
- (void)windowDidBecomeKey: (NSNotification *)notification
@@ -5841,7 +5837,10 @@ not_in_argv (NSString *arg)
FRAME_NS_VIEW (f) = self;
emacsframe = f;
+#ifdef NS_IMPL_COCOA
old_title = 0;
+ maximizing_resize = NO;
+#endif
win = [[EmacsWindow alloc]
initWithContentRect: r
@@ -5984,6 +5983,9 @@ not_in_argv (NSString *arg)
maximized_width = -1;
result.origin.y = defaultFrame.origin.y;
[self setFSValue: FULLSCREEN_HEIGHT];
+#ifdef NS_IMPL_COCOA
+ maximizing_resize = YES;
+#endif
}
else if (next_maximized == FULLSCREEN_WIDTH)
{
@@ -6002,12 +6004,18 @@ not_in_argv (NSString *arg)
maximized_width = result.size.width;
maximized_height = result.size.height;
[self setFSValue: FULLSCREEN_MAXIMIZED];
+#ifdef NS_IMPL_COCOA
+ maximizing_resize = YES;
+#endif
}
else
{
/* restore */
result = ns_userRect.size.height ? ns_userRect : result;
ns_userRect = NSMakeRect (0, 0, 0, 0);
+#ifdef NS_IMPL_COCOA
+ maximizing_resize = fs_state != FULLSCREEN_NONE;
+#endif
[self setFSValue: FULLSCREEN_NONE];
maximized_width = maximized_height = -1;
}
diff --git a/src/scroll.c b/src/scroll.c
index 037e338c696..3e296068e8f 100644
--- a/src/scroll.c
+++ b/src/scroll.c
@@ -86,7 +86,7 @@ static void do_scrolling (struct frame *,
new contents appears. */
static void
-calculate_scrolling (FRAME_PTR frame,
+calculate_scrolling (struct frame *frame,
/* matrix is of size window_size + 1 on each side. */
struct matrix_elt *matrix,
int window_size, int lines_below,
@@ -422,7 +422,7 @@ do_scrolling (struct frame *frame, struct glyph_matrix *current_matrix,
is the equivalent of draw_cost for the old line contents */
static void
-calculate_direct_scrolling (FRAME_PTR frame,
+calculate_direct_scrolling (struct frame *frame,
/* matrix is of size window_size + 1 on each side. */
struct matrix_elt *matrix,
int window_size, int lines_below,
@@ -793,7 +793,7 @@ do_direct_scrolling (struct frame *frame, struct glyph_matrix *current_matrix,
void
-scrolling_1 (FRAME_PTR frame, int window_size, int unchanged_at_top,
+scrolling_1 (struct frame *frame, int window_size, int unchanged_at_top,
int unchanged_at_bottom, int *draw_cost, int *old_draw_cost,
int *old_hash, int *new_hash, int free_at_end)
{
@@ -883,7 +883,7 @@ scrolling_max_lines_saved (int start, int end,
overhead and multiply factor values */
static void
-line_ins_del (FRAME_PTR frame, int ov1, int pf1, int ovn, int pfn,
+line_ins_del (struct frame *frame, int ov1, int pf1, int ovn, int pfn,
register int *ov, register int *mf)
{
register int i;
@@ -901,7 +901,7 @@ line_ins_del (FRAME_PTR frame, int ov1, int pf1, int ovn, int pfn,
}
static void
-ins_del_costs (FRAME_PTR frame,
+ins_del_costs (struct frame *frame,
const char *one_line_string, const char *multi_string,
const char *setup_string, const char *cleanup_string,
int *costvec, int *ncostvec,
@@ -957,7 +957,7 @@ ins_del_costs (FRAME_PTR frame,
*/
void
-do_line_insertion_deletion_costs (FRAME_PTR frame,
+do_line_insertion_deletion_costs (struct frame *frame,
const char *ins_line_string,
const char *multi_ins_string,
const char *del_line_string,
diff --git a/src/term.c b/src/term.c
index 376d6e7831a..fb69aefbe7a 100644
--- a/src/term.c
+++ b/src/term.c
@@ -2522,7 +2522,7 @@ tty_draw_row_with_mouse_face (struct window *w, struct glyph_row *row,
}
static bool
-term_mouse_movement (FRAME_PTR frame, Gpm_Event *event)
+term_mouse_movement (struct frame *frame, Gpm_Event *event)
{
/* Has the mouse moved off the glyph it was on at the last sighting? */
if (event->x != last_mouse_x || event->y != last_mouse_y)
@@ -2563,7 +2563,7 @@ timeval_to_Time (struct timeval const *t)
This clears mouse_moved until the next motion
event arrives. */
static void
-term_mouse_position (FRAME_PTR *fp, int insist, Lisp_Object *bar_window,
+term_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
enum scroll_bar_part *part, Lisp_Object *x,
Lisp_Object *y, Time *timeptr)
{
@@ -2933,7 +2933,7 @@ dissociate_if_controlling_tty (int fd)
TERMINAL_TYPE is the termcap type of the device, e.g. "vt100".
- If MUST_SUCCEED is true, then all errors are fatal. */
+ If MUST_SUCCEED is true, then all errors are fatal. */
struct terminal *
init_tty (const char *name, const char *terminal_type, bool must_succeed)
@@ -2944,7 +2944,7 @@ init_tty (const char *name, const char *terminal_type, bool must_succeed)
int status;
struct tty_display_info *tty = NULL;
struct terminal *terminal = NULL;
- bool ctty = 0; /* True if asked to open controlling tty. */
+ bool ctty = false; /* True if asked to open controlling tty. */
if (!terminal_type)
maybe_fatal (must_succeed, 0,
@@ -3031,7 +3031,7 @@ init_tty (const char *name, const char *terminal_type, bool must_succeed)
tty->termcap_term_buffer = xmalloc (buffer_size);
/* On some systems, tgetent tries to access the controlling
- terminal. */
+ terminal. */
block_tty_out_signal ();
status = tgetent (tty->termcap_term_buffer, terminal_type);
unblock_tty_out_signal ();
@@ -3101,13 +3101,13 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
Right (tty) = tgetstr ("nd", address);
Down (tty) = tgetstr ("do", address);
if (!Down (tty))
- Down (tty) = tgetstr ("nl", address); /* Obsolete name for "do" */
+ Down (tty) = tgetstr ("nl", address); /* Obsolete name for "do". */
if (tgetflag ("bs"))
- Left (tty) = "\b"; /* can't possibly be longer! */
- else /* (Actually, "bs" is obsolete...) */
+ Left (tty) = "\b"; /* Can't possibly be longer! */
+ else /* (Actually, "bs" is obsolete...) */
Left (tty) = tgetstr ("le", address);
if (!Left (tty))
- Left (tty) = tgetstr ("bc", address); /* Obsolete name for "le" */
+ Left (tty) = tgetstr ("bc", address); /* Obsolete name for "le". */
tty->TS_pad_char = tgetstr ("pc", address);
tty->TS_repeat = tgetstr ("rp", address);
tty->TS_end_standout_mode = tgetstr ("se", address);
@@ -3229,7 +3229,7 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
don't think we're losing anything by turning it off. */
terminal->line_ins_del_ok = 0;
- tty->TN_max_colors = 16; /* Required to be non-zero for tty-display-color-p */
+ tty->TN_max_colors = 16; /* Must be non-zero for tty-display-color-p. */
#endif /* DOS_NT */
#ifdef HAVE_GPM
@@ -3325,16 +3325,16 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
tty->Wcm->cm_tab = 0;
/* We can't support standout mode, because it uses magic cookies. */
tty->TS_standout_mode = 0;
- /* But that means we cannot rely on ^M to go to column zero! */
+ /* But that means we cannot rely on ^M to go to column zero! */
CR (tty) = 0;
- /* LF can't be trusted either -- can alter hpos */
- /* if move at column 0 thru a line with TS_standout_mode */
+ /* LF can't be trusted either -- can alter hpos. */
+ /* If move at column 0 thru a line with TS_standout_mode. */
Down (tty) = 0;
}
tty->specified_window = FrameRows (tty);
- if (Wcm_init (tty) == -1) /* can't do cursor motion */
+ if (Wcm_init (tty) == -1) /* Can't do cursor motion. */
{
maybe_fatal (must_succeed, terminal,
"Terminal type \"%s\" is not powerful enough to run Emacs",
diff --git a/src/terminal.c b/src/terminal.c
index c55fd4eb077..4b5532e3a44 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -39,6 +39,8 @@ static int next_terminal_id;
/* The initial terminal device, created by initial_term_init. */
struct terminal *initial_terminal;
+static Lisp_Object Qterminal_live_p;
+
static void delete_initial_terminal (struct terminal *);
/* This setter is used only in this file, so it can be private. */
@@ -549,6 +551,8 @@ Each function is called with argument, the terminal.
This may be called just before actually deleting the terminal,
or some time later. */);
Vdelete_terminal_functions = Qnil;
+
+ DEFSYM (Qterminal_live_p, "terminal-live-p");
DEFSYM (Qdelete_terminal_functions, "delete-terminal-functions");
DEFSYM (Qrun_hook_with_args, "run-hook-with-args");
diff --git a/src/w32fns.c b/src/w32fns.c
index 2b06936d119..dff35de0973 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -285,7 +285,7 @@ check_x_display_info (Lisp_Object frame)
return x_display_info_for_name (frame);
else
{
- FRAME_PTR f;
+ struct frame *f;
CHECK_LIVE_FRAME (frame);
f = XFRAME (frame);
@@ -344,7 +344,7 @@ void x_set_tool_bar_lines (struct frame *, Lisp_Object, Lisp_Object);
not Emacs's own window. */
void
-x_real_positions (FRAME_PTR f, int *xptr, int *yptr)
+x_real_positions (struct frame *f, int *xptr, int *yptr)
{
POINT pt;
RECT rect;
@@ -1019,7 +1019,7 @@ x_to_w32_color (const char * colorname)
}
void
-w32_regenerate_palette (FRAME_PTR f)
+w32_regenerate_palette (struct frame *f)
{
struct w32_palette_entry * list;
LOGPALETTE * log_palette;
@@ -1069,7 +1069,7 @@ w32_regenerate_palette (FRAME_PTR f)
#if 0
/* Keep these around in case we ever want to track color usage. */
void
-w32_map_color (FRAME_PTR f, COLORREF color)
+w32_map_color (struct frame *f, COLORREF color)
{
struct w32_palette_entry * list = FRAME_W32_DISPLAY_INFO (f)->color_list;
@@ -1100,7 +1100,7 @@ w32_map_color (FRAME_PTR f, COLORREF color)
}
void
-w32_unmap_color (FRAME_PTR f, COLORREF color)
+w32_unmap_color (struct frame *f, COLORREF color)
{
struct w32_palette_entry * list = FRAME_W32_DISPLAY_INFO (f)->color_list;
struct w32_palette_entry **prev = &FRAME_W32_DISPLAY_INFO (f)->color_list;
@@ -1153,7 +1153,7 @@ gamma_correct (struct frame *f, COLORREF *color)
If ALLOC is nonzero, allocate a new colormap cell. */
int
-w32_defined_color (FRAME_PTR f, const char *color, XColor *color_def, int alloc)
+w32_defined_color (struct frame *f, const char *color, XColor *color_def, int alloc)
{
register Lisp_Object tem;
COLORREF w32_color_ref;
@@ -1224,7 +1224,7 @@ w32_defined_color (FRAME_PTR f, const char *color, XColor *color_def, int alloc)
ARG says. */
int
-x_decode_color (FRAME_PTR f, Lisp_Object arg, int def)
+x_decode_color (struct frame *f, Lisp_Object arg, int def)
{
XColor cdef;
@@ -1525,7 +1525,7 @@ x_set_border_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
void
-x_set_cursor_type (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval)
+x_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
{
set_frame_cursor_types (f, arg);
@@ -1787,7 +1787,7 @@ x_set_name (struct frame *f, Lisp_Object name, int explicit)
specified a name for the frame; the name will override any set by the
redisplay code. */
void
-x_explicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval)
+x_explicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
{
x_set_name (f, arg, 1);
}
@@ -1796,7 +1796,7 @@ x_explicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval)
name; names set this way will never override names set by the user's
lisp code. */
void
-x_implicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval)
+x_implicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
{
x_set_name (f, arg, 0);
}
@@ -4182,9 +4182,6 @@ x_icon (struct frame *f, Lisp_Object parms)
block_input ();
- if (! EQ (icon_x, Qunbound))
- x_wm_set_icon_position (f, XINT (icon_x), XINT (icon_y));
-
#if 0 /* TODO */
/* Start up iconic or window? */
x_wm_set_window_state
@@ -4648,7 +4645,7 @@ DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
(Lisp_Object color, Lisp_Object frame)
{
XColor foo;
- FRAME_PTR f = decode_window_system_frame (frame);
+ struct frame *f = decode_window_system_frame (frame);
CHECK_STRING (color);
@@ -4663,7 +4660,7 @@ DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
(Lisp_Object color, Lisp_Object frame)
{
XColor foo;
- FRAME_PTR f = decode_window_system_frame (frame);
+ struct frame *f = decode_window_system_frame (frame);
CHECK_STRING (color);
@@ -5139,19 +5136,6 @@ SOUND is nil to use the normal beep. */)
return sound;
}
-
-int
-x_pixel_width (register struct frame *f)
-{
- return FRAME_PIXEL_WIDTH (f);
-}
-
-int
-x_pixel_height (register struct frame *f)
-{
- return FRAME_PIXEL_HEIGHT (f);
-}
-
int
x_screen_planes (register struct frame *f)
{
@@ -6626,7 +6610,7 @@ screen saver if defined.
If optional parameter FRAME is not specified, use selected frame. */)
(Lisp_Object command, Lisp_Object frame)
{
- FRAME_PTR f = decode_window_system_frame (frame);
+ struct frame *f = decode_window_system_frame (frame);
CHECK_NUMBER (command);
diff --git a/src/w32font.c b/src/w32font.c
index 105daa06365..4a97fd90a4e 100644
--- a/src/w32font.c
+++ b/src/w32font.c
@@ -99,7 +99,7 @@ static Lisp_Object Qw32_charset_thai, Qw32_charset_johab, Qw32_charset_mac;
/* Font spacing symbols - defined in font.c. */
extern Lisp_Object Qc, Qp, Qm;
-static void fill_in_logfont (FRAME_PTR, LOGFONT *, Lisp_Object);
+static void fill_in_logfont (struct frame *, LOGFONT *, Lisp_Object);
static BYTE w32_antialias_type (Lisp_Object);
static Lisp_Object lispy_antialias_type (BYTE);
@@ -297,7 +297,7 @@ intern_font_name (char * string)
Return a cache of font-entities on FRAME. The cache must be a
cons whose cdr part is the actual cache area. */
Lisp_Object
-w32font_get_cache (FRAME_PTR f)
+w32font_get_cache (struct frame *f)
{
struct w32_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
@@ -309,9 +309,9 @@ w32font_get_cache (FRAME_PTR f)
is a vector of font-entities. This is the sole API that
allocates font-entities. */
static Lisp_Object
-w32font_list (Lisp_Object frame, Lisp_Object font_spec)
+w32font_list (struct frame *f, Lisp_Object font_spec)
{
- Lisp_Object fonts = w32font_list_internal (frame, font_spec, 0);
+ Lisp_Object fonts = w32font_list_internal (f, font_spec, 0);
FONT_ADD_LOG ("w32font-list", font_spec, fonts);
return fonts;
}
@@ -321,9 +321,9 @@ w32font_list (Lisp_Object frame, Lisp_Object font_spec)
FRAME. The closeness is determined by the font backend, thus
`face-font-selection-order' is ignored here. */
static Lisp_Object
-w32font_match (Lisp_Object frame, Lisp_Object font_spec)
+w32font_match (struct frame *f, Lisp_Object font_spec)
{
- Lisp_Object entity = w32font_match_internal (frame, font_spec, 0);
+ Lisp_Object entity = w32font_match_internal (f, font_spec, 0);
FONT_ADD_LOG ("w32font-match", font_spec, entity);
return entity;
}
@@ -332,12 +332,11 @@ w32font_match (Lisp_Object frame, Lisp_Object font_spec)
List available families. The value is a list of family names
(symbols). */
static Lisp_Object
-w32font_list_family (Lisp_Object frame)
+w32font_list_family (struct frame *f)
{
Lisp_Object list = Qnil;
LOGFONT font_match_pattern;
HDC dc;
- FRAME_PTR f = XFRAME (frame);
memset (&font_match_pattern, 0, sizeof (font_match_pattern));
font_match_pattern.lfCharSet = DEFAULT_CHARSET;
@@ -356,7 +355,7 @@ w32font_list_family (Lisp_Object frame)
Open a font specified by FONT_ENTITY on frame F.
If the font is scalable, open it with PIXEL_SIZE. */
static Lisp_Object
-w32font_open (FRAME_PTR f, Lisp_Object font_entity, int pixel_size)
+w32font_open (struct frame *f, Lisp_Object font_entity, int pixel_size)
{
Lisp_Object font_object
= font_make_object (VECSIZE (struct w32font_info),
@@ -380,7 +379,7 @@ w32font_open (FRAME_PTR f, Lisp_Object font_entity, int pixel_size)
/* w32 implementation of close for font_backend.
Close FONT on frame F. */
void
-w32font_close (FRAME_PTR f, struct font *font)
+w32font_close (struct frame *f, struct font *font)
{
int i;
struct w32font_info *w32_font = (struct w32font_info *) font;
@@ -732,13 +731,13 @@ w32font_free_entity (Lisp_Object entity);
storing some data in FACE->extra. If successful, return 0.
Otherwise, return -1.
static int
-w32font_prepare_face (FRAME_PTR f, struct face *face);
+w32font_prepare_face (struct frame *f, struct face *face);
*/
/* w32 implementation of done_face for font backend.
Optional.
Done FACE for displaying characters by FACE->font on frame F.
static void
-w32font_done_face (FRAME_PTR f, struct face *face); */
+w32font_done_face (struct frame *f, struct face *face); */
/* w32 implementation of get_bitmap for font backend.
Optional.
@@ -811,15 +810,14 @@ w32font_otf_drive (struct font *font, Lisp_Object features,
Additional parameter opentype_only restricts the returned fonts to
opentype fonts, which can be used with the Uniscribe backend. */
Lisp_Object
-w32font_list_internal (Lisp_Object frame, Lisp_Object font_spec, int opentype_only)
+w32font_list_internal (struct frame *f, Lisp_Object font_spec, int opentype_only)
{
struct font_callback_data match_data;
HDC dc;
- FRAME_PTR f = XFRAME (frame);
match_data.orig_font_spec = font_spec;
match_data.list = Qnil;
- match_data.frame = frame;
+ XSETFRAME (match_data.frame, f);
memset (&match_data.pattern, 0, sizeof (LOGFONT));
fill_in_logfont (f, &match_data.pattern, font_spec);
@@ -864,14 +862,13 @@ w32font_list_internal (Lisp_Object frame, Lisp_Object font_spec, int opentype_on
Additional parameter opentype_only restricts the returned fonts to
opentype fonts, which can be used with the Uniscribe backend. */
Lisp_Object
-w32font_match_internal (Lisp_Object frame, Lisp_Object font_spec, int opentype_only)
+w32font_match_internal (struct frame *f, Lisp_Object font_spec, int opentype_only)
{
struct font_callback_data match_data;
HDC dc;
- FRAME_PTR f = XFRAME (frame);
match_data.orig_font_spec = font_spec;
- match_data.frame = frame;
+ XSETFRAME (match_data.frame, f);
match_data.list = Qnil;
memset (&match_data.pattern, 0, sizeof (LOGFONT));
@@ -892,7 +889,7 @@ w32font_match_internal (Lisp_Object frame, Lisp_Object font_spec, int opentype_o
}
int
-w32font_open_internal (FRAME_PTR f, Lisp_Object font_entity,
+w32font_open_internal (struct frame *f, Lisp_Object font_entity,
int pixel_size, Lisp_Object font_object)
{
int len, size;
@@ -1964,7 +1961,7 @@ w32_to_fc_weight (int n)
/* Fill in all the available details of LOGFONT from FONT_SPEC. */
static void
-fill_in_logfont (FRAME_PTR f, LOGFONT *logfont, Lisp_Object font_spec)
+fill_in_logfont (struct frame *f, LOGFONT *logfont, Lisp_Object font_spec)
{
Lisp_Object tmp, extra;
int dpi = FRAME_RES_Y (f);
@@ -2114,7 +2111,7 @@ static void
list_all_matching_fonts (struct font_callback_data *match_data)
{
HDC dc;
- Lisp_Object families = w32font_list_family (match_data->frame);
+ Lisp_Object families = w32font_list_family (XFRAME (match_data->frame));
struct frame *f = XFRAME (match_data->frame);
dc = get_frame_dc (f);
@@ -2467,7 +2464,7 @@ If EXCLUDE-PROPORTIONAL is non-nil, exclude proportional fonts
in the font selection dialog. */)
(Lisp_Object frame, Lisp_Object exclude_proportional)
{
- FRAME_PTR f = decode_window_system_frame (frame);
+ struct frame *f = decode_window_system_frame (frame);
CHOOSEFONT cf;
LOGFONT lf;
TEXTMETRIC tm;
diff --git a/src/w32font.h b/src/w32font.h
index b4345478a22..56220860863 100644
--- a/src/w32font.h
+++ b/src/w32font.h
@@ -63,16 +63,16 @@ struct w32font_info
#define CACHE_BLOCKSIZE 128
-Lisp_Object w32font_get_cache (FRAME_PTR fe);
-Lisp_Object w32font_list_internal (Lisp_Object frame,
+Lisp_Object w32font_get_cache (struct frame *fe);
+Lisp_Object w32font_list_internal (struct frame *f,
Lisp_Object font_spec,
int opentype_only);
-Lisp_Object w32font_match_internal (Lisp_Object frame,
+Lisp_Object w32font_match_internal (struct frame *f,
Lisp_Object font_spec,
int opentype_only);
-int w32font_open_internal (FRAME_PTR f, Lisp_Object font_entity,
+int w32font_open_internal (struct frame *f, Lisp_Object font_entity,
int pixel_size, Lisp_Object font_object);
-void w32font_close (FRAME_PTR f, struct font *font);
+void w32font_close (struct frame *f, struct font *font);
int w32font_has_char (Lisp_Object entity, int c);
int w32font_text_extents (struct font *font, unsigned *code, int nglyphs,
struct font_metrics *metrics);
diff --git a/src/w32inevt.c b/src/w32inevt.c
index 88a3f9739cd..ce36f291b00 100644
--- a/src/w32inevt.c
+++ b/src/w32inevt.c
@@ -103,10 +103,10 @@ fill_queue (BOOL block)
}
/* In a generic, multi-frame world this should take a console handle
- and return the frame for it
+ and return the frame for it.
Right now, there's only one frame so return it. */
-static FRAME_PTR
+static struct frame *
get_frame (void)
{
return SELECTED_FRAME ();
@@ -394,7 +394,7 @@ key_event (KEY_EVENT_RECORD *event, struct input_event *emacs_ev, int *isdead)
/* Mouse position hook. */
void
-w32_console_mouse_position (FRAME_PTR *f,
+w32_console_mouse_position (struct frame **f,
int insist,
Lisp_Object *bar_window,
enum scroll_bar_part *part,
@@ -461,7 +461,7 @@ do_mouse_event (MOUSE_EVENT_RECORD *event,
if (event->dwEventFlags == MOUSE_MOVED)
{
- FRAME_PTR f = SELECTED_FRAME ();
+ struct frame *f = SELECTED_FRAME ();
Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
int mx = event->dwMousePosition.X, my = event->dwMousePosition.Y;
@@ -555,7 +555,7 @@ do_mouse_event (MOUSE_EVENT_RECORD *event,
static void
resize_event (WINDOW_BUFFER_SIZE_RECORD *event)
{
- FRAME_PTR f = get_frame ();
+ struct frame *f = get_frame ();
change_frame_size (f, event->dwSize.Y, event->dwSize.X, 0, 1, 0);
SET_FRAME_GARBAGED (f);
@@ -565,7 +565,7 @@ static void
maybe_generate_resize_event (void)
{
CONSOLE_SCREEN_BUFFER_INFO info;
- FRAME_PTR f = get_frame ();
+ struct frame *f = get_frame ();
GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &info);
diff --git a/src/w32inevt.h b/src/w32inevt.h
index 8a7e4fed06a..070d1ad7b03 100644
--- a/src/w32inevt.h
+++ b/src/w32inevt.h
@@ -23,7 +23,7 @@ extern int w32_console_unicode_input;
extern int w32_console_read_socket (struct terminal *term,
struct input_event *hold_quit);
-extern void w32_console_mouse_position (FRAME_PTR *f, int insist,
+extern void w32_console_mouse_position (struct frame **f, int insist,
Lisp_Object *bar_window,
enum scroll_bar_part *part,
Lisp_Object *x, Lisp_Object *y,
diff --git a/src/w32menu.c b/src/w32menu.c
index 346402b7c6b..34020fa61d2 100644
--- a/src/w32menu.c
+++ b/src/w32menu.c
@@ -100,13 +100,13 @@ MessageBoxW_Proc unicode_message_box = NULL;
Lisp_Object Qdebug_on_next_call;
-void set_frame_menubar (FRAME_PTR, bool, bool);
+void set_frame_menubar (struct frame *, bool, bool);
#ifdef HAVE_DIALOGS
-static Lisp_Object w32_dialog_show (FRAME_PTR, int, Lisp_Object, char**);
+static Lisp_Object w32_dialog_show (struct frame *, int, Lisp_Object, char**);
#else
static int is_simple_dialog (Lisp_Object);
-static Lisp_Object simple_dialog_show (FRAME_PTR, Lisp_Object, Lisp_Object);
+static Lisp_Object simple_dialog_show (struct frame *, Lisp_Object, Lisp_Object);
#endif
static void utf8to16 (unsigned char *, int, WCHAR *);
@@ -137,7 +137,7 @@ If HEADER is non-nil, the frame title for the box is "Information",
otherwise it is "Question". */)
(Lisp_Object position, Lisp_Object contents, Lisp_Object header)
{
- FRAME_PTR f = NULL;
+ struct frame *f = NULL;
Lisp_Object window;
/* Decode the first argument: find the window or frame to use. */
@@ -147,7 +147,7 @@ otherwise it is "Question". */)
{
#if 0 /* Using the frame the mouse is on may not be right. */
/* Use the mouse's current position. */
- FRAME_PTR new_f = SELECTED_FRAME ();
+ struct frame *new_f = SELECTED_FRAME ();
Lisp_Object bar_window;
enum scroll_bar_part part;
Time time;
@@ -206,8 +206,8 @@ otherwise it is "Question". */)
in the middle of frame F. */
Lisp_Object x, y, frame, newpos;
XSETFRAME (frame, f);
- XSETINT (x, x_pixel_width (f) / 2);
- XSETINT (y, x_pixel_height (f) / 2);
+ XSETINT (x, FRAME_PIXEL_WIDTH (f) / 2);
+ XSETINT (y, FRAME_PIXEL_HEIGHT (f) / 2);
newpos = Fcons (Fcons (x, Fcons (y, Qnil)), Fcons (frame, Qnil));
return Fx_popup_menu (newpos,
Fcons (Fcar (contents), Fcons (contents, Qnil)));
@@ -252,7 +252,7 @@ otherwise it is "Question". */)
This way we can safely execute Lisp code. */
void
-x_activate_menubar (FRAME_PTR f)
+x_activate_menubar (struct frame *f)
{
set_frame_menubar (f, 0, 1);
@@ -269,7 +269,7 @@ x_activate_menubar (FRAME_PTR f)
and put the appropriate events into the keyboard buffer. */
void
-menubar_selection_callback (FRAME_PTR f, void * client_data)
+menubar_selection_callback (struct frame *f, void * client_data)
{
Lisp_Object prefix, entry;
Lisp_Object vector;
@@ -361,7 +361,7 @@ menubar_selection_callback (FRAME_PTR f, void * client_data)
it is set the first time this is called, from initialize_frame_menubar. */
void
-set_frame_menubar (FRAME_PTR f, bool first_time, bool deep_p)
+set_frame_menubar (struct frame *f, bool first_time, bool deep_p)
{
HMENU menubar_widget = f->output_data.w32->menubar_widget;
Lisp_Object items;
@@ -613,7 +613,7 @@ set_frame_menubar (FRAME_PTR f, bool first_time, bool deep_p)
is visible. */
void
-initialize_frame_menubar (FRAME_PTR f)
+initialize_frame_menubar (struct frame *f)
{
/* This function is called before the first chance to redisplay
the frame. It has to be, so the frame will have the right size. */
@@ -625,7 +625,7 @@ initialize_frame_menubar (FRAME_PTR f)
This is used when deleting a frame, and when turning off the menu bar. */
void
-free_frame_menubar (FRAME_PTR f)
+free_frame_menubar (struct frame *f)
{
block_input ();
@@ -656,7 +656,7 @@ free_frame_menubar (FRAME_PTR f)
(We return nil on failure, but the value doesn't actually matter.) */
Lisp_Object
-w32_menu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
+w32_menu_show (struct frame *f, int x, int y, int for_click, int keymaps,
Lisp_Object title, const char **error)
{
int i;
@@ -983,7 +983,7 @@ static char * button_names [] = {
"button6", "button7", "button8", "button9", "button10" };
static Lisp_Object
-w32_dialog_show (FRAME_PTR f, int keymaps,
+w32_dialog_show (struct frame *f, int keymaps,
Lisp_Object title, Lisp_Object header,
char **error)
{
@@ -1219,7 +1219,7 @@ is_simple_dialog (Lisp_Object contents)
}
static Lisp_Object
-simple_dialog_show (FRAME_PTR f, Lisp_Object contents, Lisp_Object header)
+simple_dialog_show (struct frame *f, Lisp_Object contents, Lisp_Object header)
{
int answer;
UINT type;
@@ -1699,7 +1699,7 @@ DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p, Smenu_or_popup_active_
(void)
{
#ifdef HAVE_MENUS
- FRAME_PTR f;
+ struct frame *f;
f = SELECTED_FRAME ();
return (f->output_data.w32->menubar_active > 0) ? Qt : Qnil;
#else
diff --git a/src/w32notify.c b/src/w32notify.c
index 95ab298f2d3..a48a83daf53 100644
--- a/src/w32notify.c
+++ b/src/w32notify.c
@@ -129,7 +129,7 @@ send_notifications (BYTE *info, DWORD info_size, void *desc,
volatile int *terminate)
{
int done = 0;
- FRAME_PTR f = SELECTED_FRAME ();
+ struct frame *f = SELECTED_FRAME ();
/* A single buffer is used to communicate all notifications to the
main thread. Since both the main thread and several watcher
diff --git a/src/w32term.c b/src/w32term.c
index b97632dabca..59cfdee86b0 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -181,7 +181,7 @@ int w32_keyboard_codepage;
/* Where the mouse was last time we reported a mouse event. */
static RECT last_mouse_glyph;
-static FRAME_PTR last_mouse_glyph_frame;
+static struct frame *last_mouse_glyph_frame;
/* The scroll bar in which the last motion event occurred.
@@ -249,7 +249,7 @@ static void my_set_focus (struct frame *, HWND);
#endif
static void my_set_foreground_window (HWND);
static void my_destroy_window (struct frame *, HWND);
-static void w32fullscreen_hook (FRAME_PTR);
+static void w32fullscreen_hook (struct frame *);
#ifdef GLYPH_DEBUG
static void x_check_font (struct frame *, struct font *);
@@ -450,7 +450,7 @@ w32_draw_rectangle (HDC hdc, XGCValues *gc, int x, int y,
/* Draw a filled rectangle at the specified position. */
void
-w32_fill_rect (FRAME_PTR f, HDC hdc, COLORREF pix, RECT *lprect)
+w32_fill_rect (struct frame *f, HDC hdc, COLORREF pix, RECT *lprect)
{
HBRUSH hb;
@@ -460,7 +460,7 @@ w32_fill_rect (FRAME_PTR f, HDC hdc, COLORREF pix, RECT *lprect)
}
void
-w32_clear_window (FRAME_PTR f)
+w32_clear_window (struct frame *f)
{
RECT rect;
HDC hdc = get_frame_dc (f);
@@ -3370,7 +3370,7 @@ static MSG last_mouse_motion_event;
static Lisp_Object last_mouse_motion_frame;
static int
-note_mouse_movement (FRAME_PTR frame, MSG *msg)
+note_mouse_movement (struct frame *frame, MSG *msg)
{
int mouse_x = LOWORD (msg->lParam);
int mouse_y = HIWORD (msg->lParam);
@@ -3419,7 +3419,7 @@ note_mouse_movement (FRAME_PTR frame, MSG *msg)
************************************************************************/
static struct scroll_bar *x_window_to_scroll_bar (Window);
-static void x_scroll_bar_report_motion (FRAME_PTR *, Lisp_Object *,
+static void x_scroll_bar_report_motion (struct frame **, Lisp_Object *,
enum scroll_bar_part *,
Lisp_Object *, Lisp_Object *,
unsigned long *);
@@ -3461,11 +3461,11 @@ w32_define_cursor (Window window, Cursor cursor)
movement. */
static void
-w32_mouse_position (FRAME_PTR *fp, int insist, Lisp_Object *bar_window,
+w32_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y,
unsigned long *time)
{
- FRAME_PTR f1;
+ struct frame *f1;
block_input ();
@@ -3696,7 +3696,7 @@ my_create_scrollbar (struct frame * f, struct scroll_bar * bar)
/*#define ATTACH_THREADS*/
static BOOL
-my_show_window (FRAME_PTR f, HWND hwnd, int how)
+my_show_window (struct frame *f, HWND hwnd, int how)
{
#ifndef ATTACH_THREADS
return SendMessage (FRAME_W32_WINDOW (f), WM_EMACS_SHOWWINDOW,
@@ -3816,7 +3816,7 @@ x_scroll_bar_create (struct window *w, int top, int left, int width, int height)
static void
x_scroll_bar_remove (struct scroll_bar *bar)
{
- FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
+ struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
block_input ();
@@ -3979,7 +3979,7 @@ w32_set_vertical_scroll_bar (struct window *w,
`*redeem_scroll_bar_hook' is applied to its window before the judgment. */
static void
-w32_condemn_scroll_bars (FRAME_PTR frame)
+w32_condemn_scroll_bars (struct frame *frame)
{
/* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
while (! NILP (FRAME_SCROLL_BARS (frame)))
@@ -4047,7 +4047,7 @@ w32_redeem_scroll_bar (struct window *window)
last call to `*condemn_scroll_bars_hook'. */
static void
-w32_judge_scroll_bars (FRAME_PTR f)
+w32_judge_scroll_bars (struct frame *f)
{
Lisp_Object bar, next;
@@ -4185,14 +4185,14 @@ w32_scroll_bar_handle_click (struct scroll_bar *bar, W32Msg *msg,
on the scroll bar. */
static void
-x_scroll_bar_report_motion (FRAME_PTR *fp, Lisp_Object *bar_window,
+x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window,
enum scroll_bar_part *part,
Lisp_Object *x, Lisp_Object *y,
unsigned long *time)
{
struct scroll_bar *bar = XSCROLL_BAR (last_mouse_scroll_bar);
Window w = SCROLL_BAR_W32_WINDOW (bar);
- FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
+ struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
int pos;
int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
SCROLLINFO si;
@@ -4244,7 +4244,7 @@ x_scroll_bar_report_motion (FRAME_PTR *fp, Lisp_Object *bar_window,
redraw them. */
void
-x_scroll_bar_clear (FRAME_PTR f)
+x_scroll_bar_clear (struct frame *f)
{
Lisp_Object bar;
@@ -4974,7 +4974,7 @@ w32_read_socket (struct terminal *terminal,
if (f)
{
extern void menubar_selection_callback
- (FRAME_PTR f, void * client_data);
+ (struct frame *f, void * client_data);
menubar_selection_callback (f, (void *)msg.msg.wParam);
}
@@ -5071,7 +5071,7 @@ w32_read_socket (struct terminal *terminal,
FOR_EACH_FRAME (tail, frame)
{
- FRAME_PTR f = XFRAME (frame);
+ struct frame *f = XFRAME (frame);
/* The tooltip has been drawn already. Avoid the
SET_FRAME_GARBAGED below. */
if (EQ (frame, tip_frame))
@@ -5692,7 +5692,7 @@ x_check_fullscreen (struct frame *f)
}
static void
-w32fullscreen_hook (FRAME_PTR f)
+w32fullscreen_hook (struct frame *f)
{
if (FRAME_VISIBLE_P (f))
{
@@ -5889,11 +5889,6 @@ x_focus_on_frame (struct frame *f)
unblock_input ();
}
-void
-x_unfocus_frame (struct frame *f)
-{
-}
-
/* Raise frame F. */
void
x_raise_frame (struct frame *f)
@@ -5969,7 +5964,7 @@ x_lower_frame (struct frame *f)
}
static void
-w32_frame_raise_lower (FRAME_PTR f, int raise_flag)
+w32_frame_raise_lower (struct frame *f, int raise_flag)
{
if (! FRAME_W32_P (f))
return;
@@ -6225,22 +6220,6 @@ x_wm_set_size_hint (struct frame *f, long flags, bool user_position)
leave_crit ();
}
-/* Window manager things */
-void
-x_wm_set_icon_position (struct frame *f, int icon_x, int icon_y)
-{
-#if 0
- Window window = FRAME_W32_WINDOW (f);
-
- f->display.x->wm_hints.flags |= IconPositionHint;
- f->display.x->wm_hints.icon_x = icon_x;
- f->display.x->wm_hints.icon_y = icon_y;
-
- XSetWMHints (FRAME_X_DISPLAY (f), window, &f->display.x->wm_hints);
-#endif
-}
-
-
/***********************************************************************
Fonts
***********************************************************************/
diff --git a/src/w32term.h b/src/w32term.h
index ace58758302..3c9cce35221 100644
--- a/src/w32term.h
+++ b/src/w32term.h
@@ -205,7 +205,7 @@ extern void x_focus_on_frame (struct frame *f);
extern struct w32_display_info *w32_term_init (Lisp_Object,
char *, char *);
-extern int w32_defined_color (FRAME_PTR f, const char *color,
+extern int w32_defined_color (struct frame *f, const char *color,
XColor *color_def, int alloc);
extern void x_set_window_size (struct frame *f, int change_grav,
int cols, int rows);
@@ -218,8 +218,6 @@ extern void x_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y);
extern void x_make_frame_visible (struct frame *f);
extern void x_make_frame_invisible (struct frame *f);
extern void x_iconify_frame (struct frame *f);
-extern int x_pixel_width (struct frame *f);
-extern int x_pixel_height (struct frame *f);
extern void x_set_frame_alpha (struct frame *f);
extern void x_set_menu_bar_lines (struct frame *, Lisp_Object, Lisp_Object);
extern void x_set_tool_bar_lines (struct frame *f,
diff --git a/src/w32uniscribe.c b/src/w32uniscribe.c
index c153c8f3565..b31baa0e65c 100644
--- a/src/w32uniscribe.c
+++ b/src/w32uniscribe.c
@@ -69,28 +69,27 @@ memq_no_quit (Lisp_Object elt, Lisp_Object list)
/* Font backend interface implementation. */
static Lisp_Object
-uniscribe_list (Lisp_Object frame, Lisp_Object font_spec)
+uniscribe_list (struct frame *f, Lisp_Object font_spec)
{
- Lisp_Object fonts = w32font_list_internal (frame, font_spec, 1);
+ Lisp_Object fonts = w32font_list_internal (f, font_spec, 1);
FONT_ADD_LOG ("uniscribe-list", font_spec, fonts);
return fonts;
}
static Lisp_Object
-uniscribe_match (Lisp_Object frame, Lisp_Object font_spec)
+uniscribe_match (struct frame *f, Lisp_Object font_spec)
{
- Lisp_Object entity = w32font_match_internal (frame, font_spec, 1);
+ Lisp_Object entity = w32font_match_internal (f, font_spec, 1);
FONT_ADD_LOG ("uniscribe-match", font_spec, entity);
return entity;
}
static Lisp_Object
-uniscribe_list_family (Lisp_Object frame)
+uniscribe_list_family (struct frame *f)
{
Lisp_Object list = Qnil;
LOGFONT font_match_pattern;
HDC dc;
- FRAME_PTR f = XFRAME (frame);
memset (&font_match_pattern, 0, sizeof (font_match_pattern));
/* Limit enumerated fonts to outline fonts to save time. */
@@ -107,7 +106,7 @@ uniscribe_list_family (Lisp_Object frame)
}
static Lisp_Object
-uniscribe_open (FRAME_PTR f, Lisp_Object font_entity, int pixel_size)
+uniscribe_open (struct frame *f, Lisp_Object font_entity, int pixel_size)
{
Lisp_Object font_object
= font_make_object (VECSIZE (struct uniscribe_font_info),
@@ -136,7 +135,7 @@ uniscribe_open (FRAME_PTR f, Lisp_Object font_entity, int pixel_size)
}
static void
-uniscribe_close (FRAME_PTR f, struct font *font)
+uniscribe_close (struct frame *f, struct font *font)
{
struct uniscribe_font_info *uniscribe_font
= (struct uniscribe_font_info *) font;
@@ -600,8 +599,8 @@ uniscribe_encode_char (struct font *font, int c)
int x, int y, int with_background);
Unused:
- int uniscribe_prepare_face (FRAME_PTR f, struct face *face);
- void uniscribe_done_face (FRAME_PTR f, struct face *face);
+ int uniscribe_prepare_face (struct frame *f, struct face *face);
+ void uniscribe_done_face (struct frame *f, struct face *face);
int uniscribe_get_bitmap (struct font *font, unsigned code,
struct font_bitmap *bitmap, int bits_per_pixel);
void uniscribe_free_bitmap (struct font *font, struct font_bitmap *bitmap);
@@ -609,8 +608,8 @@ uniscribe_encode_char (struct font *font, int c)
void uniscribe_free_outline (struct font *font, void *outline);
int uniscribe_anchor_point (struct font *font, unsigned code,
int index, int *x, int *y);
- int uniscribe_start_for_frame (FRAME_PTR f);
- int uniscribe_end_for_frame (FRAME_PTR f);
+ int uniscribe_start_for_frame (struct frame *f);
+ int uniscribe_end_for_frame (struct frame *f);
*/
diff --git a/src/w32xfns.c b/src/w32xfns.c
index 03611e19768..19c6b72bf89 100644
--- a/src/w32xfns.c
+++ b/src/w32xfns.c
@@ -90,7 +90,7 @@ signal_quit (void)
}
void
-select_palette (FRAME_PTR f, HDC hdc)
+select_palette (struct frame *f, HDC hdc)
{
struct w32_display_info *display_info = FRAME_W32_DISPLAY_INFO (f);
@@ -117,7 +117,7 @@ select_palette (FRAME_PTR f, HDC hdc)
}
void
-deselect_palette (FRAME_PTR f, HDC hdc)
+deselect_palette (struct frame *f, HDC hdc)
{
if (f->output_data.w32->old_palette)
SelectPalette (hdc, f->output_data.w32->old_palette, FALSE);
@@ -126,7 +126,7 @@ deselect_palette (FRAME_PTR f, HDC hdc)
/* Get a DC for frame and select palette for drawing; force an update of
all frames if palette's mapping changes. */
HDC
-get_frame_dc (FRAME_PTR f)
+get_frame_dc (struct frame *f)
{
HDC hdc;
@@ -146,7 +146,7 @@ get_frame_dc (FRAME_PTR f)
}
int
-release_frame_dc (FRAME_PTR f, HDC hdc)
+release_frame_dc (struct frame *f, HDC hdc)
{
int ret;
diff --git a/src/widget.c b/src/widget.c
index e2c8e9fa23f..ec0b506046b 100644
--- a/src/widget.c
+++ b/src/widget.c
@@ -503,26 +503,6 @@ widget_update_wm_size_hints (Widget widget)
update_wm_hints (ew);
}
-
-#if 0
-
-static void
-create_frame_gcs (EmacsFrame ew)
-{
- struct frame *s = ew->emacs_frame.frame;
-
- s->output_data.x->normal_gc
- = XCreateGC (XtDisplay (ew), RootWindowOfScreen (XtScreen (ew)), 0, 0);
- s->output_data.x->reverse_gc
- = XCreateGC (XtDisplay (ew), RootWindowOfScreen (XtScreen (ew)), 0, 0);
- s->output_data.x->cursor_gc
- = XCreateGC (XtDisplay (ew), RootWindowOfScreen (XtScreen (ew)), 0, 0);
- s->output_data.x->black_relief.gc = 0;
- s->output_data.x->white_relief.gc = 0;
-}
-
-#endif /* 0 */
-
static char setup_frame_cursor_bits[] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -683,19 +663,7 @@ EmacsFrameRealize (Widget widget, XtValueMask *mask, XSetWindowAttributes *attrs
static void
EmacsFrameDestroy (Widget widget)
{
- EmacsFrame ew = (EmacsFrame) widget;
- struct frame* s = ew->emacs_frame.frame;
-
- if (! s) emacs_abort ();
- if (! s->output_data.x) emacs_abort ();
-
- block_input ();
- x_free_gcs (s);
- if (s->output_data.x->white_relief.gc)
- XFreeGC (XtDisplay (widget), s->output_data.x->white_relief.gc);
- if (s->output_data.x->black_relief.gc)
- XFreeGC (XtDisplay (widget), s->output_data.x->black_relief.gc);
- unblock_input ();
+ /* All GCs are now freed in x_free_frame_resources. */
}
static void
@@ -838,7 +806,7 @@ void
widget_store_internal_border (Widget widget)
{
EmacsFrame ew = (EmacsFrame) widget;
- FRAME_PTR f = ew->emacs_frame.frame;
+ struct frame *f = ew->emacs_frame.frame;
ew->emacs_frame.internal_border_width = f->internal_border_width;
}
diff --git a/src/window.c b/src/window.c
index 6fd6849c6c3..1b288368884 100644
--- a/src/window.c
+++ b/src/window.c
@@ -3019,7 +3019,7 @@ replace_buffer_in_windows_safely (Lisp_Object buffer)
minimum allowable size. */
void
-check_frame_size (FRAME_PTR frame, int *rows, int *cols)
+check_frame_size (struct frame *frame, int *rows, int *cols)
{
/* For height, we have to see:
how many windows the frame has at minimum (one or two),
@@ -5516,7 +5516,7 @@ the return value is nil. Otherwise the value is t. */)
struct Lisp_Vector *saved_windows;
Lisp_Object new_current_buffer;
Lisp_Object frame;
- FRAME_PTR f;
+ struct frame *f;
ptrdiff_t old_point = -1;
CHECK_WINDOW_CONFIGURATION (configuration);
diff --git a/src/xdisp.c b/src/xdisp.c
index 1da7de5759c..7a1f03ce244 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -1854,7 +1854,7 @@ estimate_mode_line_height (struct frame *f, enum face_id face_id)
not force the value into range. */
void
-pixel_to_glyph_coords (FRAME_PTR f, register int pix_x, register int pix_y,
+pixel_to_glyph_coords (struct frame *f, register int pix_x, register int pix_y,
int *x, int *y, NativeRectangle *bounds, int noclip)
{
@@ -5346,7 +5346,7 @@ handle_composition_prop (struct it *it)
composition (in the case that the composition is from the current
buffer), draw a glyph composed from the composition components. */
if (find_composition (pos, -1, &start, &end, &prop, string)
- && COMPOSITION_VALID_P (start, end, prop)
+ && composition_valid_p (start, end, prop)
&& (STRINGP (it->string) || (PT <= start || PT >= end)))
{
if (start < pos)
@@ -11449,7 +11449,7 @@ x_cursor_to (int vpos, int hpos, int y, int x)
/* Where the mouse was last time we reported a mouse event. */
-FRAME_PTR last_mouse_frame;
+struct frame *last_mouse_frame;
/* Tool-bar item index of the item on which a mouse button was pressed
or -1. */
@@ -12852,7 +12852,7 @@ check_point_in_composition (struct buffer *prev_buf, ptrdiff_t prev_pt,
if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
&& find_composition (prev_pt, -1, &start, &end, &prop, buffer)
- && COMPOSITION_VALID_P (start, end, prop)
+ && composition_valid_p (start, end, prop)
&& start < prev_pt && end > prev_pt)
/* The last point was within the composition. Return 1 iff
point moved out of the composition. */
@@ -12862,7 +12862,7 @@ check_point_in_composition (struct buffer *prev_buf, ptrdiff_t prev_pt,
/* Check a composition at the current point. */
return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
&& find_composition (pt, -1, &start, &end, &prop, buffer)
- && COMPOSITION_VALID_P (start, end, prop)
+ && composition_valid_p (start, end, prop)
&& start < pt && end > pt);
}
diff --git a/src/xfaces.c b/src/xfaces.c
index 52cd65c029f..acd2d2b1116 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -869,7 +869,7 @@ the pixmap. Bits are stored row by row, each row occupies
if these pointers are not null. */
static ptrdiff_t
-load_pixmap (FRAME_PTR f, Lisp_Object name, unsigned int *w_ptr,
+load_pixmap (struct frame *f, Lisp_Object name, unsigned int *w_ptr,
unsigned int *h_ptr)
{
ptrdiff_t bitmap_id;
@@ -1530,15 +1530,12 @@ the face font sort order. */)
(Lisp_Object family, Lisp_Object frame)
{
Lisp_Object font_spec, list, *drivers, vec;
+ struct frame *f = decode_live_frame (frame);
ptrdiff_t i, nfonts;
EMACS_INT ndrivers;
Lisp_Object result;
USE_SAFE_ALLOCA;
- if (NILP (frame))
- frame = selected_frame;
- CHECK_LIVE_FRAME (frame);
-
font_spec = Ffont_spec (0, NULL);
if (!NILP (family))
{
@@ -1546,7 +1543,7 @@ the face font sort order. */)
font_parse_family_registry (family, Qnil, font_spec);
}
- list = font_list_entities (frame, font_spec);
+ list = font_list_entities (f, font_spec);
if (NILP (list))
return Qnil;
@@ -1589,7 +1586,7 @@ the face font sort order. */)
ASET (v, 0, AREF (font, FONT_FAMILY_INDEX));
ASET (v, 1, FONT_WIDTH_SYMBOLIC (font));
point = PIXEL_TO_POINT (XINT (AREF (font, FONT_SIZE_INDEX)) * 10,
- FRAME_RES_Y (XFRAME (frame)));
+ FRAME_RES_Y (f));
ASET (v, 2, make_number (point));
ASET (v, 3, FONT_WEIGHT_SYMBOLIC (font));
ASET (v, 4, FONT_SLANT_SYMBOLIC (font));
@@ -3078,7 +3075,7 @@ FRAME 0 means change the face on all frames, and change the default
{
if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
{
- FRAME_PTR f;
+ struct frame *f;
old_value = LFACE_FONT (lface);
if (! FONTP (value))
diff --git a/src/xfns.c b/src/xfns.c
index a4492a10fdb..a1e9e916aba 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -176,7 +176,7 @@ check_x_display_info (Lisp_Object object)
dpyinfo = x_display_info_for_name (object);
else
{
- FRAME_PTR f = decode_window_system_frame (object);
+ struct frame *f = decode_window_system_frame (object);
dpyinfo = FRAME_X_DISPLAY_INFO (f);
}
@@ -369,7 +369,7 @@ x_top_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
not Emacs's own window. */
void
-x_real_positions (FRAME_PTR f, int *xptr, int *yptr)
+x_real_positions (struct frame *f, int *xptr, int *yptr)
{
int win_x, win_y, outer_x IF_LINT (= 0), outer_y IF_LINT (= 0);
int real_x = 0, real_y = 0;
@@ -565,7 +565,7 @@ x_defined_color (struct frame *f, const char *color_name,
Signal an error if color can't be allocated. */
static int
-x_decode_color (FRAME_PTR f, Lisp_Object color_name, int mono_color)
+x_decode_color (struct frame *f, Lisp_Object color_name, int mono_color)
{
XColor cdef;
@@ -626,7 +626,7 @@ x_set_tool_bar_position (struct frame *f,
may be any format that GdkPixbuf knows about, i.e. not just bitmaps. */
int
-xg_set_icon (FRAME_PTR f, Lisp_Object file)
+xg_set_icon (struct frame *f, Lisp_Object file)
{
int result = 0;
Lisp_Object found;
@@ -660,7 +660,7 @@ xg_set_icon (FRAME_PTR f, Lisp_Object file)
}
int
-xg_set_icon_from_xpm_data (FRAME_PTR f, const char **data)
+xg_set_icon_from_xpm_data (struct frame *f, const char **data)
{
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data (data);
@@ -1050,7 +1050,7 @@ x_set_border_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
static void
-x_set_cursor_type (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval)
+x_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
{
set_frame_cursor_types (f, arg);
@@ -1449,7 +1449,7 @@ x_encode_text (Lisp_Object string, Lisp_Object coding_system, int selectionp,
icon name to NAME. */
static void
-x_set_name_internal (FRAME_PTR f, Lisp_Object name)
+x_set_name_internal (struct frame *f, Lisp_Object name)
{
if (FRAME_X_WINDOW (f))
{
@@ -1608,7 +1608,7 @@ x_set_name (struct frame *f, Lisp_Object name, int explicit)
specified a name for the frame; the name will override any set by the
redisplay code. */
static void
-x_explicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval)
+x_explicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
{
x_set_name (f, arg, 1);
}
@@ -1617,7 +1617,7 @@ x_explicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval)
name; names set this way will never override names set by the user's
lisp code. */
void
-x_implicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval)
+x_implicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
{
x_set_name (f, arg, 0);
}
@@ -1730,7 +1730,7 @@ x_default_scroll_bar_color_parameter (struct frame *f,
for example, but Xt doesn't). */
static void
-hack_wm_protocols (FRAME_PTR f, Widget widget)
+hack_wm_protocols (struct frame *f, Widget widget)
{
Display *dpy = XtDisplay (widget);
Window w = XtWindow (widget);
@@ -2088,9 +2088,6 @@ xic_free_xfontset (struct frame *f)
/* The fontset is not used anymore. It is safe to free it. */
XFreeFontSet (FRAME_X_DISPLAY (f), FRAME_XIC_FONTSET (f));
- if (FRAME_XIC_BASE_FONTNAME (f))
- xfree (FRAME_XIC_BASE_FONTNAME (f));
- FRAME_XIC_BASE_FONTNAME (f) = NULL;
FRAME_XIC_FONTSET (f) = NULL;
}
@@ -2541,7 +2538,7 @@ x_window (struct frame *f, long window_prompting, int minibuffer_only)
#else /* not USE_X_TOOLKIT */
#ifdef USE_GTK
static void
-x_window (FRAME_PTR f)
+x_window (struct frame *f)
{
if (! xg_create_frame_widgets (f))
error ("Unable to create window");
@@ -2791,10 +2788,6 @@ x_make_gc (struct frame *f)
| GCFillStyle | GCLineWidth),
&gc_values);
- /* Reliefs. */
- f->output_data.x->white_relief.gc = 0;
- f->output_data.x->black_relief.gc = 0;
-
/* Create the gray border tile used when the pointer is not in
the frame. Since this depends on the frame's pixel values,
this must be done on a per-frame basis. */
@@ -3492,7 +3485,7 @@ DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
(Lisp_Object color, Lisp_Object frame)
{
XColor foo;
- FRAME_PTR f = decode_window_system_frame (frame);
+ struct frame *f = decode_window_system_frame (frame);
CHECK_STRING (color);
@@ -3507,7 +3500,7 @@ DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
(Lisp_Object color, Lisp_Object frame)
{
XColor foo;
- FRAME_PTR f = decode_window_system_frame (frame);
+ struct frame *f = decode_window_system_frame (frame);
CHECK_STRING (color);
@@ -4325,19 +4318,6 @@ Internal use only, use `display-monitor-attributes-list' instead. */)
return attributes_list;
}
-
-int
-x_pixel_width (register struct frame *f)
-{
- return FRAME_PIXEL_WIDTH (f);
-}
-
-int
-x_pixel_height (register struct frame *f)
-{
- return FRAME_PIXEL_HEIGHT (f);
-}
-
/************************************************************************
X Displays
************************************************************************/
@@ -4606,7 +4586,7 @@ If TERMINAL is omitted or nil, that stands for the selected frame's display. */
/* Wait for responses to all X commands issued so far for frame F. */
void
-x_sync (FRAME_PTR f)
+x_sync (struct frame *f)
{
block_input ();
XSync (FRAME_X_DISPLAY (f), False);
@@ -5790,7 +5770,8 @@ or directory must exist.
This function is only defined on NS, MS Windows, and X Windows with the
Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored.
Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */)
- (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, Lisp_Object mustmatch, Lisp_Object only_dir_p)
+ (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename,
+ Lisp_Object mustmatch, Lisp_Object only_dir_p)
{
int result;
struct frame *f = SELECTED_FRAME ();
@@ -5963,7 +5944,7 @@ Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored.
Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */)
(Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, Lisp_Object mustmatch, Lisp_Object only_dir_p)
{
- FRAME_PTR f = SELECTED_FRAME ();
+ struct frame *f = SELECTED_FRAME ();
char *fn;
Lisp_Object file = Qnil;
Lisp_Object decoded_file;
@@ -6026,7 +6007,7 @@ FRAME is the frame on which to pop up the font chooser. If omitted or
nil, it defaults to the selected frame. */)
(Lisp_Object frame, Lisp_Object ignored)
{
- FRAME_PTR f = decode_window_system_frame (frame);
+ struct frame *f = decode_window_system_frame (frame);
Lisp_Object font;
Lisp_Object font_param;
char *default_name = NULL;
diff --git a/src/xfont.c b/src/xfont.c
index 9647a51ac6e..f673adbbd5e 100644
--- a/src/xfont.c
+++ b/src/xfont.c
@@ -114,19 +114,19 @@ xfont_get_pcm (XFontStruct *xfont, XChar2b *char2b)
? NULL : pcm);
}
-static Lisp_Object xfont_get_cache (FRAME_PTR);
-static Lisp_Object xfont_list (Lisp_Object, Lisp_Object);
-static Lisp_Object xfont_match (Lisp_Object, Lisp_Object);
-static Lisp_Object xfont_list_family (Lisp_Object);
-static Lisp_Object xfont_open (FRAME_PTR, Lisp_Object, int);
-static void xfont_close (FRAME_PTR, struct font *);
-static int xfont_prepare_face (FRAME_PTR, struct face *);
+static Lisp_Object xfont_get_cache (struct frame *);
+static Lisp_Object xfont_list (struct frame *, Lisp_Object);
+static Lisp_Object xfont_match (struct frame *, Lisp_Object);
+static Lisp_Object xfont_list_family (struct frame *);
+static Lisp_Object xfont_open (struct frame *, Lisp_Object, int);
+static void xfont_close (struct frame *, struct font *);
+static int xfont_prepare_face (struct frame *, struct face *);
static int xfont_has_char (Lisp_Object, int);
static unsigned xfont_encode_char (struct font *, int);
static int xfont_text_extents (struct font *, unsigned *, int,
struct font_metrics *);
static int xfont_draw (struct glyph_string *, int, int, int, int, bool);
-static int xfont_check (FRAME_PTR, struct font *);
+static int xfont_check (struct frame *, struct font *);
struct font_driver xfont_driver =
{
@@ -152,7 +152,7 @@ struct font_driver xfont_driver =
};
static Lisp_Object
-xfont_get_cache (FRAME_PTR f)
+xfont_get_cache (struct frame *f)
{
Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
@@ -486,9 +486,8 @@ xfont_list_pattern (Display *display, const char *pattern,
}
static Lisp_Object
-xfont_list (Lisp_Object frame, Lisp_Object spec)
+xfont_list (struct frame *f, Lisp_Object spec)
{
- FRAME_PTR f = XFRAME (frame);
Display *display = FRAME_X_DISPLAY_INFO (f)->display;
Lisp_Object registry, list, val, extra, script;
int len;
@@ -565,9 +564,8 @@ xfont_list (Lisp_Object frame, Lisp_Object spec)
}
static Lisp_Object
-xfont_match (Lisp_Object frame, Lisp_Object spec)
+xfont_match (struct frame *f, Lisp_Object spec)
{
- FRAME_PTR f = XFRAME (frame);
Display *display = FRAME_X_DISPLAY_INFO (f)->display;
Lisp_Object extra, val, entity;
char name[512];
@@ -622,9 +620,8 @@ xfont_match (Lisp_Object frame, Lisp_Object spec)
}
static Lisp_Object
-xfont_list_family (Lisp_Object frame)
+xfont_list_family (struct frame *f)
{
- FRAME_PTR f = XFRAME (frame);
Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
char **names;
int num_fonts, i;
@@ -679,7 +676,7 @@ xfont_list_family (Lisp_Object frame)
}
static Lisp_Object
-xfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size)
+xfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
{
Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
Display *display = dpyinfo->display;
@@ -895,7 +892,7 @@ xfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size)
}
static void
-xfont_close (FRAME_PTR f, struct font *font)
+xfont_close (struct frame *f, struct font *font)
{
block_input ();
XFreeFont (FRAME_X_DISPLAY (f), ((struct xfont_info *) font)->xfont);
@@ -903,7 +900,7 @@ xfont_close (FRAME_PTR f, struct font *font)
}
static int
-xfont_prepare_face (FRAME_PTR f, struct face *face)
+xfont_prepare_face (struct frame *f, struct face *face)
{
block_input ();
XSetFont (FRAME_X_DISPLAY (f), face->gc,
@@ -1092,7 +1089,7 @@ xfont_draw (struct glyph_string *s, int from, int to, int x, int y,
}
static int
-xfont_check (FRAME_PTR f, struct font *font)
+xfont_check (struct frame *f, struct font *font)
{
struct xfont_info *xfont = (struct xfont_info *) font;
diff --git a/src/xftfont.c b/src/xftfont.c
index 166a70acd85..f2b4c2abe2b 100644
--- a/src/xftfont.c
+++ b/src/xftfont.c
@@ -70,7 +70,7 @@ struct xftface_info
XftColor xft_bg; /* color for face->background */
};
-static void xftfont_get_colors (FRAME_PTR, struct face *, GC gc,
+static void xftfont_get_colors (struct frame *, struct face *, GC gc,
struct xftface_info *,
XftColor *fg, XftColor *bg);
@@ -80,7 +80,9 @@ static void xftfont_get_colors (FRAME_PTR, struct face *, GC gc,
may be NULL. */
static void
-xftfont_get_colors (FRAME_PTR f, struct face *face, GC gc, struct xftface_info *xftface_info, XftColor *fg, XftColor *bg)
+xftfont_get_colors (struct frame *f, struct face *face, GC gc,
+ struct xftface_info *xftface_info,
+ XftColor *fg, XftColor *bg)
{
if (xftface_info && face->gc == gc)
{
@@ -139,9 +141,9 @@ xftfont_get_colors (FRAME_PTR f, struct face *face, GC gc, struct xftface_info *
struct font_driver xftfont_driver;
static Lisp_Object
-xftfont_list (Lisp_Object frame, Lisp_Object spec)
+xftfont_list (struct frame *f, Lisp_Object spec)
{
- Lisp_Object list = ftfont_driver.list (frame, spec), tail;
+ Lisp_Object list = ftfont_driver.list (f, spec), tail;
for (tail = list; CONSP (tail); tail = XCDR (tail))
ASET (XCAR (tail), FONT_TYPE_INDEX, Qxft);
@@ -149,9 +151,9 @@ xftfont_list (Lisp_Object frame, Lisp_Object spec)
}
static Lisp_Object
-xftfont_match (Lisp_Object frame, Lisp_Object spec)
+xftfont_match (struct frame *f, Lisp_Object spec)
{
- Lisp_Object entity = ftfont_driver.match (frame, spec);
+ Lisp_Object entity = ftfont_driver.match (f, spec);
if (! NILP (entity))
ASET (entity, FONT_TYPE_INDEX, Qxft);
@@ -262,7 +264,7 @@ xftfont_add_rendering_parameters (FcPattern *pat, Lisp_Object entity)
}
static Lisp_Object
-xftfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size)
+xftfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
{
FcResult result;
Display *display = FRAME_X_DISPLAY (f);
@@ -484,7 +486,7 @@ xftfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size)
}
static void
-xftfont_close (FRAME_PTR f, struct font *font)
+xftfont_close (struct frame *f, struct font *font)
{
struct xftfont_info *xftfont_info = (struct xftfont_info *) font;
@@ -499,7 +501,7 @@ xftfont_close (FRAME_PTR f, struct font *font)
}
static int
-xftfont_prepare_face (FRAME_PTR f, struct face *face)
+xftfont_prepare_face (struct frame *f, struct face *face)
{
struct xftface_info *xftface_info;
@@ -522,7 +524,7 @@ xftfont_prepare_face (FRAME_PTR f, struct face *face)
}
static void
-xftfont_done_face (FRAME_PTR f, struct face *face)
+xftfont_done_face (struct frame *f, struct face *face)
{
struct xftface_info *xftface_info;
@@ -595,7 +597,7 @@ xftfont_text_extents (struct font *font, unsigned int *code, int nglyphs, struct
}
static XftDraw *
-xftfont_get_xft_draw (FRAME_PTR f)
+xftfont_get_xft_draw (struct frame *f)
{
XftDraw *xft_draw = font_get_frame_data (f, &xftfont_driver);
@@ -617,7 +619,7 @@ static int
xftfont_draw (struct glyph_string *s, int from, int to, int x, int y,
bool with_background)
{
- FRAME_PTR f = s->f;
+ struct frame *f = s->f;
struct face *face = s->face;
struct xftfont_info *xftfont_info = (struct xftfont_info *) s->font;
struct xftface_info *xftface_info = NULL;
@@ -677,7 +679,7 @@ xftfont_shape (Lisp_Object lgstring)
#endif
static int
-xftfont_end_for_frame (FRAME_PTR f)
+xftfont_end_for_frame (struct frame *f)
{
XftDraw *xft_draw;
diff --git a/src/xmenu.c b/src/xmenu.c
index 5cc37842da9..cad892444ff 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -111,7 +111,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
static Lisp_Object Qdebug_on_next_call;
#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
-static Lisp_Object xdialog_show (FRAME_PTR, bool, Lisp_Object, Lisp_Object,
+static Lisp_Object xdialog_show (struct frame *, bool, Lisp_Object, Lisp_Object,
const char **);
#endif
@@ -130,7 +130,7 @@ static struct frame *
menubar_id_to_frame (LWLIB_ID id)
{
Lisp_Object tail, frame;
- FRAME_PTR f;
+ struct frame *f;
FOR_EACH_FRAME (tail, frame)
{
@@ -154,13 +154,12 @@ menubar_id_to_frame (LWLIB_ID id)
the scroll bar or the edit window. Fx_popup_menu needs to be
sure it is the edit window. */
void
-mouse_position_for_popup (FRAME_PTR f, int *x, int *y)
+mouse_position_for_popup (struct frame *f, int *x, int *y)
{
Window root, dummy_window;
int dummy;
- if (! FRAME_X_P (f))
- emacs_abort ();
+ eassert (FRAME_X_P (f));
block_input ();
@@ -220,7 +219,7 @@ for instance using the window manager, then this produces a quit and
`x-popup-dialog' does not return. */)
(Lisp_Object position, Lisp_Object contents, Lisp_Object header)
{
- FRAME_PTR f = NULL;
+ struct frame *f = NULL;
Lisp_Object window;
/* Decode the first argument: find the window or frame to use. */
@@ -230,7 +229,7 @@ for instance using the window manager, then this produces a quit and
{
#if 0 /* Using the frame the mouse is on may not be right. */
/* Use the mouse's current position. */
- FRAME_PTR new_f = SELECTED_FRAME ();
+ struct frame *new_f = SELECTED_FRAME ();
Lisp_Object bar_window;
enum scroll_bar_part part;
Time time;
@@ -294,8 +293,8 @@ for instance using the window manager, then this produces a quit and
{
Lisp_Object x, y, frame, newpos;
XSETFRAME (frame, f);
- XSETINT (x, x_pixel_width (f) / 2);
- XSETINT (y, x_pixel_height (f) / 2);
+ XSETINT (x, FRAME_PIXEL_WIDTH (f) / 2);
+ XSETINT (y, FRAME_PIXEL_HEIGHT (f) / 2);
newpos = list2 (list2 (x, y), frame);
return Fx_popup_menu (newpos,
@@ -482,7 +481,7 @@ If FRAME is nil or not given, use the selected frame. */)
(Lisp_Object frame)
{
XEvent ev;
- FRAME_PTR f = decode_window_system_frame (frame);
+ struct frame *f = decode_window_system_frame (frame);
Widget menubar;
block_input ();
@@ -560,10 +559,7 @@ If FRAME is nil or not given, use the selected frame. */)
(Lisp_Object frame)
{
GtkWidget *menubar;
- FRAME_PTR f;
-
- /* gcc 2.95 doesn't accept the FRAME_PTR declaration after
- block_input (). */
+ struct frame *f;
block_input ();
f = decode_window_system_frame (frame);
@@ -621,10 +617,9 @@ popup_widget_loop (int do_timers, GtkWidget *widget)
execute Lisp code. */
void
-x_activate_menubar (FRAME_PTR f)
+x_activate_menubar (struct frame *f)
{
- if (! FRAME_X_P (f))
- emacs_abort ();
+ eassert (FRAME_X_P (f));
if (!f->output_data.x->saved_menu_event->type)
return;
@@ -684,7 +679,7 @@ popup_deactivate_callback (
for that widget.
F is the frame if known, or NULL if not known. */
static void
-show_help_event (FRAME_PTR f, xt_or_gtk_widget widget, Lisp_Object help)
+show_help_event (struct frame *f, xt_or_gtk_widget widget, Lisp_Object help)
{
Lisp_Object frame;
@@ -817,7 +812,7 @@ menubar_selection_callback (GtkWidget *widget, gpointer client_data)
static void
menubar_selection_callback (Widget widget, LWLIB_ID id, XtPointer client_data)
{
- FRAME_PTR f;
+ struct frame *f;
f = menubar_id_to_frame (id);
if (!f)
@@ -831,7 +826,7 @@ menubar_selection_callback (Widget widget, LWLIB_ID id, XtPointer client_data)
changed. */
static void
-update_frame_menubar (FRAME_PTR f)
+update_frame_menubar (struct frame *f)
{
#ifdef USE_GTK
xg_update_frame_menubar (f);
@@ -839,8 +834,7 @@ update_frame_menubar (FRAME_PTR f)
struct x_output *x;
int columns, rows;
- if (! FRAME_X_P (f))
- emacs_abort ();
+ eassert (FRAME_X_P (f));
x = f->output_data.x;
@@ -914,7 +908,7 @@ apply_systemfont_to_menu (struct frame *f, Widget w)
it is set the first time this is called, from initialize_frame_menubar. */
void
-set_frame_menubar (FRAME_PTR f, bool first_time, bool deep_p)
+set_frame_menubar (struct frame *f, bool first_time, bool deep_p)
{
xt_or_gtk_widget menubar_widget;
#ifdef USE_X_TOOLKIT
@@ -927,8 +921,7 @@ set_frame_menubar (FRAME_PTR f, bool first_time, bool deep_p)
bool *submenu_top_level_items;
int *submenu_n_panes;
- if (! FRAME_X_P (f))
- emacs_abort ();
+ eassert (FRAME_X_P (f));
menubar_widget = f->output_data.x->menubar_widget;
@@ -1267,7 +1260,7 @@ set_frame_menubar (FRAME_PTR f, bool first_time, bool deep_p)
is visible. */
void
-initialize_frame_menubar (FRAME_PTR f)
+initialize_frame_menubar (struct frame *f)
{
/* This function is called before the first chance to redisplay
the frame. It has to be, so the frame will have the right size. */
@@ -1282,12 +1275,11 @@ initialize_frame_menubar (FRAME_PTR f)
#ifndef USE_GTK
void
-free_frame_menubar (FRAME_PTR f)
+free_frame_menubar (struct frame *f)
{
Widget menubar_widget;
- if (! FRAME_X_P (f))
- emacs_abort ();
+ eassert (FRAME_X_P (f));
menubar_widget = f->output_data.x->menubar_widget;
@@ -1360,7 +1352,7 @@ static Lisp_Object *volatile menu_item_selection;
create_and_show_popup_menu below. */
struct next_popup_x_y
{
- FRAME_PTR f;
+ struct frame *f;
int x;
int y;
};
@@ -1418,7 +1410,7 @@ pop_down_menu (void *arg)
menu pops down.
menu_item_selection will be set to the selection. */
static void
-create_and_show_popup_menu (FRAME_PTR f, widget_value *first_wv, int x, int y,
+create_and_show_popup_menu (struct frame *f, widget_value *first_wv, int x, int y,
bool for_click, Time timestamp)
{
int i;
@@ -1434,8 +1426,7 @@ create_and_show_popup_menu (FRAME_PTR f, widget_value *first_wv, int x, int y,
use_pos_func = 1;
#endif
- if (! FRAME_X_P (f))
- emacs_abort ();
+ eassert (FRAME_X_P (f));
xg_crazy_callback_abort = 1;
menu = xg_create_widget ("popup", first_wv->name, f, first_wv,
@@ -1528,7 +1519,7 @@ pop_down_menu (Lisp_Object arg)
menu pops down.
menu_item_selection will be set to the selection. */
static void
-create_and_show_popup_menu (FRAME_PTR f, widget_value *first_wv,
+create_and_show_popup_menu (struct frame *f, widget_value *first_wv,
int x, int y, bool for_click, Time timestamp)
{
int i;
@@ -1539,8 +1530,7 @@ create_and_show_popup_menu (FRAME_PTR f, widget_value *first_wv,
LWLIB_ID menu_id;
Widget menu;
- if (! FRAME_X_P (f))
- emacs_abort ();
+ eassert (FRAME_X_P (f));
#ifdef USE_LUCID
apply_systemfont_to_menu (f, f->output_data.x->widget);
@@ -1608,7 +1598,7 @@ cleanup_widget_value_tree (void *arg)
}
Lisp_Object
-xmenu_show (FRAME_PTR f, int x, int y, bool for_click, bool keymaps,
+xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
Lisp_Object title, const char **error_name, Time timestamp)
{
int i;
@@ -1623,8 +1613,7 @@ xmenu_show (FRAME_PTR f, int x, int y, bool for_click, bool keymaps,
ptrdiff_t specpdl_count = SPECPDL_INDEX ();
- if (! FRAME_X_P (f))
- emacs_abort ();
+ eassert (FRAME_X_P (f));
*error_name = NULL;
@@ -1902,12 +1891,11 @@ dialog_selection_callback (GtkWidget *widget, gpointer client_data)
dialog pops down.
menu_item_selection will be set to the selection. */
static void
-create_and_show_dialog (FRAME_PTR f, widget_value *first_wv)
+create_and_show_dialog (struct frame *f, widget_value *first_wv)
{
GtkWidget *menu;
- if (! FRAME_X_P (f))
- emacs_abort ();
+ eassert (FRAME_X_P (f));
menu = xg_create_widget ("dialog", first_wv->name, f, first_wv,
G_CALLBACK (dialog_selection_callback),
@@ -1949,12 +1937,11 @@ dialog_selection_callback (Widget widget, LWLIB_ID id, XtPointer client_data)
dialog pops down.
menu_item_selection will be set to the selection. */
static void
-create_and_show_dialog (FRAME_PTR f, widget_value *first_wv)
+create_and_show_dialog (struct frame *f, widget_value *first_wv)
{
LWLIB_ID dialog_id;
- if (!FRAME_X_P (f))
- emacs_abort ();
+ eassert (FRAME_X_P (f));
dialog_id = widget_id_tick++;
#ifdef USE_LUCID
@@ -1994,7 +1981,7 @@ static const char * button_names [] = {
"button6", "button7", "button8", "button9", "button10" };
static Lisp_Object
-xdialog_show (FRAME_PTR f,
+xdialog_show (struct frame *f,
bool keymaps,
Lisp_Object title,
Lisp_Object header,
@@ -2012,8 +1999,7 @@ xdialog_show (FRAME_PTR f,
ptrdiff_t specpdl_count = SPECPDL_INDEX ();
- if (! FRAME_X_P (f))
- emacs_abort ();
+ eassert (FRAME_X_P (f));
*error_name = NULL;
@@ -2225,7 +2211,7 @@ menu_help_callback (char const *help_string, int pane, int item)
static void
pop_down_menu (Lisp_Object arg)
{
- FRAME_PTR f = XSAVE_POINTER (arg, 0);
+ struct frame *f = XSAVE_POINTER (arg, 0);
XMenu *menu = XSAVE_POINTER (arg, 1);
block_input ();
@@ -2253,7 +2239,7 @@ pop_down_menu (Lisp_Object arg)
Lisp_Object
-xmenu_show (FRAME_PTR f, int x, int y, bool for_click, bool keymaps,
+xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
Lisp_Object title, const char **error_name, Time timestamp)
{
Window root;
@@ -2269,8 +2255,7 @@ xmenu_show (FRAME_PTR f, int x, int y, bool for_click, bool keymaps,
unsigned int dummy_uint;
ptrdiff_t specpdl_count = SPECPDL_INDEX ();
- if (! FRAME_X_P (f) && ! FRAME_MSDOS_P (f))
- emacs_abort ();
+ eassert (FRAME_X_P (f) || FRAME_MSDOS_P (f));
*error_name = 0;
if (menu_items_n_panes == 0)
diff --git a/src/xselect.c b/src/xselect.c
index d9f7d9c29c7..3a16d7d3496 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -993,7 +993,7 @@ x_handle_selection_event (struct input_event *event)
We do this when about to delete a frame. */
void
-x_clear_frame_selections (FRAME_PTR f)
+x_clear_frame_selections (struct frame *f)
{
Lisp_Object frame;
Lisp_Object rest;
@@ -2377,7 +2377,7 @@ x_property_data_to_lisp (struct frame *f, const unsigned char *data,
/* Get the mouse position in frame relative coordinates. */
static void
-mouse_position_for_drop (FRAME_PTR f, int *x, int *y)
+mouse_position_for_drop (struct frame *f, int *x, int *y)
{
Window root, dummy_window;
int dummy;
diff --git a/src/xterm.c b/src/xterm.c
index a2306935e4e..a486242b8c3 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -145,7 +145,7 @@ int use_xim = 0; /* configure --without-xim */
/* Non-zero means that a HELP_EVENT has been generated since Emacs
start. */
-static int any_help_event_p;
+static bool any_help_event_p;
/* Last window where we saw the mouse. Used by mouse-autoselect-window. */
static Lisp_Object last_window;
@@ -212,8 +212,7 @@ static unsigned long ignore_next_mouse_click_timeout;
/* Where the mouse was last time we reported a mouse event. */
static XRectangle last_mouse_glyph;
-static FRAME_PTR last_mouse_glyph_frame;
-static Lisp_Object last_mouse_press_frame;
+static struct frame *last_mouse_glyph_frame;
/* The scroll bar in which the last X motion event occurred.
@@ -288,8 +287,6 @@ enum xembed_message
XEMBED_ACTIVATE_ACCELERATOR = 14
};
-/* Used in x_flush. */
-
static bool x_alloc_nearest_color_1 (Display *, Colormap, XColor *);
static void x_set_window_size_1 (struct frame *, int, int, int);
static void x_raise_frame (struct frame *);
@@ -357,15 +354,18 @@ x_flush (struct frame *f)
return;
block_input ();
- if (f == NULL)
+ if (f)
+ {
+ eassert (FRAME_X_P (f));
+ XFlush (FRAME_X_DISPLAY (f));
+ }
+ else
{
- Lisp_Object rest, frame;
- FOR_EACH_FRAME (rest, frame)
- if (FRAME_X_P (XFRAME (frame)))
- x_flush (XFRAME (frame));
+ /* Flush all displays and so all frames on them. */
+ struct x_display_info *xdi;
+ for (xdi = x_display_list; xdi; xdi = xdi->next)
+ XFlush (xdi->display);
}
- else if (FRAME_X_P (f))
- XFlush (FRAME_X_DISPLAY (f));
unblock_input ();
}
@@ -877,8 +877,6 @@ XTreset_terminal_modes (struct terminal *terminal)
static void x_set_glyph_string_clipping (struct glyph_string *);
static void x_set_glyph_string_gc (struct glyph_string *);
-static void x_draw_glyph_string_background (struct glyph_string *,
- int);
static void x_draw_glyph_string_foreground (struct glyph_string *);
static void x_draw_composite_glyph_string_foreground (struct glyph_string *);
static void x_draw_glyph_string_box (struct glyph_string *);
@@ -1163,7 +1161,7 @@ x_clear_glyph_string_rect (struct glyph_string *s, int x, int y, int w, int h)
contains the first component of a composition. */
static void
-x_draw_glyph_string_background (struct glyph_string *s, int force_p)
+x_draw_glyph_string_background (struct glyph_string *s, bool force_p)
{
/* Nothing to do if background has already been drawn or if it
shouldn't be drawn in the first place. */
@@ -1413,11 +1411,6 @@ x_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
#ifdef USE_X_TOOLKIT
-static Boolean cvt_string_to_pixel (Display *, XrmValue *, Cardinal *,
- XrmValue *, XrmValue *, XtPointer *);
-static void cvt_pixel_dtor (XtAppContext, XrmValue *, XtPointer,
- XrmValue *, Cardinal *);
-
#ifdef USE_LUCID
/* Return the frame on which widget WIDGET is used.. Abort if frame
@@ -3195,7 +3188,7 @@ XTflash (struct frame *f)
static void
-XTtoggle_invisible_pointer (FRAME_PTR f, int invisible)
+XTtoggle_invisible_pointer (struct frame *f, int invisible)
{
block_input ();
if (invisible)
@@ -3804,7 +3797,7 @@ static XMotionEvent last_mouse_motion_event;
static Lisp_Object last_mouse_motion_frame;
static int
-note_mouse_movement (FRAME_PTR frame, XMotionEvent *event)
+note_mouse_movement (struct frame *frame, XMotionEvent *event)
{
last_mouse_movement_time = event->time;
last_mouse_motion_event = *event;
@@ -3880,11 +3873,11 @@ redo_mouse_highlight (void)
movement. */
static void
-XTmouse_position (FRAME_PTR *fp, int insist, Lisp_Object *bar_window,
+XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y,
Time *timestamp)
{
- FRAME_PTR f1;
+ struct frame *f1;
block_input ();
@@ -4423,7 +4416,8 @@ xg_scroll_callback (GtkRange *range,
gdouble position;
int part = -1, whole = 0, portion = 0;
GtkAdjustment *adj = GTK_ADJUSTMENT (gtk_range_get_adjustment (range));
- FRAME_PTR f = (FRAME_PTR) g_object_get_data (G_OBJECT (range), XG_FRAME_DATA);
+ struct frame *f = (struct frame *) g_object_get_data (G_OBJECT (range),
+ XG_FRAME_DATA);
if (xg_ignore_gtk_scrollbar) return FALSE;
position = gtk_adjustment_get_value (adj);
@@ -5040,7 +5034,7 @@ x_scroll_bar_set_handle (struct scroll_bar *bar, int start, int end, int rebuild
{
int dragging = ! NILP (bar->dragging);
Window w = bar->x_window;
- FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
+ struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
GC gc = f->output_data.x->normal_gc;
/* If the display is already accurate, do nothing. */
@@ -5381,7 +5375,7 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio
`*redeem_scroll_bar_hook' is applied to its window before the judgment. */
static void
-XTcondemn_scroll_bars (FRAME_PTR frame)
+XTcondemn_scroll_bars (struct frame *frame)
{
/* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
while (! NILP (FRAME_SCROLL_BARS (frame)))
@@ -5449,7 +5443,7 @@ XTredeem_scroll_bar (struct window *window)
last call to `*condemn_scroll_bars_hook'. */
static void
-XTjudge_scroll_bars (FRAME_PTR f)
+XTjudge_scroll_bars (struct frame *f)
{
Lisp_Object bar, next;
@@ -5485,7 +5479,7 @@ static void
x_scroll_bar_expose (struct scroll_bar *bar, XEvent *event)
{
Window w = bar->x_window;
- FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
+ struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
GC gc = f->output_data.x->normal_gc;
int width_trim = VERTICAL_SCROLL_BAR_WIDTH_TRIM;
@@ -5584,7 +5578,7 @@ x_scroll_bar_handle_click (struct scroll_bar *bar, XEvent *event, struct input_e
static void
x_scroll_bar_note_movement (struct scroll_bar *bar, XEvent *event)
{
- FRAME_PTR f = XFRAME (XWINDOW (bar->window)->frame);
+ struct frame *f = XFRAME (XWINDOW (bar->window)->frame);
last_mouse_movement_time = event->xmotion.time;
@@ -5612,13 +5606,13 @@ x_scroll_bar_note_movement (struct scroll_bar *bar, XEvent *event)
on the scroll bar. */
static void
-x_scroll_bar_report_motion (FRAME_PTR *fp, Lisp_Object *bar_window,
+x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window,
enum scroll_bar_part *part, Lisp_Object *x,
Lisp_Object *y, Time *timestamp)
{
struct scroll_bar *bar = XSCROLL_BAR (last_mouse_scroll_bar);
Window w = bar->x_window;
- FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
+ struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
int win_x, win_y;
Window dummy_window;
int dummy_coord;
@@ -5686,7 +5680,7 @@ x_scroll_bar_report_motion (FRAME_PTR *fp, Lisp_Object *bar_window,
redraw them. */
static void
-x_scroll_bar_clear (FRAME_PTR f)
+x_scroll_bar_clear (struct frame *f)
{
#ifndef USE_TOOLKIT_SCROLL_BARS
Lisp_Object bar;
@@ -6975,14 +6969,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
&& event.xbutton.same_screen)
{
SET_SAVED_BUTTON_EVENT;
- XSETFRAME (last_mouse_press_frame, f);
*finish = X_EVENT_DROP;
}
- else if (event.type == ButtonPress)
- {
- last_mouse_press_frame = Qnil;
- goto OTHER;
- }
else
goto OTHER;
#endif /* USE_X_TOOLKIT || USE_GTK */
@@ -8537,7 +8525,7 @@ do_ewmh_fullscreen (struct frame *f)
}
static void
-XTfullscreen_hook (FRAME_PTR f)
+XTfullscreen_hook (struct frame *f)
{
if (FRAME_VISIBLE_P (f))
{
@@ -8938,7 +8926,7 @@ x_lower_frame (struct frame *f)
/* Request focus with XEmbed */
void
-xembed_request_focus (FRAME_PTR f)
+xembed_request_focus (struct frame *f)
{
/* See XEmbed Protocol Specification at
http://freedesktop.org/wiki/Specifications/xembed-spec */
@@ -8950,7 +8938,7 @@ xembed_request_focus (FRAME_PTR f)
/* Activate frame with Extended Window Manager Hints */
void
-x_ewmh_activate_frame (FRAME_PTR f)
+x_ewmh_activate_frame (struct frame *f)
{
/* See Window Manager Specification/Extended Window Manager Hints at
http://freedesktop.org/wiki/Specifications/wm-spec */
@@ -8968,7 +8956,7 @@ x_ewmh_activate_frame (FRAME_PTR f)
}
static void
-XTframe_raise_lower (FRAME_PTR f, int raise_flag)
+XTframe_raise_lower (struct frame *f, int raise_flag)
{
if (raise_flag)
x_raise_frame (f);
@@ -9452,6 +9440,19 @@ x_free_frame_resources (struct frame *f)
unload_color (f, f->output_data.x->black_relief.pixel);
x_free_gcs (f);
+
+ /* Free extra GCs allocated by x_setup_relief_colors. */
+ if (f->output_data.x->white_relief.gc)
+ {
+ XFreeGC (dpyinfo->display, f->output_data.x->white_relief.gc);
+ f->output_data.x->white_relief.gc = 0;
+ }
+ if (f->output_data.x->black_relief.gc)
+ {
+ XFreeGC (dpyinfo->display, f->output_data.x->black_relief.gc);
+ f->output_data.x->black_relief.gc = 0;
+ }
+
XFlush (FRAME_X_DISPLAY (f));
}
@@ -9817,18 +9818,11 @@ get_bits_and_offset (long unsigned int mask, int *bits, int *offset)
/* Return 1 if display DISPLAY is available for use, 0 otherwise.
But don't permanently open it, just test its availability. */
-int
+bool
x_display_ok (const char *display)
{
- int dpy_ok = 1;
- Display *dpy;
-
- dpy = XOpenDisplay (display);
- if (dpy)
- XCloseDisplay (dpy);
- else
- dpy_ok = 0;
- return dpy_ok;
+ Display *dpy = XOpenDisplay (display);
+ return dpy ? (XCloseDisplay (dpy), 1) : 0;
}
#ifdef USE_GTK
@@ -10728,9 +10722,6 @@ syms_of_xterm (void)
DEFSYM (Qvendor_specific_keysyms, "vendor-specific-keysyms");
DEFSYM (Qlatin_1, "latin-1");
- staticpro (&last_mouse_press_frame);
- last_mouse_press_frame = Qnil;
-
#ifdef USE_GTK
xg_default_icon_file = build_pure_c_string ("icons/hicolor/scalable/apps/emacs.svg");
staticpro (&xg_default_icon_file);
diff --git a/src/xterm.h b/src/xterm.h
index 6bdc708220b..5324ef628e7 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -403,7 +403,7 @@ extern Lisp_Object x_display_name_list;
extern struct x_display_info *x_display_info_for_display (Display *);
extern struct x_display_info *x_term_init (Lisp_Object, char *, char *);
-extern int x_display_ok (const char *);
+extern bool x_display_ok (const char *);
extern void select_visual (struct x_display_info *);
@@ -590,7 +590,6 @@ struct x_output
XIC xic;
XIMStyle xic_style;
XFontSet xic_xfs;
- char *xic_base_fontname;
#endif
/* Relief GCs, colors etc. */
@@ -754,7 +753,6 @@ enum
#define FRAME_X_XIM_STYLES(f) (FRAME_X_DISPLAY_INFO (f)->xim_styles)
#define FRAME_XIC_STYLE(f) ((f)->output_data.x->xic_style)
#define FRAME_XIC_FONTSET(f) ((f)->output_data.x->xic_xfs)
-#define FRAME_XIC_BASE_FONTNAME(f) ((f)->output_data.x->xic_base_fontname)
/* Value is the smallest width of any character in any font on frame F. */
@@ -1031,8 +1029,6 @@ extern void destroy_frame_xic (struct frame *);
extern void xic_set_preeditarea (struct window *, int, int);
extern void xic_set_statusarea (struct frame *);
extern void xic_set_xfontset (struct frame *, const char *);
-extern int x_pixel_width (struct frame *);
-extern int x_pixel_height (struct frame *);
extern bool x_defined_color (struct frame *, const char *, XColor *, bool);
#ifdef HAVE_X_I18N
extern void free_frame_xic (struct frame *);
diff --git a/test/ChangeLog b/test/ChangeLog
index bffe85e6a7a..f3d14786bd9 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,30 @@
+2013-08-04 Glenn Morris <rgm@gnu.org>
+
+ * automated/icalendar-tests.el (icalendar-tests--test-export)
+ (icalendar-tests--test-import): Try more precise TZ specification.
+
+2013-08-03 Glenn Morris <rgm@gnu.org>
+
+ * automated/core-elisp-tests.el (core-elisp-tests): Fix defcustom.
+
+ * automated/icalendar-tests.el (icalendar-tests--test-export)
+ (icalendar-tests--test-import):
+ Use getenv/setenv rather than set-time-zone-rule. Add debug messages.
+ (icalendar-tests--test-import): Reset zone even if error occurred.
+
+2013-08-02 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * automated/core-elisp-tests.el: New file.
+
+2013-08-01 Glenn Morris <rgm@gnu.org>
+
+ * automated/file-notify-tests.el (file-notify--test-remote-enabled):
+ Try to check that the remote system has a notification program.
+
+2013-07-31 Glenn Morris <rgm@gnu.org>
+
+ * automated/undo-tests.el (undo-test2, undo-test5): Be quieter.
+
2013-07-24 Michael Albinus <michael.albinus@gmx.de>
* automated/file-notify-tests.el
diff --git a/test/automated/core-elisp-tests.el b/test/automated/core-elisp-tests.el
new file mode 100644
index 00000000000..40169b836d5
--- /dev/null
+++ b/test/automated/core-elisp-tests.el
@@ -0,0 +1,40 @@
+;;; core-elisp-tests.el --- Testing some core Elisp rules
+
+;; Copyright (C) 2013 Free Software Foundation, Inc.
+
+;; Author: Stefan Monnier <monnier@iro.umontreal.ca>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(ert-deftest core-elisp-tests ()
+ "Test some core Elisp rules."
+ (with-temp-buffer
+ ;; Check that when defvar is run within a let-binding, the toplevel default
+ ;; is properly initialized.
+ (should (equal (list (let ((c-e-x 1)) (defvar c-e-x 2) c-e-x) c-e-x)
+ '(1 2)))
+ (should (equal (list (let ((c-e-x 1))
+ (defcustom c-e-x 2 "doc" :group 'blah) c-e-x)
+ c-e-x)
+ '(1 2)))))
+
+(provide 'core-elisp-tests)
+;;; core-elisp-tests.el ends here
diff --git a/test/automated/file-notify-tests.el b/test/automated/file-notify-tests.el
index 8bd4f258b1c..9f552ee7ab1 100644
--- a/test/automated/file-notify-tests.el
+++ b/test/automated/file-notify-tests.el
@@ -43,6 +43,7 @@
(defvar file-notify--test-event nil)
(require 'tramp)
+(require 'tramp-sh)
(setq tramp-verbose 0
tramp-message-show-message nil)
(when noninteractive (defalias 'tramp-read-passwd 'ignore))
@@ -57,7 +58,18 @@
(ignore-errors
(and (file-remote-p file-notify-test-remote-temporary-file-directory)
(file-directory-p file-notify-test-remote-temporary-file-directory)
- (file-writable-p file-notify-test-remote-temporary-file-directory))))
+ (file-writable-p file-notify-test-remote-temporary-file-directory)
+ ;; Extracted from tramp-sh-handle-file-notify-add-watch.
+ ;; Even though the "remote" system is just ssh@localhost,
+ ;; the PATH might not be the same as the "local" PATH.
+ ;; Eg this seems to be the case on hydra.nixos.org.
+ ;; Without this, tests fail with:
+ ;; "No file notification program found on /ssh:localhost:"
+ ;; Try to fix PATH instead?
+ (with-parsed-tramp-file-name
+ file-notify-test-remote-temporary-file-directory nil
+ (or (tramp-get-remote-gvfs-monitor-dir v)
+ (tramp-get-remote-inotifywait v))))))
(defmacro file-notify--deftest-remote (test docstring)
"Define ert `TEST-remote' for remote files."
diff --git a/test/automated/icalendar-tests.el b/test/automated/icalendar-tests.el
index 28fa47630a8..227855681e8 100644
--- a/test/automated/icalendar-tests.el
+++ b/test/automated/icalendar-tests.el
@@ -428,12 +428,14 @@ Argument EXPECTED-OUTPUT expected iCalendar result string.
European style input data must use german month names. American
and ISO style input data must use english month names."
- (let ((tz (cadr (current-time-zone)))
+ (let ((tz (getenv "TZ"))
(calendar-date-style 'iso)
(icalendar-recurring-start-year 2000))
(unwind-protect
(progn
- (set-time-zone-rule "CET")
+ (message "Current time zone: %s" (current-time-zone))
+ (setenv "TZ" "CET-1CEST,M3.5.0/2,M10.5.0/3")
+ (message "Current time zone: %s" (current-time-zone))
(when input-iso
(let ((calendar-month-name-array
["January" "February" "March" "April" "May" "June" "July" "August"
@@ -461,8 +463,8 @@ and ISO style input data must use english month names."
"Saturday"]))
(setq calendar-date-style 'american)
(icalendar-tests--do-test-export input-american expected-output))))
- ;; restore time-zone if something went terribly wrong
- (set-time-zone-rule tz))))
+ ;; restore time-zone even if something went terribly wrong
+ (setenv "TZ" tz))))
(defun icalendar-tests--do-test-export (input expected-output)
"Actually perform export test.
@@ -671,37 +673,41 @@ Argument INPUT icalendar event string.
Argument EXPECTED-ISO expected iso style diary string.
Argument EXPECTED-EUROPEAN expected european style diary string.
Argument EXPECTED-AMERICAN expected american style diary string."
- (let ((timezone (cadr (current-time-zone))))
- (set-time-zone-rule "CET")
- (with-temp-buffer
- (if (string-match "^BEGIN:VCALENDAR" input)
- (insert input)
- (insert "BEGIN:VCALENDAR\nPRODID:-//Emacs//NONSGML icalendar.el//EN\n")
- (insert "VERSION:2.0\nBEGIN:VEVENT\n")
- (insert input)
- (unless (eq (char-before) ?\n)
- (insert "\n"))
- (insert "END:VEVENT\nEND:VCALENDAR\n"))
- (let ((icalendar-import-format "%s%d%l%o%t%u%c%U")
- (icalendar-import-format-summary "%s")
- (icalendar-import-format-location "\n Location: %s")
- (icalendar-import-format-description "\n Desc: %s")
- (icalendar-import-format-organizer "\n Organizer: %s")
- (icalendar-import-format-status "\n Status: %s")
- (icalendar-import-format-url "\n URL: %s")
- (icalendar-import-format-class "\n Class: %s")
- (icalendar-import-format-uid "\n UID: %s")
- calendar-date-style)
- (when expected-iso
- (setq calendar-date-style 'iso)
- (icalendar-tests--do-test-import input expected-iso))
- (when expected-european
- (setq calendar-date-style 'european)
- (icalendar-tests--do-test-import input expected-european))
- (when expected-american
- (setq calendar-date-style 'american)
- (icalendar-tests--do-test-import input expected-american))))
- (set-time-zone-rule timezone)))
+ (let ((timezone (getenv "TZ")))
+ (unwind-protect
+ (progn
+ (message "Current time zone: %s" (current-time-zone))
+ (setenv "TZ" "CET-1CEST,M3.5.0/2,M10.5.0/3")
+ (message "Current time zone: %s" (current-time-zone))
+ (with-temp-buffer
+ (if (string-match "^BEGIN:VCALENDAR" input)
+ (insert input)
+ (insert "BEGIN:VCALENDAR\nPRODID:-//Emacs//NONSGML icalendar.el//EN\n")
+ (insert "VERSION:2.0\nBEGIN:VEVENT\n")
+ (insert input)
+ (unless (eq (char-before) ?\n)
+ (insert "\n"))
+ (insert "END:VEVENT\nEND:VCALENDAR\n"))
+ (let ((icalendar-import-format "%s%d%l%o%t%u%c%U")
+ (icalendar-import-format-summary "%s")
+ (icalendar-import-format-location "\n Location: %s")
+ (icalendar-import-format-description "\n Desc: %s")
+ (icalendar-import-format-organizer "\n Organizer: %s")
+ (icalendar-import-format-status "\n Status: %s")
+ (icalendar-import-format-url "\n URL: %s")
+ (icalendar-import-format-class "\n Class: %s")
+ (icalendar-import-format-uid "\n UID: %s")
+ calendar-date-style)
+ (when expected-iso
+ (setq calendar-date-style 'iso)
+ (icalendar-tests--do-test-import input expected-iso))
+ (when expected-european
+ (setq calendar-date-style 'european)
+ (icalendar-tests--do-test-import input expected-european))
+ (when expected-american
+ (setq calendar-date-style 'american)
+ (icalendar-tests--do-test-import input expected-american)))))
+ (setenv "TZ" timezone))))
(defun icalendar-tests--do-test-import (input expected-output)
"Actually perform import test.
diff --git a/test/automated/undo-tests.el b/test/automated/undo-tests.el
index 87c55c5d374..7b6989a5ef0 100644
--- a/test/automated/undo-tests.el
+++ b/test/automated/undo-tests.el
@@ -124,7 +124,7 @@
(undo-boundary)
(insert " Zero")
(undo-boundary)
- (push-mark)
+ (push-mark nil t)
(delete-region (save-excursion
(forward-word -1)
(point)) (point))
@@ -172,7 +172,7 @@
(insert " BEE")
(undo-boundary)
(setq buffer-undo-list (cons '(0.0 bogus) buffer-undo-list))
- (push-mark)
+ (push-mark nil t)
(delete-region (save-excursion
(forward-word -1)
(point)) (point))