Mercurial > emacs
changeset 107987:54f7ec0a9243
merge trunk
author | Kenichi Handa <handa@etlken> |
---|---|
date | Tue, 20 Apr 2010 16:26:02 +0900 |
parents | 8a09d4206862 (current diff) bef5d1738c0b (diff) |
children | b7a5dd2fb441 cd095471cdae |
files | etc/NEWS.23 src/ChangeLog |
diffstat | 71 files changed, 2338 insertions(+), 1373 deletions(-) [+] |
line wrap: on
line diff
--- a/.bzrignore Tue Apr 20 15:30:26 2010 +0900 +++ b/.bzrignore Tue Apr 20 16:26:02 2010 +0900 @@ -10,6 +10,7 @@ oo oo-spd autom4te.cache +*.dSYM *.elc *.exe DOC @@ -48,6 +49,7 @@ lisp/cus-load.el lisp/eshell/esh-groups.el lisp/finder-inf.el +nextstep/Emacs.app nt/config.log src/buildobj.h src/config.h
--- a/admin/notes/bugtracker Tue Apr 20 15:30:26 2010 +0900 +++ b/admin/notes/bugtracker Tue Apr 20 16:26:02 2010 +0900 @@ -4,7 +4,7 @@ * Quick-start guide -This is 95% of all you will ever need. +This is 95% of all you will ever need to know. ** How do I report a bug? Use M-x report-emacs-bug, or send mail to bug-gnu-emacs@gnu.org. @@ -34,8 +34,12 @@ For a list of all bugs, see http://debbugs.gnu.org/db/pa/lemacs.html This is a static page, updated once a day. There is also a dynamic -list, generated on request, but since there are many bug reports this -is slow and not recommended. +list, generated on request. This accepts various options, eg to see +the most recent bugs: + +http://debbugs.gnu.org/cgi/pkgreport.cgi?newest=100 + +Or follow the links on the front page http://debbugs.gnu.org . ** How do I report a bug in Emacs now? The same way as you always did. Send mail to bug-gnu-emacs@gnu.org, @@ -92,6 +96,9 @@ in the subsequent discussion will end up creating a new bug. This is annoying. +(So annoying that a form of message-id tracking has been implemented +to hopefully stop this happening, but it is still better to use X-Debbugs-CC.) + If a new report contains X-Debbugs-CC in the input, this is converted to a real Cc header in the output. (See Bug#1720). It is also merged into the Resent-CC header (see below). @@ -191,8 +198,7 @@ Version: 23.0.60 Severity: minor -Optionally, add a sub-package, eg Package: emacs,calendar. -This can include tags. Some things (e.g. submitter) don't seem to +This can also include tags. Some things (e.g. submitter) don't seem to work here. Otherwise, send mail to the control server, control@debbugs.gnu.org. @@ -229,7 +235,7 @@ 123 # given bug number 123;mbox=yes # mbox version of given bug -package # bugs in given package (don't use "emacs" - too many bugs!) +package # bugs in given package from:submitter@email.address severity:severity # all bugs of given severity tag:tag # all bugs with given tag @@ -281,6 +287,9 @@ search box. The only piece you really need to add is the "users" portion, the rest has the same syntax as normal. +**** To browse bugs by usertag: +http://debbugs.gnu.org/cgi/pkgindex.cgi?indexon=users + **** To find all bugs usertagged by a given email address: http://debbugs.gnu.org/cgi/pkgreport.cgi?users=bug-gnu-emacs@gnu.org @@ -359,7 +368,7 @@ notfixed 123 23.0.60 *** To assign or reassign a bug to a package or list of packages: -reassign 1234 emacs,cc-mode +reassign 1234 emacs ** To remove spam from the tracker, move it to the `spam' pseudo-package: reassign 123 spam
--- a/doc/emacs/ChangeLog Tue Apr 20 15:30:26 2010 +0900 +++ b/doc/emacs/ChangeLog Tue Apr 20 16:26:02 2010 +0900 @@ -1,3 +1,42 @@ +2010-04-18 Chong Yidong <cyd@stupidchicken.com> + + * programs.texi (Semantic): New node. + + * maintaining.texi (EDE): New node. + + * emacs.texi: Update node listing. + + * misc.texi (Gnus): Use the `C-h i' keybinding for info. + +2010-04-18 Glenn Morris <rgm@gnu.org> + + * emacs.texi (Acknowledgments): Remove duplicate. + + * maintaining.texi (VC Directory Commands): Mention stashes and shelves. + +2010-04-18 Glenn Morris <rgm@gnu.org> + + * dired.texi (Misc Dired Features): Mention VC diff and log. + * maintaining.texi (Old Revisions, VC Change Log): + Mention that diff and log work in Dired buffers. + + * help.texi (Help Summary): Mention M-x info-finder. + + * ack.texi (Acknowledgments): Add mpc.el. + + * custom.texi (Specifying File Variables, Directory Variables): + Document new commands for manipulating local variable lists. + +2010-04-18 Glenn Morris <rgm@gnu.org> + + * trouble.texi (Contributing): Add cindex entry. + Mention etc/CONTRIBUTE. + +2010-04-18 Chong Yidong <cyd@stupidchicken.com> + + * mark.texi (Persistent Mark): Copyedits. Replace undo example with + query-replace (Bug#5774). + 2010-04-16 Glenn Morris <rgm@gnu.org> * ack.texi, emacs.texi (Acknowledgments): Update for Org changes.
--- a/doc/emacs/ack.texi Tue Apr 20 15:30:26 2010 +0900 +++ b/doc/emacs/ack.texi Tue Apr 20 16:26:02 2010 +0900 @@ -801,8 +801,9 @@ @file{reveal.el}, a minor mode for automatically revealing invisible text; @file{smerge-mode.el}, a minor mode for resolving @code{diff3} conflicts; @file{diff-mode.el}, a mode for viewing and editing context -diffs; @file{css-mode.el} for Cascading Style Sheets; and -@file{bibtex-style.el} for BibTeX Style files. +diffs; @file{css-mode.el} for Cascading Style Sheets; +@file{bibtex-style.el} for BibTeX Style files; and @file{mpc.el}, a +client for the ``Music Player Daemon''. @item Morioka Tomohiko wrote several packages for MIME support in Gnus and
--- a/doc/emacs/custom.texi Tue Apr 20 15:30:26 2010 +0900 +++ b/doc/emacs/custom.texi Tue Apr 20 16:26:02 2010 +0900 @@ -1,6 +1,7 @@ @c This is part of the Emacs manual. @c Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1997, 2000, 2001, -@c 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. +@c 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 +@c Free Software Foundation, Inc. @c See file emacs.texi for copying conditions. @node Customization, Quitting, Amusements, Top @chapter Customization @@ -1086,11 +1087,22 @@ pair with a colon and semicolon as shown above. The special variable/value pair @code{mode: @var{modename};}, if present, specifies a major or minor mode; if you use this to specify a major -mode, it should come first in the line. The @var{value}s are are used +mode, it should come first in the line. The @var{value}s are used literally, and not evaluated. - Here is an example that specifies Lisp mode and sets two variables -with numeric values: +@findex add-file-local-variable-prop-line +@findex delete-file-local-variable-prop-line +@findex copy-dir-locals-to-file-locals-prop-line + You can use the command @code{add-file-local-variable-prop-line} +instead of adding entries by hand. It prompts for a variable +and value, and adds them to the first line in the appropriate way. +The command @code{delete-file-local-variable-prop-line} deletes a +variable from the line. The command +@code{copy-dir-locals-to-file-locals-prop-line} copies directory-local +variables (@pxref{Directory Variables}) to the first line. + + Here is an example first line that specifies Lisp mode and sets two +variables with numeric values: @smallexample ;; -*- mode: Lisp; fill-column: 75; comment-column: 50; -*- @@ -1144,6 +1156,17 @@ example above is for the C programming language, where comment lines start with @samp{/*} and end with @samp{*/}. +@findex add-file-local-variable +@findex delete-file-local-variable +@findex copy-dir-locals-to-file-locals + You can construct the local variables list yourself, or use the +command @code{add-file-local-variable}. This prompts for a variable +and value, and adds them to the list. If necessary, it also adds the +start and end markers. The command @code{delete-file-local-variable} +deletes a variable from the list. The command +@code{copy-dir-locals-to-file-locals} copies directory-local variables +(@pxref{Directory Variables}) to the list. + As with the @samp{-*-} line, the variables in a local variables list are used literally, and are not evaluated first. If you want to split a long string across multiple lines of the file, you can use @@ -1323,6 +1346,16 @@ subdirectory of the directory where you put the @file{.dir-locals.el} file. +@findex add-dir-local-variable +@findex delete-dir-local-variable +@findex copy-file-locals-to-dir-locals + You can edit the @file{.dir-locals.el} file by hand, or use the +command @code{add-dir-local-variable}. This prompts for a mode (or +subdirectory), variable and value, and adds an entry to the file. +The command @code{delete-dir-local-variable} deletes an entry. The +command @code{copy-file-locals-to-dir-locals} copies file local +variables (@pxref{File Variables}) to the @file{.dir-locals.el} file. + @findex dir-locals-set-class-variables @findex dir-locals-set-directory-class Another method of specifying directory-local variables is to explicitly
--- a/doc/emacs/dired.texi Tue Apr 20 15:30:26 2010 +0900 +++ b/doc/emacs/dired.texi Tue Apr 20 16:26:02 2010 +0900 @@ -1,6 +1,7 @@ @c This is part of the Emacs manual. @c Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1997, 2000, 2001, -@c 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. +@c 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 +@c Free Software Foundation, Inc. @c See file emacs.texi for copying conditions. @node Dired, Calendar/Diary, Rmail, Top @chapter Dired, the Directory Editor @@ -1339,6 +1340,11 @@ it added to the kill ring, so you can use it to display the list of currently marked files in the echo area. +@cindex Dired and version control + If the directory you are visiting is under version control +(@pxref{Version Control}), then the normal VC diff and log commands +will operate on the selected files. + @findex dired-compare-directories The command @kbd{M-x dired-compare-directories} is used to compare the current Dired buffer with another directory. It marks all the files
--- a/doc/emacs/emacs.texi Tue Apr 20 15:30:26 2010 +0900 +++ b/doc/emacs/emacs.texi Tue Apr 20 16:26:02 2010 +0900 @@ -649,6 +649,7 @@ * Hideshow:: Displaying blocks selectively. * Symbol Completion:: Completion on symbol names of your program or language. * Glasses:: Making identifiersLikeThis more readable. +* Semantic:: Suite of editing tools based on source code parsing. * Misc for Programs:: Other Emacs features useful for editing programs. * C Modes:: Special commands of C, C++, Objective-C, Java, and Pike modes. @@ -763,6 +764,7 @@ * Change Log:: Maintaining a change history for your program. * Tags:: Go directly to any function in your program in one command. Tags remembers which file it is in. +* EDE:: An integrated development environment for Emacs. * Emerge:: A convenient way of merging two versions of a program. Version Control
--- a/doc/emacs/help.texi Tue Apr 20 15:30:26 2010 +0900 +++ b/doc/emacs/help.texi Tue Apr 20 16:26:02 2010 +0900 @@ -133,7 +133,9 @@ @item C-h n Display news of recent Emacs changes (@code{view-emacs-news}). @item C-h p -Find packages by topic keyword (@code{finder-by-keyword}). +Find packages by topic keyword (@code{finder-by-keyword}). For an +alternative interface to the same information, try the @code{info-finder} +command. @item C-h r Display the Emacs manual in Info (@code{info-emacs-manual}). @item C-h s
--- a/doc/emacs/maintaining.texi Tue Apr 20 15:30:26 2010 +0900 +++ b/doc/emacs/maintaining.texi Tue Apr 20 16:26:02 2010 +0900 @@ -14,6 +14,7 @@ * Change Log:: Maintaining a change history for your program. * Tags:: Go directly to any function in your program in one command. Tags remembers which file it is in. +* EDE:: An integrated development environment for Emacs. @ifnottex * Emerge:: A convenient way of merging two versions of a program. @end ifnottex @@ -653,7 +654,8 @@ @item C-x v = Compare the files in the current fileset with the working revision(s) you started from (@code{vc-diff}). With a prefix argument, prompt for -two revisions of the current fileset and compare them. +two revisions of the current fileset and compare them. You can call +this command from a Dired buffer (@pxref{Dired}). @item C-x v D Compare the entire tree corresponding to the current fileset with the @@ -895,6 +897,7 @@ Buffer}.) Point is centered at the revision of the file currently being visited. With a prefix argument, the command prompts for the revision to center on, and the maximum number of revisions to display. +You can call this command from a Dired buffer (@pxref{Dired}). @findex vc-print-root-log Type @kbd{C-x v L} (@code{vc-print-root-log}) to display a @@ -1145,9 +1148,14 @@ @kbd{M-s a C-M-s} does an incremental search on the marked files. - Commands are also accessible from the VC-dir menu. Note that some VC -backends use the VC-dir menu to make available extra backend specific -commands. +@cindex stashes in version control +@cindex shelves in version control + Commands are also accessible from the VC-dir menu. Note that some +VC backends use the VC-dir menu to make available extra, +backend-specific, commands. For example, Git and Bazaar allow you to +manipulate @dfn{stashes} and @dfn{shelves}. (These provide a +mechanism to temporarily store uncommitted changes somewhere out of +the way, and bring them back at a later time.) Normal VC commands with the @kbd{C-x v} prefix work in VC directory buffers. Some single-key shortcuts are available as well; @kbd{=}, @@ -2260,6 +2268,69 @@ @include emerge-xtra.texi @end ifnottex +@node EDE +@section Emacs Development Environment +@cindex EDE (Emacs Development Environment) +@cindex Emacs Development Environment +@cindex Integrated development environment + +EDE (@dfn{Emacs Development Environment}) is a package that simplifies +the task of creating, building, and debugging large programs with +Emacs. It provides some of the features of an IDE, or @dfn{Integrated +Development Environment}, in Emacs. + +This section provides a brief description of EDE usage. +@ifnottex +For full details, see @ref{Top, EDE,, ede, Emacs Development Environment}. +@end ifnottex +@iftex +For full details on Ede, type @kbd{C-h i} and then select the EDE +manual. +@end iftex + + EDE is implemented as a global minor mode (@pxref{Minor Modes}). To +enable it, type @kbd{M-x global-ede-mode} or click on the +@samp{Project Support (EDE)} item in the @samp{Tools} menu. You can +also enable EDE each time you start Emacs, by adding the following +line to your initialization file: + +@smallexample +(global-ede-mode t) +@end smallexample + +@noindent +Activating EDE adds a menu named @samp{Development} to the menu bar. +Many EDE commands, including the ones described below, can be invoked +from this menu. + + EDE organizes files into @dfn{projects}, which correspond to +directory trees. The @dfn{project root} is the topmost directory of a +project. To define a new project, visit a file in the desired project +root and type @kbd{M-x ede-new}. This command prompts for a +@dfn{project type}, which refers to the underlying method that EDE +will use to manage the project (@pxref{Creating a Project, EDE,, ede, +Emacs Development Environment}). The most common project types are +@samp{Make}, which uses Makefiles, and @samp{Automake}, which uses GNU +Automake (@pxref{Top, Automake,, automake, Automake}). In both cases, +EDE also creates a file named @file{Project.ede}, which stores +information about the project. + + A project may contain one or more @dfn{targets}. A target can be an +object file, executable program, or some other type of file, which is +``built'' from one or more of the files in the project. + + To add a new @dfn{target} to a project, type @kbd{C-c . t} +(@code{M-x ede-new-target}). This command also asks if you wish to +``add'' the current file to that target, which means that the target +is to be built from that file. After you have defined a target, you +can add more files to it by typing @kbd{C-c . a} +(@code{ede-add-file}). + + To build a target, type @kbd{C-c . c} (@code{ede-compile-target}). +To build all the targets in the project, type @kbd{C-c . C} +(@code{ede-compile-project}). EDE uses the file types to guess how +the target should be built. + @ignore arch-tag: b9d83dfb-82ea-4ff6-bab5-05a3617091fb @end ignore
--- a/doc/emacs/mark.texi Tue Apr 20 15:30:26 2010 +0900 +++ b/doc/emacs/mark.texi Tue Apr 20 16:26:02 2010 +0900 @@ -387,10 +387,10 @@ @findex transient-mark-mode To turn off Transient Mark mode, type @kbd{M-x transient-mark-mode}. -This command toggles the mode; you can use the same command to turn -Transient Mark mode on again. You can also turn off Transient Mark -mode using the menu bar: in the @samp{Options} menu, toggle the -@samp{Active Region Highlighting} menu item. +This command toggles the mode; you can use the same command to turn it +on again. You can also toggle Transient Mark mode using the +@samp{Active Region Highlighting} menu item in the @samp{Options} +menu. Here are the details of how Emacs behaves when Transient Mark mode is off: @@ -415,13 +415,12 @@ @kbd{C-s}, first set the mark where point was. @item -Some commands, which ordinarily operate on the region when the mark is -active, instead act on the entire buffer. For instance, @kbd{C-x u} -normally reverses changes within the region if the mark is active; -when Transient Mark mode is off, it acts on the entire buffer. -However, you can type @kbd{C-u C-x u} to make it operate on the -region. @xref{Undo}. Other commands that act this way are identified -in their own documentation. +Some commands, which ordinarily act on the region when the mark is +active, no longer do so. For example, normally @kbd{M-%} +(@code{query-replace}) performs replacements within the region, if the +mark is active. When Transient Mark mode is off, it always operates +from point to the end of the buffer. Commands that act this way are +identified in their own documentation. @end itemize While Transient Mark mode is off, you can activate it temporarily @@ -437,9 +436,9 @@ @item C-u C-x C-x @kindex C-u C-x C-x -Activate the mark without changing it; enable Transient Mark mode just -once, until the mark is deactivated. (This is the @kbd{C-x C-x} -command, @code{exchange-point-and-mark}, with a prefix argument.) +Activate the mark and enable Transient Mark mode temporarily, until +the mark is next deactivated. (This is the @kbd{C-x C-x} command, +@code{exchange-point-and-mark}, with a prefix argument.) @end table These commands set or activate the mark, and enable Transient Mark
--- a/doc/emacs/misc.texi Tue Apr 20 15:30:26 2010 +0900 +++ b/doc/emacs/misc.texi Tue Apr 20 16:26:02 2010 +0900 @@ -203,7 +203,7 @@ For full details, see @ref{Top, Gnus,, gnus, The Gnus Manual}. @end ifnottex @iftex -For full details on Gnus, type @kbd{M-x info} and then select the Gnus +For full details on Gnus, type @kbd{C-h i} and then select the Gnus manual. @end iftex
--- a/doc/emacs/programs.texi Tue Apr 20 15:30:26 2010 +0900 +++ b/doc/emacs/programs.texi Tue Apr 20 16:26:02 2010 +0900 @@ -39,6 +39,7 @@ * Hideshow:: Displaying blocks selectively. * Symbol Completion:: Completion on symbol names of your program or language. * Glasses:: Making identifiersLikeThis more readable. +* Semantic:: Suite of editing tools based on source code parsing. * Misc for Programs:: Other Emacs features useful for editing programs. * C Modes:: Special commands of C, C++, Objective-C, Java, and Pike modes. @@ -1387,6 +1388,73 @@ of the programming language major modes in which you normally want to use Glasses mode. +@node Semantic +@section Semantic +@cindex Semantic package + +Semantic is a package that provides language-aware editing commands +based on @code{source code parsers}. This section provides a brief +description of Semantic; +@ifnottex +for full details, see @ref{Top, Semantic,, semantic, Semantic}. +@end ifnottex +@iftex +for full details, type @kbd{C-h i} (@code{info}) and then select the +Semantic manual. +@end iftex + + Most of the ``language aware'' features in Emacs, such as font lock +(@pxref{Font Lock}), rely on ``rules of thumb''@footnote{Regular +expressions and syntax tables.} that usually give good results but are +never completely exact. In contrast, the parsers used by Semantic +have an exact understanding of programming language syntax. This +allows Semantic to provide search, navigation, and completion commands +that are powerful and precise. + + To begin using Semantic, type @kbd{M-x semantic-mode} or click on +the menu item named @samp{Source Code Parsers (Semantic)} in the +@samp{Tools} menu. This enables Semantic mode, a global minor mode. + + When Semantic mode is enabled, Emacs automatically attempts to +parses each file you visit. Currently, Semantic understands C, C++, +Scheme, Javascript, Java, HTML, and Make. Within each parsed buffer, +the following commands are available: + +@table @kbd +@item C-c , j +@kindex C-c , j +Prompt for the name of a function defined in the current file, and +move point there (@code{semantic-complete-jump-local}). + +@item C-c , J +@kindex C-c , J +Prompt for the name of a function defined in any file Emacs has +parsed, and move point there (@code{semantic-complete-jump}). + +@item C-c , @key{SPC} +@kindex C-c , @key{SPC} +Display a list of possible completions for the symbol at point +(@code{semantic-complete-analyze-inline}). This also activates a set +of special keybindings for choosing a completion: @key{RET} accepts +the current completion, @kbd{M-n} and @kbd{M-p} cycle through possible +completions, @key{TAB} completes as far as possible and then cycles, +and @kbd{C-g} or any other key aborts completion. + +@item C-c , l +@kindex C-c , l +Display a list of the possible completions of the symbol at point, in +another window (@code{semantic-analyze-possible-completions}). +@end table + +@noindent +In addition to the above commands, the Semantic package provides a +variety of other ways to make use of parser information. For +instance, you can use it to display a list of completions when Emacs +is idle. +@ifnottex +@xref{Top, Semantic,, semantic, Semantic}, for details. +@end ifnottex + @node Misc for Programs @section Other Features Useful for Editing Programs
--- a/doc/emacs/trouble.texi Tue Apr 20 15:30:26 2010 +0900 +++ b/doc/emacs/trouble.texi Tue Apr 20 16:26:02 2010 +0900 @@ -1008,6 +1008,7 @@ @node Contributing, Service, Bugs, Top @section Contributing to Emacs Development +@cindex contributing to Emacs If you would like to help pretest Emacs releases to assure they work well, or if you would like to work on improving Emacs, please contact @@ -1027,6 +1028,9 @@ See the Emacs project page @url{http://savannah.gnu.org/projects/emacs/} for details. +For more information on how to contribute, see the @file{etc/CONTRIBUTE} +file in the Emacs distribution. + @node Service, Copying, Contributing, Top @section How To Get Help with GNU Emacs
--- a/doc/lispref/ChangeLog Tue Apr 20 15:30:26 2010 +0900 +++ b/doc/lispref/ChangeLog Tue Apr 20 16:26:02 2010 +0900 @@ -1,3 +1,17 @@ +2010-04-14 Juri Linkov <juri@jurta.org> + + Fix @deffn without category. + + * abbrevs.texi (Abbrev Expansion): Replace @deffn with @defun + for `abbrev-insert'. + + * buffers.texi (Indirect Buffers): Add category `Command' + to @deffn of `clone-indirect-buffer'. + + * windows.texi (Cyclic Window Ordering): Replace @deffn with @defun + for `next-window' and `previous-window'. Add category `Command' + to @deffn of `pop-to-buffer'. + 2010-04-01 Chong Yidong <cyd@stupidchicken.com> * nonascii.texi (Text Representations): Don't mark
--- a/doc/lispref/abbrevs.texi Tue Apr 20 15:30:26 2010 +0900 +++ b/doc/lispref/abbrevs.texi Tue Apr 20 16:26:02 2010 +0900 @@ -281,7 +281,7 @@ returns @code{nil} even though expansion did occur. @end deffn -@deffn abbrev-insert abbrev &optional name start end +@defun abbrev-insert abbrev &optional name start end This function inserts the abbrev expansion of @code{abbrev}, replacing the text between @code{start} and @code{end}. If @code{start} is omitted, it defaults to point. @code{name}, if non-@code{nil}, should @@ -289,7 +289,7 @@ figure out whether to adjust the capitalization of the expansion. The function returns @code{abbrev} if the abbrev was successfully inserted. -@end deffn +@end defun @deffn Command abbrev-prefix-mark &optional arg This command marks the current location of point as the beginning of
--- a/doc/lispref/buffers.texi Tue Apr 20 15:30:26 2010 +0900 +++ b/doc/lispref/buffers.texi Tue Apr 20 16:26:02 2010 +0900 @@ -1135,7 +1135,7 @@ buffer, not from @var{base-buffer}. @end deffn -@deffn clone-indirect-buffer newname display-flag &optional norecord +@deffn Command clone-indirect-buffer newname display-flag &optional norecord This function creates and returns a new indirect buffer that shares the current buffer's base buffer and copies the rest of the current buffer's attributes. (If the current buffer is not indirect, it is
--- a/doc/lispref/windows.texi Tue Apr 20 15:30:26 2010 +0900 +++ b/doc/lispref/windows.texi Tue Apr 20 16:26:02 2010 +0900 @@ -525,7 +525,7 @@ In general, within each set of siblings at any level in the window tree (@pxref{Window Tree}), the order is left to right, or top to bottom. -@deffn next-window &optional window minibuf all-frames +@defun next-window &optional window minibuf all-frames @cindex minibuffer window, and @code{next-window} This function returns the window following @var{window} in the cyclic ordering of windows. This is the window @kbd{C-x o} selects if typed @@ -588,13 +588,13 @@ @result{} #<window 56 on windows.texi> @end group @end example -@end deffn - -@deffn previous-window &optional window minibuf all-frames +@end defun + +@defun previous-window &optional window minibuf all-frames This function returns the window preceding @var{window} in the cyclic ordering of windows. The other arguments specify which windows to include in the cycle, as in @code{next-window}. -@end deffn +@end defun @deffn Command other-window count &optional all-frames This function selects another window in the cyclic ordering of windows. @@ -827,7 +827,7 @@ unless @var{norecord} is non-@code{nil}. @end deffn -@deffn pop-to-buffer buffer-or-name &optional other-window norecord +@deffn Command pop-to-buffer buffer-or-name &optional other-window norecord This command makes @var{buffer-or-name} the current buffer and switches to it in some window, preferably not the window previously selected. The ``popped-to'' window becomes the selected window. Its frame is
--- a/doc/misc/ChangeLog Tue Apr 20 15:30:26 2010 +0900 +++ b/doc/misc/ChangeLog Tue Apr 20 16:26:02 2010 +0900 @@ -1,3 +1,20 @@ +2010-04-18 Teodor Zlatanov <tzz@lifelogs.com> + + * gnus.texi (Gnus Versions, Oort Gnus): Mention the Git repo instead of + the CVS repo. Put the Git repo in the news section. + + * gnus-coding.texi (Gnus Maintainance Guide): Fix title typo. + Removed some mentions of CVS. Mention the new Git repo. + +2010-04-18 Andreas Seltenreich <seltenreich@gmx.de> + + * gnus.texi (Score File Format): Fix typo. Reported by Štěpán Němec. + (Mail Group Commands): Add index entry. + +2010-04-18 Glenn Morris <rgm@gnu.org> + + * info.texi (Search Index): Mention Emacs's Info-virtual-index. + 2010-04-18 Jay Belanger <jay.p.belanger@gmail.com> * calc.texi (Radix modes): Mention that the option prefix will @@ -7,11 +24,10 @@ 2010-04-15 Carsten Dominik <carsten.dominik@gmail.com> * org.texi (LaTeX and PDF export): Add a footnote about xetex. - (LaTeX/PDF export commands): Section renamed and - moved. + (LaTeX/PDF export commands): Rename and Move section. (Sectioning structure): Update. (References): New use case for field coordinates. - (The export dispatcher): Renamed from ASCII export. + (The export dispatcher): Rename from ASCII export. (Setting up the staging area): Document the availability of encryption for MobileOrg. (Images and tables): Document how to reference labels. @@ -44,12 +60,10 @@ scheduling and deadline commands. (Search view): Point to the docstring of `org-search-view' for more details. - (Agenda commands): Document that `>' prompts for a - date. + (Agenda commands): Document that `>' prompts for a date. (Setting tags): Document variable org-complete-tags-always-offer-all-agenda-tags. - (Column attributes): Cross-reference special - properties. + (Column attributes): Cross-reference special properties. 2010-04-10 Michael Albinus <michael.albinus@gmx.de>
--- a/doc/misc/gnus-coding.texi Tue Apr 20 15:30:26 2010 +0900 +++ b/doc/misc/gnus-coding.texi Tue Apr 20 16:26:02 2010 +0900 @@ -32,16 +32,16 @@ @titlepage -@title Gnus Coding Style and Maintainance Guide +@title Gnus Coding Style and Maintenance Guide @author by Reiner Steib <Reiner.Steib@@gmx.de> @insertcopying @end titlepage -@c Obviously this is only a very rudimentary draft. We put it in CVS -@c anyway hoping that it might annoy someone enough to fix it. ;-) -@c Fixing only a paragraph also is appreciated. +@c Obviously this is only a very rudimentary draft. We put it in the +@c repository anyway hoping that it might annoy someone enough to fix +@c it. ;-) Fixing only a paragraph also is appreciated. @ifnottex @node Top @@ -255,15 +255,17 @@ @section Stable and development versions -The development of Gnus normally is done on the CVS trunk, i.e. there -are no separate branches to develop and test new features. Most of the -time, the trunk is developed quite actively with more or less daily -changes. Only after a new major release, e.g. 5.10.1, there's usually a -feature period of several months. After the release of Gnus 5.10.6 the -development of new features started again on the trunk while the 5.10 -series is continued on the stable branch (v5-10) from which more stable -releases will be done when needed (5.10.8, @dots{}). -@ref{Gnus Development, ,Gnus Development, gnus, The Gnus Newsreader} +The development of Gnus normally is done on the Git repository trunk +as of April 19, 2010 (formerly it was done in CVS; the repository is +at http://git.gnus.org), i.e. there are no separate branches to +develop and test new features. Most of the time, the trunk is +developed quite actively with more or less daily changes. Only after +a new major release, e.g. 5.10.1, there's usually a feature period of +several months. After the release of Gnus 5.10.6 the development of +new features started again on the trunk while the 5.10 series is +continued on the stable branch (v5-10) from which more stable releases +will be done when needed (5.10.8, @dots{}). @ref{Gnus Development, +,Gnus Development, gnus, The Gnus Newsreader} Stable releases of Gnus finally become part of Emacs. E.g. Gnus 5.8 became a part of Emacs 21 (relabeled to Gnus 5.9). The 5.10 series @@ -333,8 +335,12 @@ @item For general Gnus development changes, of course you just make the -change on the Gnus CVS trunk and it goes into Emacs a few years +change on the Gnus Git trunk and it goes into Emacs a few years later... :-) + +With the new Git repository, we'll probably set up something to +automatically synchronize with Emacs when possible. CVS was much less +powerful for this kind of synchronization. @end itemize Of course in any case, if you just can't wait for me to sync your
--- a/doc/misc/gnus.texi Tue Apr 20 15:30:26 2010 +0900 +++ b/doc/misc/gnus.texi Tue Apr 20 16:26:02 2010 +0900 @@ -11331,6 +11331,7 @@ @item B DEL @kindex B DEL (Summary) +@cindex deleting mail @findex gnus-summary-delete-article @c @icon{gnus-summary-mail-delete} Delete the mail article. This is ``delete'' as in ``delete it from your @@ -21843,7 +21844,7 @@ When you enter the group the first time, you will only see the new threads. You then raise the score of the threads that you find -interesting (with @kbd{I T} or @kbd{I S}), and ignore (@kbd{C y}) the +interesting (with @kbd{I T} or @kbd{I S}), and ignore (@kbd{c y}) the rest. Next time you enter the group, you will see new articles in the interesting threads, plus any new threads. @@ -27111,6 +27112,10 @@ On the January 4th 2004, No Gnus was begun. +On April 19, 2010 Gnus development was moved to Git. See +http://git.gnus.org for details (http://www.gnus.org will be updated +with the information when possible). + If you happen upon a version of Gnus that has a prefixed name -- ``(ding) Gnus'', ``September Gnus'', ``Red Gnus'', ``Quassia Gnus'', ``Pterodactyl Gnus'', ``Oort Gnus'', ``No Gnus'' -- don't panic. @@ -28507,7 +28512,7 @@ hierarchy. @c FIXME: `gnus-load' is mentioned in README, which is not included in -@c CVS. We should find a better place for this item. +@c the repository. We should find a better place for this item. @item @code{(require 'gnus-load)}
--- a/doc/misc/info.texi Tue Apr 20 15:30:26 2010 +0900 +++ b/doc/misc/info.texi Tue Apr 20 16:26:02 2010 +0900 @@ -15,7 +15,8 @@ documentation system. Copyright @copyright{} 1989, 1992, 1996, 1997, 1998, 1999, 2000, 2001, -2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. +2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 +Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document @@ -1050,6 +1051,13 @@ want to read the description of what the @kbd{C-l} key does, type @kbd{iC-l@key{RET}} literally. +@findex Info-virtual-index +@kindex I @r{(Info mode)} +Emacs provides the command @code{Info-virtual-index}, bound to the +@kbd{I} key. This behaves like @kbd{i}, but constructs a virtual +info node displaying the results of an index search, making it easier +to select the one you want. + @findex info-apropos @findex index-apropos If you aren't sure which manual documents the topic you are looking
--- a/etc/ChangeLog Tue Apr 20 15:30:26 2010 +0900 +++ b/etc/ChangeLog Tue Apr 20 16:26:02 2010 +0900 @@ -1,3 +1,7 @@ +2010-04-18 Francesc Rocher <rocher@member.fsf.org> + + * MORE.STUFF: Add a new entry for QWE. + 2010-04-18 Stefan Monnier <monnier@iro.umontreal.ca> * HELLO (Mathematics): Prefer Unicode charset.
--- a/etc/MORE.STUFF Tue Apr 20 15:30:26 2010 +0900 +++ b/etc/MORE.STUFF Tue Apr 20 16:26:02 2010 +0900 @@ -215,6 +215,10 @@ * Quack: <URL:http://www.neilvandyke.org/quack/> Quack enhances Emacs support for Scheme. + * QWE: <URL:http://www.nongnu.org/qwe/> + QWE's not WEB for Emacs is a quasi-WYSIWYG literate programming system for + Emacs that can be used with almost every programming language. + * Session: <URL:http://emacs-session.sourceforge.net/> Session Management for Emacs.
--- a/etc/NEWS.23 Tue Apr 20 15:30:26 2010 +0900 +++ b/etc/NEWS.23 Tue Apr 20 16:26:02 2010 +0900 @@ -24,6 +24,7 @@ * Installation Changes in Emacs 23.2 +--- ** New configure options for Emacs developers These are not new features; only the configure flags are new. --- @@ -36,8 +37,10 @@ ** `make install' now consistently ignores umask, creating a world-readable install. ++++ ** Emacs compiles with Gconf support, if it is detected. Use the configure option --without-gconf to disable this. +This is used by the `font-use-system-font' feature (see below). * Startup Changes in Emacs 23.2 +++ @@ -95,12 +98,14 @@ unconditionally. The previous behavior, toggling the mode, was neither reliable nor generally desirable. -*** New commands for adding and removing file-local variables: ++++ +*** There are new commands for adding and removing file-local variables: `add-file-local-variable', `delete-file-local-variable', `add-file-local-variable-prop-line', and `delete-file-local-variable-prop-line'. -*** New commands for adding and removing directory-local variables, ++++ +*** There are new commands for adding and removing directory-local variables, and copying them to and from file-local variable lists: `add-dir-local-variable', `delete-dir-local-variable', `copy-dir-locals-to-file-locals', @@ -181,15 +186,18 @@ * Changes in Specialized Modes and Packages in Emacs 23.2 +--- ** The bookmark menu has a narrowing search via bookmark-bmenu-search. ** LaTeX mode now provides completion (via completion-at-point). --- -** sym-comp.el is now declared obsolete, superceded by completion-at-point. - +** sym-comp.el is now declared obsolete, superseded by completion-at-point. + +--- ** lucid.el and levents.el are now declared obsolete. +--- ** pcomplete provides a new command `pcomplete-std-completion' which is similar to `pcomplete' but using the standard completion UI code. @@ -233,9 +241,9 @@ ** GDB-UI ++++ *** Toolbar functionality for reverse debugging. Display of STL -collections as watch expressions. These features require GDB 7.0 -or later. +collections as watch expressions. These features require GDB 7.0 or later. ** Grep +++ @@ -243,9 +251,11 @@ ** Info ++++ *** The new command `Info-virtual-index' bound to "I" displays a menu of matched topics found in the index. ++++ *** The new command `info-finder' replaces finder.el with a virtual Info manual that generates an Info file which gives the same information through a menu structure. @@ -325,22 +335,25 @@ backends do not support this. --- *** When a file is not found, VC will not try to check it out of RCS anymore. - ++++ *** Diff and log operations can be used from Dired buffers. *** vc-git changes -**** The short log format for git makes use of the graph display, so -it's not supported on git versions earlier than 1.5. - -**** Support for operating with stashes has been added to vc-dir: the stash list is -displayed in the *vc-dir* header, stashes can be created, removed, applied and -their content displayed. - -**** vc-dir displays the stash status - -**** vc-dir requires at least git-1.5.5. - +--- +**** The short log format for git makes use of the graph display, +so it's not supported on git versions earlier than 1.5.6. + +--- +**** vc-dir uses the --relative option of git, and so requires at least +git version 1.5.5. + ++++ +**** Support for operating with stashes has been added to vc-dir: +the stash list is displayed in the *vc-dir* header, stashes can be +created, removed, applied and their content displayed. + ++++ *** vc-bzr supports operating with shelves: the shelve list is displayed in the *vc-dir* header, shelves can be created, removed and applied. --- @@ -383,7 +396,7 @@ That means, they change `default-directory' to the new users value, and let commands run under that user permissions. It works even when `default-directory' is already remote. Calling the external commands -is possible by `*su' or `*sudo', repectively. +is possible by `*su' or `*sudo', respectively. --- *** When running in a new enough xterm (newer than version 242), Emacs asks xterm what the background color is and it sets up faces @@ -397,6 +410,7 @@ This is a collection of packages to aid with using Emacs as an IDE (integrated development environment): ++++ *** The Semantic package allows the use of parsers to intelligently edit and navigate source code. Parsers for C/C++, Java, Javascript, and several other languages are included by default, and Semantic can @@ -405,6 +419,7 @@ To enable Semantic, use the global minor mode `semantic-mode'. See the Semantic manual for details. ++++ *** EDE (Emacs Development Environment) is a package for managing code projects, including features such as automatic Makefile generation. @@ -415,9 +430,11 @@ code. It is currently used by some parts of Semantic and EDE; in the future, it may be used for code generation features. ++++ *** The EIEIO library implements a subset of the Common Lisp Object System (CLOS). It is used by the other CEDET packages. +--- ** mpc.el is a front end for the Music Player Daemon. Run it with M-x mpc. ** htmlfontify.el turns a fontified Emacs buffer into an HTML page. @@ -425,6 +442,7 @@ +++ ** js.el is a new major mode for JavaScript files. +--- ** imap-hash.el is a new library to address IMAP mailboxes as hashtables. @@ -452,16 +470,17 @@ ** Support for generating Emacs 18 compatible bytecode (by setting the variable `byte-compile-compatibility') has been removed. -** In image-mode.el `image-mode-maybe' is obsolete. Instead, you can -either use `image-mode' that displays an image file as the actual image -inititally, or `image-mode-as-text' when you want to display an image file -as text inititally. `image-mode-as-text' is a combination of a non-image -mode from `auto-mode-alist' (or Fundamental mode) and `image-minor-mode'. -`image-minor-mode' provides `C-c C-c' key binding to toggle image display. +--- +** In image-mode.el `image-mode-maybe' is obsolete. +Instead, you can either use `image-mode' (which displays an image file +as the actual image initially), or `image-mode-as-text' (when you want +to display an image file as text initially). `image-mode-as-text' is a +combination of a non-image mode from `auto-mode-alist' (or Fundamental +mode) and `image-minor-mode'. `image-minor-mode' provides a `C-c C-c' +key binding to toggle image display. `image-toggle-display-text' removes image properties. `image-toggle-display-image' adds image properties. -`image-toggle-display' toggles between `image-mode-as-text' and -`image-mode'. +`image-toggle-display' toggles between `image-mode-as-text' and `image-mode'. * Lisp changes in Emacs 23.2
--- a/leim/ChangeLog Tue Apr 20 15:30:26 2010 +0900 +++ b/leim/ChangeLog Tue Apr 20 16:26:02 2010 +0900 @@ -1,3 +1,7 @@ +2010-04-06 Chong Yidong <cyd@stupidchicken.com> + + * quail/vntelex.el: Fix "af" rule (Bug#5836). + 2010-03-27 Eli Zaretskii <eliz@gnu.org> * makefile.w32-in ($(TIT), $(MISC_DIC), leim-list.el): Enclose the
--- a/leim/quail/vntelex.el Tue Apr 20 15:30:26 2010 +0900 +++ b/leim/quail/vntelex.el Tue Apr 20 16:26:02 2010 +0900 @@ -285,7 +285,7 @@ ("Dd" ?,2p(B) ;("$$" ?$,1tK(B) ; U+20AB DONG SIGN (#### check) - ("aff" ["aff"]) + ("aff" ["af"]) ("AFF" ["AF"]) ("Aff" ["Af"]) ("ass" ["as"])
--- a/lib-src/ChangeLog Tue Apr 20 15:30:26 2010 +0900 +++ b/lib-src/ChangeLog Tue Apr 20 16:26:02 2010 +0900 @@ -1,3 +1,9 @@ +2010-04-18 Juanma Barranquero <lekktu@gmail.com> + + Add stubs for Windows, required after CVE-2010-0825 change. + * ntlib.c (getgid, getegid, setegid): New stubs. + * ntlib.h (getgid, getegid, setegid): Declare them. + 2010-04-12 Dan Nicolaescu <dann@ics.uci.edu> * Makefile.in (ALL_CFLAGS, LINK_CFLAGS, CPP_CFLAGS): Move to the
--- a/lisp/ChangeLog Tue Apr 20 15:30:26 2010 +0900 +++ b/lisp/ChangeLog Tue Apr 20 16:26:02 2010 +0900 @@ -1,5 +1,98 @@ 2010-04-19 Stefan Monnier <monnier@iro.umontreal.ca> + * international/mule.el: Help the user choose a valid coding-system. + (read-buffer-file-coding-system): New function. + (set-buffer-file-coding-system): Use it. Prompt the user if the + coding-system cannot encode all the chars. + + * vc-bzr.el: Use standard *vc* and *vc-diff* buffers. + (vc-bzr-shelve-show, vc-bzr-shelve-apply) + (vc-bzr-shelve-apply-and-keep, vc-bzr-shelve-snapshot): + Don't use *vc-bzr-shelve*. + +2010-04-19 Chong Yidong <cyd@stupidchicken.com> + + * cedet/ede/pmake.el (ede-proj-makefile-insert-variables): + Don't destroy list before using it. + +2010-04-19 Dan Nicolaescu <dann@ics.uci.edu> + + Fix the version number for added files. + * vc-hg.el (vc-hg-working-revision): Check if the file is + registered after hg parent fails (Bug#5961). + +2010-04-19 Glenn Morris <rgm@gnu.org> + + * htmlfontify.el (htmlfontify-buffer) + (htmlfontify-copy-and-link-dir): Autoload entry points. + +2010-04-19 Magnus Henoch <magnus.henoch@gmail.com> + + * vc-hg.el (vc-hg-annotate-extract-revision-at-line): Expand file + name relative to the project root (Bug#5960). + +2010-04-19 Glenn Morris <rgm@gnu.org> + + * vc-git.el (vc-git-print-log): Doc fix. + +2010-04-19 Óscar Fuentes <ofv@wanadoo.es> + + * ido.el (ido-file-internal): Fix 2009-12-02 change. + +2010-04-19 Christoph <cschol2112@googlemail.com> (tiny change) + + * progmodes/grep.el (grep-compute-defaults): Fix handling of host + default settings (Bug#5928). + +2010-04-19 Glenn Morris <rgm@gnu.org> + + * progmodes/fortran.el (fortran-match-and-skip-declaration): + New function. + (fortran-font-lock-keywords-3): Use it. (Bug#1385) + +2010-04-19 Kenichi Handa <handa@m17n.org> + + * language/indian.el (malayalam-composable-pattern): Fix previous + change (add U+0D4D "SIGN VIRAMA"). + (oriya-composable-pattern): Add U+0B30 and fix typo in the regexp. + (tamil-composable-pattern): Fix typo in the regexp. + (telugu-composable-pattern): Fix U+0C4D and typo in the regexp. + (kannada-composable-pattern): Fix U+0CB0 and typo in the regexp. + (malayalam-composable-pattern): Fix U+0D4D and typo in the regexp. + +2010-04-19 Chong Yidong <cyd@stupidchicken.com> + + * textmodes/tex-mode.el (latex-mode): Revert 2008-03-03 change to + paragraph-separate (Bug#5821). + +2010-04-19 Juri Linkov <juri@jurta.org> + + Put breadcrumbs on overlay instead of inserting to buffer (bug#5809). + + * info.el (Info-find-node-2): Comment out code that skips + breadcrumbs line. + (Info-mouse-follow-link): New command. + (Info-link-keymap): New keymap. + (Info-breadcrumbs): Rename from `Info-insert-breadcrumbs'. + Return a string with links instead of inserting breadcrumbs + to the Info buffer. + (Info-fontify-node): Comment out code that inserts breadcrumbs. + Instead of putting the `invisible' text property over the Info + header, make an overlay over the Info header with the `invisible' + property and `after-string' set to the string returned by + `Info-breadcrumbs'. + +2010-04-19 Chong Yidong <cyd@stupidchicken.com> + + * help.el (help-window-setup-finish): Doc fix (Bug#5830). + Reported by monkey@sandpframing.com. + +2010-04-19 Stefan Monnier <monnier@iro.umontreal.ca> + + * tmm.el (tmm-prompt): Remove obsolete call to x-popup-menu. + (tmm-get-keymap): Add key-binding shortcuts now that they're not + available in the "keyseq cache" any more. + * custom.el (defcustom): Add edebug spec. 2010-04-18 Juri Linkov <juri@jurta.org> @@ -355,32 +448,31 @@ 2010-04-07 Michael McNamara <mac@mail.brushroad.com> - * progmodes/verilog-mode.el (verilog-forward-sexp): + * progmodes/verilog-mode.el (verilog-forward-sexp): (verilog-calc-1): Support "disable fork" and "fork wait" multi word keywords, suggested by Steve Pearlmutter. - (verilog-pretty-declarations): Support lineup of declarations in + (verilog-pretty-declarations): Support lineup of declarations in port lists. - (verilog-skip-backward-comments, verilog-skip-forward-comment-p): - fix bug for /* / comments - (verilog-backward-syntactic-ws, verilog-forward-syntactic-ws): + (verilog-skip-backward-comments, verilog-skip-forward-comment-p): + fix bug for /* / comments + (verilog-backward-syntactic-ws, verilog-forward-syntactic-ws): Speed up and simplfy as this is never called with a bound. - (verilog-pretty-declarations): Enhance to line up declarations - inside a parameter list, suggested by Alan Morgan. - (verilog-pretty-expr): Tune assignment regular expression match - string for corner cases; also use markers instead of character - number as indent changes the later. + (verilog-pretty-declarations): Enhance to line up declarations + inside a parameter list, suggested by Alan Morgan. + (verilog-pretty-expr): Tune assignment regular expression match + string for corner cases; also use markers instead of character + number as indent changes the later. 2010-04-07 Wilson Snyder <wsnyder@wsnyder.org> - * progmodes/verilog-mode.el (verilog-type-keywords): Fix pulldown as missing - keyword. - (verilog-read-sub-decls-line): Fix comments in AUTO_TEMPLATE - causing truncation of AUTOWIRE signals. Reported by Bruce - Tennant. - (verilog-auto-inst, verilog-auto-inst-port): Add vl_mbits for - AUTO_TEMPLATEs needing multiple array bits. Suggested by Bruce - Tennant. - (verilog-keywords): + * progmodes/verilog-mode.el (verilog-type-keywords): Fix pulldown + as missing keyword. + (verilog-read-sub-decls-line): Fix comments in AUTO_TEMPLATE + causing truncation of AUTOWIRE signals. Reported by Bruce Tennant. + (verilog-auto-inst, verilog-auto-inst-port): Add vl_mbits for + AUTO_TEMPLATEs needing multiple array bits. Suggested by Bruce + Tennant. + (verilog-keywords): (verilog-1800-2005-keywords, verilog-1800-2009-keywords): Add IEEE 1800-2009 keywords, including "global.". @@ -543,7 +635,7 @@ 2010-03-31 Stefan Monnier <monnier@iro.umontreal.ca> - Make tmm-menubar work for the Buffers menu again. + Make tmm-menubar work for the Buffers menu again (bug#5726). * tmm.el (tmm-prompt): Also handle keymap entries in the form of vectors rather than cons cells, as used in menu-bar-update-buffers. @@ -1267,11 +1359,6 @@ * calendar/cal-hebrew.el (holiday-hebrew-passover): Fix date of Yom HaAtzma'ut when it falls on a Monday (rule changed in 2004). -2010-03-01 Alan Mackenzie <acm@muc.de> - - * progmodes/cc-engine.el (c-remove-stale-state-cache): - Correct previous patch. - 2010-03-01 Kenichi Handa <handa@m17n.org> * language/burmese.el (burmese-composable-pattern): Rename from @@ -1283,11 +1370,6 @@ (otf-script-alist): Likewise. (setup-default-fontset): Likewise. Re-fix :otf spec. -2010-03-01 Alan Mackenzie <bug-cc-mode@gnu.org> - - * cc-engine.el (c-remove-stale-state-cache): Take account of when - `good-pos' is in the same macro as `here'. Fixes bug#5649. - 2010-02-28 Katsumi Yamaoka <yamaoka@jpl.org> * menu-bar.el (menu-bar-manuals-menu): Fix typo. @@ -1353,16 +1435,6 @@ * mail/sendmail.el (send-mail-function): Autoload the call to custom-initialize-delay, not otherwise preserved in loaddefs.el. -2010-02-25 Alan Mackenzie <acm@muc.de> - - * progmodes/cc-engine.el (c-clear-<-pair-props) - (c-clear->-pair-props): Correct to wipe category text props, not - syntax-table ones. - - * progmodes/cc-mode.el (c-after-change): Remove any hard - syntax-table properties for <, > which, e.g., C-y has - inopportunely converted from category properties. - 2010-02-24 Chong Yidong <cyd@stupidchicken.com> * files.el (hack-local-variables-filter): For eval forms, also @@ -1700,33 +1772,6 @@ (doc-view-pdf->png): Don't rely on doc-view-pdf/ps->png for the few windows that are not yet showing images. -2010-02-04 Alan Mackenzie <acm@muc.de> - - Change strategy for marking < and > as template delimiters: mark - them strictly in matching pairs. - - * cc-mode.el (c-before-change): - Use c-get-state-before-change-functions. - (c-common-init): Adapt to use - c-get-state-before-change-functions (note plural). - - * cc-langs.el (c-no-parens-syntax-table): New syntax table, used - for searching syntactically for matching <s and >s. - (c-get-state-before-change-functions): New language variable (note - the plural) which supersedes c-get-state-before-change-function. - - * cc-engine.el (c-clear-<-pair-props, c-clear->-pair-props) - (c-clear-<>-pair-props, c-clear-<-pair-props-if-match-after) - (c-clear->-pair-props-if-match-before) - (c-before-change-check-<>-operators): New functions. - (c-after-change-check-<>-operators): Use macro - c-unmark-<->-as-paren. - - * cc-defs.el (c-search-backward-char-property): New macro. - - * cc-cmds.el (c-electric-lt-gt): Do not set text properties on < - and > any more. (These will be handled by font locking.) - 2010-02-04 Michael Albinus <michael.albinus@gmx.de> * dired.el (dired-revert): If DIRED-DIRECTORY is a cons cell, call
--- a/lisp/cedet/ede/pmake.el Tue Apr 20 15:30:26 2010 +0900 +++ b/lisp/cedet/ede/pmake.el Tue Apr 20 16:26:02 2010 +0900 @@ -425,10 +425,9 @@ (link (ede-proj-linkers this)) (name (ede-proj-makefile-target-name this)) (src (oref this source))) - (while comp - (ede-compiler-only-once (car comp) - (ede-proj-makefile-insert-variables (car comp))) - (setq comp (cdr comp))) + (dolist (obj comp) + (ede-compiler-only-once obj + (ede-proj-makefile-insert-variables obj))) (ede-proj-makefile-insert-object-variables (car comp) name src) (while link (ede-linker-only-once (car link)
--- a/lisp/gnus/ChangeLog Tue Apr 20 15:30:26 2010 +0900 +++ b/lisp/gnus/ChangeLog Tue Apr 20 16:26:02 2010 +0900 @@ -1,6 +1,15 @@ +2010-04-17 Teodor Zlatanov <tzz@lifelogs.com> + + * smime.el: Don't mention CVS. + + * nnrss.el (nnrss-fetch): Don't mention CVS. + + * nnir.el: Don't mention CVS. + 2010-04-14 Stefan Monnier <monnier@iro.umontreal.ca> - * gnus-sum.el (gnus-summary-bookmark-make-record): Add `location' field. + * gnus-sum.el (gnus-summary-bookmark-make-record): + Add `location' field. 2010-04-12 Stefan Monnier <monnier@iro.umontreal.ca>
--- a/lisp/gnus/nnir.el Tue Apr 20 15:30:26 2010 +0900 +++ b/lisp/gnus/nnir.el Tue Apr 20 16:26:02 2010 +0900 @@ -52,7 +52,7 @@ ;; The most recent version of this can always be fetched from the Gnus -;; CVS repository. See http://www.gnus.org/ for more information. +;; repository. See http://www.gnus.org/ for more information. ;; This code is still in the development stage but I'd like other ;; people to have a look at it. Please do not hesitate to contact me
--- a/lisp/gnus/nnrss.el Tue Apr 20 15:30:26 2010 +0900 +++ b/lisp/gnus/nnrss.el Tue Apr 20 16:26:02 2010 +0900 @@ -427,7 +427,7 @@ (defun nnrss-fetch (url &optional local) "Fetch URL and put it in a the expected Lisp structure." (mm-with-unibyte-buffer - ;;some CVS versions of url.el need this to close the connection quickly + ;;some versions of url.el need this to close the connection quickly (let (cs xmlform htmlform) ;; bit o' work necessary for w3 pre-cvs and post-cvs (if local
--- a/lisp/gnus/smime.el Tue Apr 20 15:30:26 2010 +0900 +++ b/lisp/gnus/smime.el Tue Apr 20 16:26:02 2010 +0900 @@ -42,7 +42,7 @@ ;; done on messages encoded in these formats. The terminology chosen ;; reflect this. ;; -;; The home of this file is in Gnus CVS, but also available from +;; The home of this file is in Gnus, but also available from ;; http://josefsson.org/smime.html. ;;; Quick introduction:
--- a/lisp/help.el Tue Apr 20 15:30:26 2010 +0900 +++ b/lisp/help.el Tue Apr 20 16:26:02 2010 +0900 @@ -1048,10 +1048,9 @@ Select WINDOW according to the value of `help-window-select'. Display message telling how to scroll and eventually quit WINDOW. -Optional argument REUSE non-nil means WINDOW has been reused \(by -`display-buffer'\) for displaying help. Optional argument -KEEP-FRAME non-nil means that quitting must no delete the frame -of WINDOW." +Optional argument REUSE non-nil means WINDOW has been reused by +`display-buffer'. Optional argument KEEP-FRAME non-nil means +that quitting should not delete WINDOW's frame." (let ((number-of-windows (length (window-list (window-frame window) 'no-mini window)))) (cond
--- a/lisp/htmlfontify.el Tue Apr 20 15:30:26 2010 +0900 +++ b/lisp/htmlfontify.el Tue Apr 20 16:26:02 2010 +0900 @@ -1790,6 +1790,7 @@ (when font-lock-defaults (font-lock-fontify-buffer)) )) +;;;###autoload (defun htmlfontify-buffer (&optional srcdir file) "Create a new buffer, named for the current buffer + a .html extension, containing an inline CSS-stylesheet and formatted CSS-markup HTML @@ -2276,6 +2277,7 @@ (save-buffer) (kill-buffer B))) +;;;###autoload (defun htmlfontify-copy-and-link-dir (srcdir dstdir &optional f-ext l-ext) "Trawl SRCDIR and write fontified-and-hyperlinked output in DSTDIR. F-EXT and L-EXT specify values for `hfy-extn' and `hfy-link-extn'.\n
--- a/lisp/ido.el Tue Apr 20 15:30:26 2010 +0900 +++ b/lisp/ido.el Tue Apr 20 16:26:02 2010 +0900 @@ -2312,7 +2312,8 @@ (or ido-use-url-at-point ido-use-filename-at-point)) (let (fn d) (require 'ffap) - ;; Duplicate code from ffap-guesser as we want different behavior for files and URLs. + ;; Duplicate code from ffap-guesser as we want different + ;; behavior for files and URLs. (cond ((with-no-warnings (and ido-use-url-at-point @@ -2328,7 +2329,10 @@ (ffap-guesser) (ffap-string-at-point)))) (not (string-match "^http:/" fn)) - (setq d (file-name-directory (expand-file-name fn))) + (let ((absolute-fn (expand-file-name fn))) + (setq d (if (file-directory-p absolute-fn) + (file-name-as-directory absolute-fn) + (file-name-directory absolute-fn)))) (file-directory-p d)) (setq ido-current-directory d) (setq initial (file-name-nondirectory fn))))))
--- a/lisp/info.el Tue Apr 20 15:30:26 2010 +0900 +++ b/lisp/info.el Tue Apr 20 16:26:02 2010 +0900 @@ -1053,8 +1053,8 @@ (Info-select-node) (goto-char (point-min)) (forward-line 1) ; skip header line - (when (> Info-breadcrumbs-depth 0) ; skip breadcrumbs line - (forward-line 1)) + ;; (when (> Info-breadcrumbs-depth 0) ; skip breadcrumbs line + ;; (forward-line 1)) (cond (anchorpos (let ((new-history (list Info-current-file @@ -3602,6 +3602,19 @@ ((setq node (Info-get-token (point) "Prev: " "Prev: \\([^,\n\t]*\\)")) (Info-goto-node node fork))) node)) + +(defun Info-mouse-follow-link (click) + "Follow a link where you click." + (interactive "e") + (let* ((position (event-start click)) + (posn-string (and position (posn-string position))) + (string (car-safe posn-string)) + (string-pos (cdr-safe posn-string)) + (link-args (and string string-pos + (get-text-property string-pos 'link-args string)))) + (when link-args + (Info-goto-node link-args)))) + (defvar Info-mode-map (let ((map (make-keymap))) @@ -4183,11 +4196,22 @@ keymap) "Keymap to put on the Up link in the text or the header line.") -(defun Info-insert-breadcrumbs () +(defvar Info-link-keymap + (let ((keymap (make-sparse-keymap))) + (define-key keymap [header-line mouse-1] 'Info-mouse-follow-link) + (define-key keymap [header-line mouse-2] 'Info-mouse-follow-link) + (define-key keymap [header-line down-mouse-1] 'ignore) + (define-key keymap [mouse-2] 'Info-mouse-follow-link) + (define-key keymap [follow-link] 'mouse-face) + keymap) + "Keymap to put on the link in the text or the header line.") + +(defun Info-breadcrumbs () (let ((nodes (Info-toc-nodes Info-current-file)) (node Info-current-node) (crumbs ()) - (depth Info-breadcrumbs-depth)) + (depth Info-breadcrumbs-depth) + line) ;; Get ancestors from the cached parent-children node info (while (and (not (equal "Top" node)) (> depth 0)) @@ -4214,15 +4238,25 @@ (file-name-nondirectory Info-current-file) ;; Some legacy code can still use a symbol. Info-current-file))))) - (insert (if (bolp) "" " > ") - (cond - ((null node) "...") - ((equal node Info-current-node) - ;; No point linking to ourselves. - (propertize text 'font-lock-face 'info-header-node)) - (t - (concat "*Note " text "::")))))) - (insert "\n")))) + (setq line (concat + line + (if (null line) "" " > ") + (cond + ((null node) "...") + ((equal node Info-current-node) + ;; No point linking to ourselves. + (propertize text 'font-lock-face 'info-header-node)) + (t + (propertize text + 'mouse-face 'highlight + 'font-lock-face 'info-header-xref + 'help-echo "mouse-2: Go to node" + 'keymap Info-link-keymap + 'link-args text))))))) + (setq line (concat line "\n"))) + ;; (font-lock-append-text-property 0 (length line) + ;; 'font-lock-face 'header-line line) + line)) (defun Info-fontify-node () "Fontify the node." @@ -4269,8 +4303,8 @@ ((string-equal (downcase tag) "next") Info-next-link-keymap) ((string-equal (downcase tag) "up" ) Info-up-link-keymap)))))) - (when (> Info-breadcrumbs-depth 0) - (Info-insert-breadcrumbs)) + ;; (when (> Info-breadcrumbs-depth 0) + ;; (insert (Info-breadcrumbs))) ;; Treat header line. (when Info-use-header-line @@ -4302,7 +4336,10 @@ ;; that is in the header, if it is just part. (cond ((> Info-breadcrumbs-depth 0) - (put-text-property (point-min) (1+ header-end) 'invisible t)) + (let ((ov (make-overlay (point-min) (1+ header-end)))) + (overlay-put ov 'invisible t) + (overlay-put ov 'after-string (Info-breadcrumbs)) + (overlay-put ov 'evaporate t))) ((not (bobp)) ;; Hide the punctuation at the end, too. (skip-chars-backward " \t,")
--- a/lisp/international/mule.el Tue Apr 20 15:30:26 2010 +0900 +++ b/lisp/international/mule.el Tue Apr 20 16:26:02 2010 +0900 @@ -1165,6 +1165,64 @@ (make-variable-buffer-local 'buffer-file-coding-system-explicit) (put 'buffer-file-coding-system-explicit 'permanent-local t) +(defun read-buffer-file-coding-system () + (let* ((bcss (find-coding-systems-region (point-min) (point-max))) + (css-table + (unless (equal bcss '(undecided)) + (append '("dos" "unix" "mac") + (delq nil (mapcar (lambda (cs) + (if (memq (coding-system-base cs) bcss) + (symbol-name cs))) + coding-system-list))))) + (combined-table + (if css-table + (completion-table-in-turn css-table coding-system-alist) + coding-system-alist)) + (auto-cs + (unless find-file-literally + (save-excursion + (save-restriction + (widen) + (goto-char (point-min)) + (funcall set-auto-coding-function + (or buffer-file-name "") (buffer-size)))))) + (preferred + (let ((bfcs (default-value 'buffer-file-coding-system))) + (cons (and (or (equal bcss '(undecided)) + (memq (coding-system-base bfcs) bcss)) + bfcs) + (mapcar (lambda (cs) + (and (coding-system-p cs) + (coding-system-get cs :mime-charset) + (or (equal bcss '(undecided)) + (memq (coding-system-base cs) bcss)) + cs)) + (coding-system-priority-list))))) + (default + (let ((current (coding-system-base buffer-file-coding-system))) + ;; Generally use as a default the first preferred coding-system + ;; different from the current coding-system, except for + ;; the case of auto-cs since choosing anything else is asking + ;; for trouble (would lead to using a different coding + ;; system than specified in the coding tag). + (or auto-cs + (car (delq nil + (mapcar (lambda (cs) + (if (eq current (coding-system-base cs)) + nil + cs)) + preferred)))))) + (completion-ignore-case t) + (completion-pcm--delim-wild-regex ; Let "u8" complete to "utf-8". + (concat completion-pcm--delim-wild-regex + "\\|\\([[:alpha:]]\\)[[:digit:]]")) + (cs (completing-read + (format "Coding system for saving file (default %s): " default) + combined-table + nil t nil 'coding-system-history + (if default (symbol-name default))))) + (unless (zerop (length cs)) (intern cs)))) + (defun set-buffer-file-coding-system (coding-system &optional force nomodify) "Set the file coding-system of the current buffer to CODING-SYSTEM. This means that when you save the buffer, it will be converted @@ -1182,19 +1240,26 @@ don't want to mark the buffer modified, specify t for NOMODIFY. If you know exactly what coding system you want to use, just set the variable `buffer-file-coding-system' directly." - (interactive "zCoding system for saving file (default nil): \nP") + (interactive + (list (read-buffer-file-coding-system) + current-prefix-arg)) (check-coding-system coding-system) (if (and coding-system buffer-file-coding-system (null force)) (setq coding-system (merge-coding-systems coding-system buffer-file-coding-system))) + (when (called-interactively-p 'interactive) + ;; Check whether save would succeed, and jump to the offending char(s) + ;; if not. + (let ((css (find-coding-systems-region (point-min) (point-max)))) + (unless (or (eq (car css) 'undecided) + (memq (coding-system-base coding-system) css)) + (setq coding-system (select-safe-coding-system-interactively + (point-min) (point-max) css + (list coding-system)))))) (setq buffer-file-coding-system coding-system) (if buffer-file-coding-system-explicit (setcdr buffer-file-coding-system-explicit coding-system) (setq buffer-file-coding-system-explicit (cons nil coding-system))) - ;; This is in case of an explicit call. Normally, `normal-mode' and - ;; `set-buffer-major-mode-hook' take care of setting the table. - (if (fboundp 'ucs-set-table-for-input) ; don't lose when building - (ucs-set-table-for-input)) (unless nomodify (set-buffer-modified-p t)) (force-mode-line-update))
--- a/lisp/language/indian.el Tue Apr 20 15:30:26 2010 +0900 +++ b/lisp/language/indian.el Tue Apr 20 16:26:02 2010 +0900 @@ -241,7 +241,7 @@ ;; syllables with an independent vowel, or "\\(?:RH\\)?Vn?\\(?:J?HR\\)?v*n?a?A?\\|" ;; consonant-based syllables, or - "Cn?\\(?:J?HJ?Cn?\\)*\\(?:H[NJ]?|v*n?a?A?\\)\\|" + "Cn?\\(?:J?HJ?Cn?\\)*\\(?:H[NJ]?\\|v*n?a?A?\\)\\|" ;; special consonant form, or "JHR\\|" ;; any other singleton characters @@ -256,8 +256,9 @@ ("V" . "[\u0B05-\u0B14\u0B60-\u0B61]") ; independent vowel ("C" . "[\u0B15-\u0B39\u0B5C-\u0B5D\u0B71]") ; consonant ("B" . "[\u0B15-\u0B17\u0B1B-\u0B1D\u0B1F-\u0B21\u0B23-\u0B24\u0B27-\u0B30\u0B32-\u0B35\u0B38-\u0B39]") ; consonant with below form + ("R" . "\u0B30") ; RA ("n" . "\u0B3C") ; NUKTA - ("v" . "[\u0B3E-\u0B44\u0B56-\u0B57\u0B62-\u0B63]") ; vowel sign + ("v" . "[\u0B3E-\u0B44\u0B47\u0B56-\u0B57\u0B62-\u0B63]") ; vowel sign ("H" . "\u0B4D") ; VIRAMA ("N" . "\u200C") ; ZWNJ ("J" . "\u200D") ; ZWJ @@ -267,7 +268,7 @@ ;; syllables with an independent vowel, or "\\(?:RH\\)?Vn?\\(?:J?HB\\)?v*n?a?A?\\|" ;; consonant-based syllables, or - "Cn?\\(?:J?HJ?Cn?\\)*\\(?:H[NJ]?|v*n?a?A?\\)\\|" + "Cn?\\(?:J?HJ?Cn?\\)*\\(?:H[NJ]?\\|v*n?a?A?\\)\\|" ;; special consonant form, or "JHB\\|" ;; any other singleton characters @@ -288,7 +289,7 @@ (indian-compose-regexp (concat ;; consonant-based syllables, or - "C\\(?:J?HJ?C\\)*\\(?:H[NJ]?|v*a?\\)\\|" + "C\\(?:J?HJ?C\\)*\\(?:H[NJ]?\\|v*a?\\)\\|" ;; syllables with an independent vowel, or "Vv*a?\\|" ;; any other singleton characters @@ -302,14 +303,14 @@ ("V" . "[\u0C05-\u0C14\u0C60-\u0C61]") ; independent vowel ("C" . "[\u0C15-\u0C39\u0C58-\u0C59]") ; consonant ("v" . "[\u0C3E-\u0C4C\u0C55-\u0C56\u0C62-\u0C63]") ; vowel sign - ("H" . "\u0BCD") ; VIRAMA + ("H" . "\u0C4D") ; VIRAMA ("N" . "\u200C") ; ZWNJ ("J" . "\u200D") ; ZWJ ("X" . "[\u0C00-\u0C7F]")))) ; all coverage (indian-compose-regexp (concat ;; consonant-based syllables, or - "C\\(?:J?HJ?C\\)*\\(?:H[NJ]?|v*a?\\)\\|" + "C\\(?:J?HJ?C\\)*\\(?:H[NJ]?\\|v*a?\\)\\|" ;; syllables with an independent vowel, or "V\\(?:J?HC\\)?v*a?\\|" ;; special consonant form, or @@ -324,7 +325,7 @@ '(("A" . "[\u0C82-\u0C83]") ; SIGN ANUSVARA .. VISARGA ("V" . "[\u0C85-\u0C94\u0CE0-\u0CE1]") ; independent vowel ("C" . "[\u0C95-\u0CB9\u0CDE]") ; consonant - ("B" . "\u0CB0") ; RA + ("R" . "\u0CB0") ; RA ("n" . "\u0CBC") ; NUKTA ("v" . "[\u0CBE-\u0CCC\u0CD5-\u0CD6\u0CE2-\u0CE3]") ; vowel sign ("H" . "\u0CCD") ; VIRAMA @@ -336,9 +337,9 @@ ;; syllables with an independent vowel, or "\\(?:RH\\)?Vn?\\(?:J?HC\\)?v?A?\\|" ;; consonant-based syllables, or - "Cn?\\(?:J?HJ?Cn?\\)*\\(?:H[NJ]?|v*n?A?\\)\\|" + "Cn?\\(?:J?HJ?Cn?\\)*\\(?:H[NJ]?\\|v*n?A?\\)\\|" ;; special consonant form, or - "JHB\\|" + "JHC\\|" ;; any other singleton characters "X") table)) @@ -351,13 +352,14 @@ ("C" . "[\u0D15-\u0D39]") ; consonant ("Y" . "[\u0D2F-\u0D30\u0D32\u0D35]") ; YA, RA, LA, VA ("v" . "[\u0D3E-\u0D48\u0D57\u0D62-\u0D63]") ; postbase matra + ("H" . "\u0D4D") ; SIGN VIRAMA ("N" . "\u200C") ; ZWNJ ("J" . "\u200D") ; ZWJ ("X" . "[\u0D00-\u0D7F]")))) ; all coverage (indian-compose-regexp (concat ;; consonant-based syllables, or - "\\(?:CJ?HJ?C\\)*\\(?:H[NJ]?\\|v?A?\\)\\|" + "C\\(?:J?HJ?C\\)*\\(?:H[NJ]?\\|v?A?\\)\\|" ;; syllables with an independent vowel, or "V\\(?:J?HY\\)?v*?A?\\|" ;; special consonant form, or
--- a/lisp/minibuffer.el Tue Apr 20 15:30:26 2010 +0900 +++ b/lisp/minibuffer.el Tue Apr 20 16:26:02 2010 +0900 @@ -381,21 +381,38 @@ (defconst completion-styles-alist '((emacs21 completion-emacs21-try-completion completion-emacs21-all-completions - "Simple prefix-based completion.") + "Simple prefix-based completion. +I.e. when completing \"foo_bar\" (where _ is the position of point), +it will consider all completions candidates matching the glob +pattern \"foobar*\".") (emacs22 completion-emacs22-try-completion completion-emacs22-all-completions - "Prefix completion that only operates on the text before point.") + "Prefix completion that only operates on the text before point. +I.e. when completing \"foo_bar\" (where _ is the position of point), +it will consider all completions candidates matching the glob +pattern \"foo*\" and will add back \"bar\" to the end of it.") (basic completion-basic-try-completion completion-basic-all-completions - "Completion of the prefix before point and the suffix after point.") + "Completion of the prefix before point and the suffix after point. +I.e. when completing \"foo_bar\" (where _ is the position of point), +it will consider all completions candidates matching the glob +pattern \"foo*bar*\".") (partial-completion completion-pcm-try-completion completion-pcm-all-completions "Completion of multiple words, each one taken as a prefix. -E.g. M-x l-c-h can complete to list-command-history -and C-x C-f /u/m/s to /usr/monnier/src.") +I.e. when completing \"l-co_h\" (where _ is the position of point), +it will consider all completions candidates matching the glob +pattern \"l*-co*h*\". +Furthermore, for completions that are done step by step in subfields, +the method is applied to all the preceding fields that do not yet match. +E.g. C-x C-f /u/mo/s TAB could complete to /usr/monnier/src. +Additionally the user can use the char \"*\" as a glob pattern.") (substring completion-substring-try-completion completion-substring-all-completions - "Completion of the string taken as a substring.") + "Completion of the string taken as a substring. +I.e. when completing \"foo_bar\" (where _ is the position of point), +it will consider all completions candidates matching the glob +pattern \"*foo*bar*\".") (initials completion-initials-try-completion completion-initials-all-completions "Completion of acronyms and initialisms. @@ -410,7 +427,19 @@ follow the calling convention of `completion-all-completions'), and DOC describes the way this style of completion works.") -(defcustom completion-styles '(basic partial-completion emacs22) +(defcustom completion-styles + ;; First, use `basic' because prefix completion has been the standard + ;; for "ever" and works well in most cases, so using it first + ;; ensures that we obey previous behavior in most cases. + '(basic + ;; Then use `partial-completion' because it has proven to + ;; be a very convenient extension. + partial-completion + ;; Finally use `emacs22' so as to maintain (in many/most cases) + ;; the previous behavior that when completing "foobar" with point + ;; between "foo" and "bar" the completion try to complete "foo" + ;; and simply add "bar" to the end of the result. + emacs22) "List of completion styles to use. The available styles are listed in `completion-styles-alist'." :type `(repeat (choice ,@(mapcar (lambda (x) (list 'const (car x)))
--- a/lisp/progmodes/fortran.el Tue Apr 20 15:30:26 2010 +0900 +++ b/lisp/progmodes/fortran.el Tue Apr 20 16:26:02 2010 +0900 @@ -403,6 +403,28 @@ '("^ *\\([0-9]+\\)" . font-lock-constant-face))) "Medium level highlighting for Fortran mode.") +;; See bug#1385. Never really looked into _why_ this matters... +(defun fortran-match-and-skip-declaration (limit) + "Like `font-lock-match-c-style-declaration-item-and-skip-to-next'. +The only difference is, it returns t in a case when the default returns nil." + (when (looking-at "[ \n\t*]*\\(\\sw+\\)[ \t\n]*\\(((?\\)?") + (when (and (match-end 2) (> (- (match-end 2) (match-beginning 2)) 1)) + (let ((pos (point))) + (skip-chars-backward " \t\n") + (skip-syntax-backward "w") + (unless (looking-at "\\(\\sw+\\)[ \t\n]*\\sw+[ \t\n]*\\(((?\\)?") + (goto-char pos) + (looking-at "[ \n\t*]*\\(\\sw+\\)[ \t\n]*\\(((?\\)?")))) + (save-match-data + (condition-case nil + (save-restriction + (narrow-to-region (point-min) limit) + (goto-char (match-end 1)) + (while (not (looking-at "[ \t\n]*\\(\\(,\\)\\|;\\|\\'\\)")) + (goto-char (or (scan-sexps (point) 1) (point-max)))) + (goto-char (match-end 2))) + (error t))))) + (defvar fortran-font-lock-keywords-3 (append fortran-font-lock-keywords-1 @@ -412,7 +434,7 @@ ;; Type specifier. '(1 font-lock-type-face) ;; Declaration item (or just /.../ block name). - `(font-lock-match-c-style-declaration-item-and-skip-to-next + `(fortran-match-and-skip-declaration ;; Start after any *(...) expression. (condition-case nil (and (match-beginning ,(1+ (regexp-opt-depth
--- a/lisp/progmodes/grep.el Tue Apr 20 15:30:26 2010 +0900 +++ b/lisp/progmodes/grep.el Tue Apr 20 16:26:02 2010 +0900 @@ -513,8 +513,8 @@ grep-find-template grep-find-use-xargs grep-highlight-matches)) (set setting - (or (cadr (assq setting host-defaults)) - (cadr (assq setting defaults))))) + (cadr (or (assq setting host-defaults) + (assq setting defaults))))) (unless (or (not grep-use-null-device) (eq grep-use-null-device t)) (setq grep-use-null-device
--- a/lisp/textmodes/tex-mode.el Tue Apr 20 15:30:26 2010 +0900 +++ b/lisp/textmodes/tex-mode.el Tue Apr 20 16:26:02 2010 +0900 @@ -1060,7 +1060,7 @@ "\\>\\|\\\\[a-z]*" (regexp-opt '("space" "skip" "page") t) "\\>\\)")) (setq paragraph-separate - (concat "[\f]\\|[ \t]*\\($\\|" + (concat "[\f%]\\|[ \t]*\\($\\|" "\\\\[][]\\|" "\\\\" (regexp-opt (append (mapcar 'car latex-section-alist)
--- a/lisp/tmm.el Tue Apr 20 15:30:26 2010 +0900 +++ b/lisp/tmm.el Tue Apr 20 16:26:02 2010 +0900 @@ -262,9 +262,6 @@ (condition-case nil (require 'mouse) (error nil)) - (condition-case nil - (x-popup-menu nil choice) ; Get the shortcuts - (error nil)) (tmm-prompt choice)) ;; We just handled a menu keymap and found a command. (choice @@ -445,7 +442,7 @@ `x-popup-menu' argument (when IN-X-MENU is not-nil). This function adds the element only if it is not already present. It uses the free variable `tmm-table-undef' to keep undefined keys." - (let (km str cache plist filter visible enable (event (car elt))) + (let (km str plist filter visible enable (event (car elt))) (setq elt (cdr elt)) (if (eq elt 'undefined) (setq tmm-table-undef (cons (cons event nil) tmm-table-undef)) @@ -468,11 +465,7 @@ (and (symbolp (cdr-safe (cdr-safe elt))) (fboundp (cdr-safe (cdr-safe elt))))) (setq km (cddr elt)) - (and (stringp (car elt)) (setq str (car elt))) - (and str - (stringp (cdr-safe (cadr elt))) ; keyseq cache - (setq cache (cdr (cadr elt))) - cache (setq str (concat str cache)))) + (and (stringp (car elt)) (setq str (car elt)))) ((eq (car-safe elt) 'menu-item) ;; (menu-item TITLE COMMAND KEY ...) @@ -489,13 +482,7 @@ (setq km (and (eval visible) km))) (setq enable (plist-get plist :enable)) (if enable - (setq km (if (eval enable) km 'ignore))) - (and str - (consp (nth 3 elt)) - (stringp (cdr (nth 3 elt))) ; keyseq cache - (setq cache (cdr (nth 3 elt))) - cache - (setq str (concat str cache)))) + (setq km (if (eval enable) km 'ignore)))) ((if (listp (cdr-safe (cdr-safe (cdr-safe elt)))) (or (keymapp (cdr-safe (cdr-safe (cdr-safe elt)))) @@ -504,16 +491,25 @@ (fboundp (cdr-safe (cdr-safe (cdr-safe elt)))))) ; New style of easy-menu (setq km (cdr (cddr elt))) - (and (stringp (car elt)) (setq str (car elt))) - (and str - (stringp (cdr-safe (car (cddr elt)))) ; keyseq cache - (setq cache (cdr (car (cdr (cdr elt))))) - cache (setq str (concat str cache)))) + (and (stringp (car elt)) (setq str (car elt)))) ((stringp event) ; x-popup or x-popup element (if (or in-x-menu (stringp (car-safe elt))) (setq str event event nil km elt) - (setq str event event nil km (cons 'keymap elt)))))) + (setq str event event nil km (cons 'keymap elt))))) + (unless (eq km 'ignore) + (let ((binding (where-is-internal km nil t))) + (when binding + (setq binding (key-description binding)) + ;; Try to align the keybindings. + (let ((colwidth (min 30 (- (/ (window-width) 2) 10)))) + (setq str + (concat str + (make-string (max 2 (- colwidth + (string-width str) + (string-width binding))) + ?\s) + binding))))))) (and km (stringp km) (setq str km)) ;; Verify that the command is enabled; ;; if not, don't mention it.
--- a/lisp/vc-bzr.el Tue Apr 20 15:30:26 2010 +0900 +++ b/lisp/vc-bzr.el Tue Apr 20 16:26:02 2010 +0900 @@ -899,10 +899,10 @@ (defun vc-bzr-shelve-show (name) "Show the contents of shelve NAME." (interactive "sShelve name: ") - (vc-setup-buffer "*vc-bzr-shelve*") + (vc-setup-buffer "*vc-diff*") ;; FIXME: how can you show the contents of a shelf? - (vc-bzr-command "unshelve" "*vc-bzr-shelve*" 'async nil "--preview" name) - (set-buffer "*vc-bzr-shelve*") + (vc-bzr-command "unshelve" "*vc-diff*" 'async nil "--preview" name) + (set-buffer "*vc-diff*") (diff-mode) (setq buffer-read-only t) (pop-to-buffer (current-buffer))) @@ -910,13 +910,13 @@ (defun vc-bzr-shelve-apply (name) "Apply shelve NAME and remove it afterwards." (interactive "sApply (and remove) shelf: ") - (vc-bzr-command "unshelve" "*vc-bzr-shelve*" 0 nil "--apply" name) + (vc-bzr-command "unshelve" nil 0 nil "--apply" name) (vc-resynch-buffer (vc-bzr-root default-directory) t t)) (defun vc-bzr-shelve-apply-and-keep (name) "Apply shelve NAME and keep it afterwards." (interactive "sApply (and keep) shelf: ") - (vc-bzr-command "unshelve" "*vc-bzr-shelve*" 0 nil "--apply" "--keep" name) + (vc-bzr-command "unshelve" nil 0 nil "--apply" "--keep" name) (vc-resynch-buffer (vc-bzr-root default-directory) t t)) (defun vc-bzr-shelve-snapshot () @@ -927,7 +927,7 @@ (concat (format-time-string "Snapshot on %Y-%m-%d" ct) (format-time-string " at %H:%M" ct)))) - (vc-bzr-command "unshelve" "*vc-bzr-shelve*" 0 nil "--apply" "--keep") + (vc-bzr-command "unshelve" nil 0 nil "--apply" "--keep") (vc-resynch-buffer (vc-bzr-root default-directory) t t)) (defun vc-bzr-shelve-list ()
--- a/lisp/vc-git.el Tue Apr 20 15:30:26 2010 +0900 +++ b/lisp/vc-git.el Tue Apr 20 16:26:02 2010 +0900 @@ -420,6 +420,7 @@ (vc-git-command (current-buffer) 'async files "ls-files" "-z" "-o" "-i" "--directory" "--no-empty-directory" "--exclude-standard" "--")) + ;; --relative added in Git 1.5.5. (diff-index (vc-git-command (current-buffer) 'async files "diff-index" "--relative" "-z" "-M" "HEAD" "--"))) @@ -578,7 +579,9 @@ ;;; HISTORY FUNCTIONS (defun vc-git-print-log (files buffer &optional shortlog start-revision limit) - "Get change log associated with FILES." + "Get change log associated with FILES. +Note that using SHORTLOG requires at least Git version 1.5.6, +for the --graph option." (let ((coding-system-for-read git-commits-coding-system)) ;; `vc-do-command' creates the buffer, but we need it before running ;; the command.
--- a/lisp/vc-hg.el Tue Apr 20 15:30:26 2010 +0900 +++ b/lisp/vc-hg.el Tue Apr 20 16:26:02 2010 +0900 @@ -196,16 +196,16 @@ (let* ((status nil) (default-directory (file-name-directory file)) + ;; Avoid localization of messages so we can parse the output. + (avoid-local-env (append (list "TERM=dumb" "LANGUAGE=C" "HGRC=") + process-environment)) (out (with-output-to-string (with-current-buffer standard-output (setq status (condition-case nil - (let ((process-environment - ;; Avoid localization of messages so we can parse the output. - (append (list "TERM=dumb" "LANGUAGE=C" "HGRC=") - process-environment))) + (let ((process-environment avoid-local-env)) ;; Ignore all errors. (process-file "hg" nil t nil @@ -213,7 +213,23 @@ ;; Some problem happened. E.g. We can't find an `hg' ;; executable. (error nil))))))) - (when (eq 0 status) out))) + (if (eq 0 status) + out + ;; Check if the file is in the 'added state, the above hg + ;; command does not distinguish between 'added and 'unregistered. + (setq status + (condition-case nil + (let ((process-environment avoid-local-env)) + (process-file + "hg" nil nil nil + ;; We use "log" here, if there's a faster command + ;; that returns true for an 'added file and false + ;; for an 'unregistered one, we could use that. + "log" "-l1" (file-relative-name file))) + ;; Some problem happened. E.g. We can't find an `hg' + ;; executable. + (error nil))) + (when (eq 0 status) "0")))) ;;; History functions @@ -356,7 +372,8 @@ (if (match-beginning 3) (match-string-no-properties 1) (cons (match-string-no-properties 1) - (expand-file-name (match-string-no-properties 4))))))) + (expand-file-name (match-string-no-properties 4) + (vc-hg-root default-directory))))))) (defun vc-hg-previous-revision (file rev) (let ((newrev (1- (string-to-number rev))))
--- a/src/.gdbinit Tue Apr 20 15:30:26 2010 +0900 +++ b/src/.gdbinit Tue Apr 20 16:26:02 2010 +0900 @@ -889,6 +889,19 @@ This command assumes that $ is an Emacs Lisp char-table value. end +define xsubchartable + xgetptr $ + print (struct Lisp_Sub_Char_Table *) $ptr + xgetint $->depth + set $depth = $int + xgetint $->min_char + printf "Depth: %d, Min char: %d (0x%x)\n", $depth, $int, $int +end +document xsubchartable +Print the address of the sub-char-table $, its depth and min-char. +This command assumes that $ is an Emacs Lisp sub-char-table value. +end + define xboolvector xgetptr $ print (struct Lisp_Bool_Vector *) $ptr
--- a/src/ChangeLog Tue Apr 20 15:30:26 2010 +0900 +++ b/src/ChangeLog Tue Apr 20 16:26:02 2010 +0900 @@ -3,10 +3,122 @@ * charset.c (char_charset): Consider Vcharset_non_preferred_head only when the arg CHARSET_LIST is nil. +2010-04-20 Stefan Monnier <monnier@iro.umontreal.ca> + + Make variable forwarding explicit rather the using special values. + Basically, this makes the structure of buffer-local values and object + forwarding explicit in the type of Lisp_Symbols rather than use + special Lisp_Objects for that. This tends to lead to slightly more + verbose code, but is more C-like, simpler, and makes it easier to make + sure we handled all cases, among other things by letting the compiler + help us check it. + * lisp.h (enum Lisp_Misc_Type, union Lisp_Misc): + Removing forwarding objects. + (enum Lisp_Fwd_Type, enum symbol_redirect, union Lisp_Fwd): New types. + (struct Lisp_Symbol): Make the various forms of variable-forwarding + explicit rather than hiding them inside Lisp_Object "values". + (XFWDTYPE): New macro. + (XINTFWD, XBOOLFWD, XOBJFWD, XKBOARD_OBJFWD): Redefine. + (XBUFFER_LOCAL_VALUE): Remove. + (SYMBOL_VAL, SYMBOL_ALIAS, SYMBOL_BLV, SYMBOL_FWD, SET_SYMBOL_VAL) + (SET_SYMBOL_ALIAS, SET_SYMBOL_BLV, SET_SYMBOL_FWD): New macros. + (SYMBOL_VALUE, SET_SYMBOL_VALUE): Remove. + (struct Lisp_Intfwd, struct Lisp_Boolfwd, struct Lisp_Objfwd) + (struct Lisp_Buffer_Objfwd, struct Lisp_Kboard_Objfwd): + Remove the Lisp_Misc_* header. + (struct Lisp_Buffer_Local_Value): Redefine. + (BLV_FOUND, SET_BLV_FOUND, BLV_VALUE, SET_BLV_VALUE): New macros. + (struct Lisp_Misc_Any): Add filler to get the right size. + (struct Lisp_Free): Use struct Lisp_Misc_Any rather than struct + Lisp_Intfwd. + (DEFVAR_LISP, DEFVAR_LISP_NOPRO, DEFVAR_BOOL, DEFVAR_INT) + (DEFVAR_KBOARD): Allocate a forwarding object. + * data.c (do_blv_forwarding, store_blv_forwarding): New macros. + (let_shadows_global_binding_p): New function. + (union Lisp_Val_Fwd): New type. + (make_blv): New function. + (swap_in_symval_forwarding, indirect_variable, do_symval_forwarding) + (store_symval_forwarding, swap_in_global_binding, Fboundp) + (swap_in_symval_forwarding, find_symbol_value, Fset) + (let_shadows_buffer_binding_p, set_internal, default_value) + (Fset_default, Fmake_variable_buffer_local, Fmake_local_variable) + (Fkill_local_variable, Fmake_variable_frame_local) + (Flocal_variable_p, Flocal_variable_if_set_p) + (Fvariable_binding_locus): + * xdisp.c (select_frame_for_redisplay): + * lread.c (Fintern, Funintern, init_obarray, defvar_int) + (defvar_bool, defvar_lisp_nopro, defvar_lisp, defvar_kboard): + * frame.c (store_frame_param): + * eval.c (Fdefvaralias, Fuser_variable_p, specbind, unbind_to): + * bytecode.c (Fbyte_code) <varref, varset>: Adapt to the new symbol + value structure. + * buffer.c (PER_BUFFER_SYMBOL): Move from buffer.h. + (clone_per_buffer_values): Only adjust markers into the current buffer. + (reset_buffer_local_variables): PER_BUFFER_IDX is never -2. + (Fbuffer_local_value, set_buffer_internal_1) + (swap_out_buffer_local_variables): + Adapt to the new symbol value structure. + (DEFVAR_PER_BUFFER): Allocate a Lisp_Buffer_Objfwd object. + (defvar_per_buffer): Take a new arg for the fwd object. + (buffer_lisp_local_variables): Return a proper alist (different fix + for bug#4138). + * alloc.c (Fmake_symbol): Use SET_SYMBOL_VAL. + (Fgarbage_collect): Don't handle buffer_defaults specially. + (mark_object): Handle new symbol value structure rather than the old + special Lisp_Misc_* objects. + (gc_sweep) <symbols>: Free also the buffer-local-value objects. + * term.c (set_tty_color_mode): + * bidi.c (bidi_initialize): Don't access the ->value field directly. + * buffer.h (PER_BUFFER_VAR_OFFSET): Don't bother with + a buffer_local_flags. + * print.c (print_object): Get rid of impossible forwarding objects. + +2010-04-19 Eli Zaretskii <eliz@gnu.org> + + * bidi.c (bidi_get_type, bidi_get_category) + (bidi_at_paragraph_end, bidi_resolve_weak, bidi_resolve_neutral) + (bidi_type_of_next_char, bidi_level_of_next_char): + Declare static. Use `INLINE' rather than `inline'. + +2010-04-19 Juanma Barranquero <lekktu@gmail.com> + + * dired.c (Ffile_attributes): Fix typo in docstring. + +2010-04-19 Adrian Robert <Adrian.B.Robert@gmail.com> + + * nsmenu.m (EmacsDialog-runDialogAt:): Declare ret as + NSInteger (Bug#5811). + +2010-04-19 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> + + * s/darwin.h (PTY_ITERATION, PTY_NAME_SPRINTF, PTY_TTY_NAME_SPRINTF) + (PTY_OPEN): New defines. Use openpty (Bug#726, Bug#5819). + +2010-04-19 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> + + * frame.h (FRAME_LINE_TO_PIXEL_Y): Add missing parenthesis. + +2010-04-19 Jan Djärv <jan.h.d@swipnet.se> + + * frame.h (FRAME_TEXT_LINES_TO_PIXEL_HEIGHT): Don't use + FRAME_LINE_TO_PIXEL_Y. + + * xterm.c (x_set_window_size_1): Don't add border_width/height to + pixelwidth/height. + +2010-04-19 Chong Yidong <cyd@stupidchicken.com> + + * xdisp.c (prepare_menu_bars): Don't call ns_set_doc_edited for + terminal frames (Bug#5837). + +2010-04-19 Eli Zaretskii <eliz@gnu.org> + + * .gdbinit (xsubchartable): New command. + 2010-04-19 Eli Zaretskii <eliz@gnu.org> * xdisp.c (display_line): Don't write beyond the last glyph row in - the desired matrix. Fixes a crash in "emacs -nw", see + the desired matrix. Fixes a crash in "emacs -nw" (bug#5972), see http://lists.gnu.org/archive/html/emacs-devel/2010-04/msg00075.html and http://lists.gnu.org/archive/html/emacs-devel/2010-04/msg00213.html
--- a/src/alloc.c Tue Apr 20 15:30:26 2010 +0900 +++ b/src/alloc.c Tue Apr 20 16:26:02 2010 +0900 @@ -1365,7 +1365,7 @@ pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init (&alloc_mutex, &attr); #else /* !DOUG_LEA_MALLOC */ - /* Some systems such as Solaris 2.6 doesn't have a recursive mutex, + /* Some systems such as Solaris 2.6 don't have a recursive mutex, and the bundled gmalloc.c doesn't require it. */ pthread_mutex_init (&alloc_mutex, NULL); #endif /* !DOUG_LEA_MALLOC */ @@ -3193,13 +3193,13 @@ p = XSYMBOL (val); p->xname = name; p->plist = Qnil; - p->value = Qunbound; + p->redirect = SYMBOL_PLAINVAL; + SET_SYMBOL_VAL (p, Qunbound); p->function = Qunbound; p->next = NULL; p->gcmarkbit = 0; p->interned = SYMBOL_UNINTERNED; p->constant = 0; - p->indirect_variable = 0; consing_since_gc += sizeof (struct Lisp_Symbol); symbols_consed++; return val; @@ -5581,17 +5581,42 @@ break; CHECK_ALLOCATED_AND_LIVE (live_symbol_p); ptr->gcmarkbit = 1; - mark_object (ptr->value); mark_object (ptr->function); mark_object (ptr->plist); - + switch (ptr->redirect) + { + case SYMBOL_PLAINVAL: mark_object (SYMBOL_VAL (ptr)); break; + case SYMBOL_VARALIAS: + { + Lisp_Object tem; + XSETSYMBOL (tem, SYMBOL_ALIAS (ptr)); + mark_object (tem); + break; + } + case SYMBOL_LOCALIZED: + { + struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (ptr); + /* If the value is forwarded to a buffer or keyboard field, + these are marked when we see the corresponding object. + And if it's forwarded to a C variable, either it's not + a Lisp_Object var, or it's staticpro'd already. */ + mark_object (blv->where); + mark_object (blv->valcell); + mark_object (blv->defcell); + break; + } + case SYMBOL_FORWARDED: + /* If the value is forwarded to a buffer or keyboard field, + these are marked when we see the corresponding object. + And if it's forwarded to a C variable, either it's not + a Lisp_Object var, or it's staticpro'd already. */ + break; + default: abort (); + } if (!PURE_POINTER_P (XSTRING (ptr->xname))) MARK_STRING (XSTRING (ptr->xname)); MARK_INTERVAL_TREE (STRING_INTERVALS (ptr->xname)); - /* Note that we do not mark the obarray of the symbol. - It is safe not to do so because nothing accesses that - slot except to check whether it is nil. */ ptr = ptr->next; if (ptr) { @@ -5610,22 +5635,6 @@ switch (XMISCTYPE (obj)) { - case Lisp_Misc_Buffer_Local_Value: - { - register struct Lisp_Buffer_Local_Value *ptr - = XBUFFER_LOCAL_VALUE (obj); - /* If the cdr is nil, avoid recursion for the car. */ - if (EQ (ptr->cdr, Qnil)) - { - obj = ptr->realvalue; - goto loop; - } - mark_object (ptr->realvalue); - mark_object (ptr->buffer); - mark_object (ptr->frame); - obj = ptr->cdr; - goto loop; - } case Lisp_Misc_Marker: /* DO NOT mark thru the marker's chain. @@ -5633,17 +5642,6 @@ instead, markers are removed from the chain when freed by gc. */ break; - case Lisp_Misc_Intfwd: - case Lisp_Misc_Boolfwd: - case Lisp_Misc_Objfwd: - case Lisp_Misc_Buffer_Objfwd: - case Lisp_Misc_Kboard_Objfwd: - /* Don't bother with Lisp_Buffer_Objfwd, - since all markable slots in current buffer marked anyway. */ - /* Don't need to do Lisp_Objfwd, since the places they point - are protected with staticpro. */ - break; - case Lisp_Misc_Save_Value: #if GC_MARK_STACK { @@ -6048,6 +6046,8 @@ if (!sym->gcmarkbit && !pure_p) { + if (sym->redirect == SYMBOL_LOCALIZED) + xfree (SYMBOL_BLV (sym)); sym->next = symbol_free_list; symbol_free_list = sym; #if GC_MARK_STACK
--- a/src/bidi.c Tue Apr 20 15:30:26 2010 +0900 +++ b/src/bidi.c Tue Apr 20 16:26:02 2010 +0900 @@ -23,7 +23,8 @@ as per UAX#9, a part of the Unicode Standard. Unlike the reference and most other implementations, this one is - designed to be called once for every character in the buffer. + designed to be called once for every character in the buffer or + string. The main entry point is bidi_get_next_char_visually. Each time it is called, it finds the next character in the visual order, and @@ -34,6 +35,11 @@ more details about its algorithm that finds the next visual-order character by resolving their levels on the fly. + The two other entry points are bidi_paragraph_init and + bidi_mirror_char. The first determines the base direction of a + paragraph, while the second returns the mirrored version of its + argument character. + If you want to understand the code, you will have to read it together with the relevant portions of UAX#9. The comments include references to UAX#9 rules, for that very reason. @@ -394,14 +400,14 @@ make_number (bidi_type[i].type)); fallback_paragraph_start_re = - XSYMBOL (Fintern_soft (build_string ("paragraph-start"), Qnil))->value; + Fsymbol_value (Fintern_soft (build_string ("paragraph-start"), Qnil)); if (!STRINGP (fallback_paragraph_start_re)) fallback_paragraph_start_re = build_string ("\f\\|[ \t]*$"); staticpro (&fallback_paragraph_start_re); Qparagraph_start = intern ("paragraph-start"); staticpro (&Qparagraph_start); fallback_paragraph_separate_re = - XSYMBOL (Fintern_soft (build_string ("paragraph-separate"), Qnil))->value; + Fsymbol_value (Fintern_soft (build_string ("paragraph-separate"), Qnil)); if (!STRINGP (fallback_paragraph_separate_re)) fallback_paragraph_separate_re = build_string ("[ \t\f]*$"); staticpro (&fallback_paragraph_separate_re); @@ -412,7 +418,7 @@ /* Return the bidi type of a character CH, subject to the current directional OVERRIDE. */ -bidi_type_t +static INLINE bidi_type_t bidi_get_type (int ch, bidi_dir_t override) { bidi_type_t default_type; @@ -463,7 +469,7 @@ } /* Given a bidi TYPE of a character, return its category. */ -bidi_category_t +static INLINE bidi_category_t bidi_get_category (bidi_type_t type) { switch (type) @@ -520,7 +526,7 @@ /* Copy the bidi iterator from FROM to TO. To save cycles, this only copies the part of the level stack that is actually in use. */ -static inline void +static INLINE void bidi_copy_it (struct bidi_it *to, struct bidi_it *from) { int i; @@ -540,14 +546,14 @@ static int bidi_cache_idx; static int bidi_cache_last_idx; -static inline void +static INLINE void bidi_cache_reset (void) { bidi_cache_idx = 0; bidi_cache_last_idx = -1; } -static inline void +static INLINE void bidi_cache_fetch_state (int idx, struct bidi_it *bidi_it) { int current_scan_dir = bidi_it->scan_dir; @@ -564,7 +570,7 @@ level less or equal to LEVEL. if LEVEL is -1, disregard the resolved levels in cached states. DIR, if non-zero, means search in that direction from the last cache hit. */ -static inline int +static INLINE int bidi_cache_search (int charpos, int level, int dir) { int i, i_start; @@ -655,7 +661,7 @@ return -1; } -static inline void +static INLINE void bidi_cache_iterator_state (struct bidi_it *bidi_it, int resolved) { int idx; @@ -710,7 +716,7 @@ bidi_cache_idx = idx + 1; } -static inline bidi_type_t +static INLINE bidi_type_t bidi_cache_find (int charpos, int level, struct bidi_it *bidi_it) { int i = bidi_cache_search (charpos, level, bidi_it->scan_dir); @@ -730,7 +736,7 @@ return UNKNOWN_BT; } -static inline int +static INLINE int bidi_peek_at_next_level (struct bidi_it *bidi_it) { if (bidi_cache_idx == 0 || bidi_cache_last_idx == -1) @@ -743,7 +749,7 @@ following the buffer position, -1 if position is at the beginning of a new paragraph, or -2 if position is neither at beginning nor at end of a paragraph. */ -EMACS_INT +static EMACS_INT bidi_at_paragraph_end (EMACS_INT charpos, EMACS_INT bytepos) { Lisp_Object sep_re = Fbuffer_local_value (Qparagraph_separate, @@ -773,7 +779,7 @@ embedding levels on either side of the run boundary. Also, update the saved info about previously seen characters, since that info is generally valid for a single level run. */ -static inline void +static INLINE void bidi_set_sor_type (struct bidi_it *bidi_it, int level_before, int level_after) { int higher_level = level_before > level_after ? level_before : level_after; @@ -873,7 +879,6 @@ int ch, ch_len; EMACS_INT pos; bidi_type_t type; - EMACS_INT sep_len; /* If we are inside a paragraph separator, we are just waiting for the separator to be exhausted; use the previous paragraph @@ -954,7 +959,7 @@ /* Do whatever UAX#9 clause X8 says should be done at paragraph's end. */ -static inline void +static INLINE void bidi_set_paragraph_end (struct bidi_it *bidi_it) { bidi_it->invalid_levels = 0; @@ -996,7 +1001,7 @@ /* Push the current embedding level and override status; reset the current level to LEVEL and the current override status to OVERRIDE. */ -static inline void +static INLINE void bidi_push_embedding_level (struct bidi_it *bidi_it, int level, bidi_dir_t override) { @@ -1009,7 +1014,7 @@ /* Pop the embedding level and directional override status from the stack, and return the new level. */ -static inline int +static INLINE int bidi_pop_embedding_level (struct bidi_it *bidi_it) { /* UAX#9 says to ignore invalid PDFs. */ @@ -1019,7 +1024,7 @@ } /* Record in SAVED_INFO the information about the current character. */ -static inline void +static INLINE void bidi_remember_char (struct bidi_saved_info *saved_info, struct bidi_it *bidi_it) { @@ -1035,7 +1040,7 @@ /* Resolve the type of a neutral character according to the type of surrounding strong text and the current embedding level. */ -static inline bidi_type_t +static INLINE bidi_type_t bidi_resolve_neutral_1 (bidi_type_t prev_type, bidi_type_t next_type, int lev) { /* N1: European and Arabic numbers are treated as though they were R. */ @@ -1052,7 +1057,7 @@ return STRONG_R; } -static inline int +static INLINE int bidi_explicit_dir_char (int c) { /* FIXME: this should be replaced with a lookup table with suitable @@ -1302,7 +1307,7 @@ /* Advance in the buffer, resolve weak types and return the type of the next character after weak type resolution. */ -bidi_type_t +static bidi_type_t bidi_resolve_weak (struct bidi_it *bidi_it) { bidi_type_t type; @@ -1493,7 +1498,7 @@ return type; } -bidi_type_t +static bidi_type_t bidi_resolve_neutral (struct bidi_it *bidi_it) { int prev_level = bidi_it->level_stack[bidi_it->stack_idx].level; @@ -1617,7 +1622,7 @@ /* Given an iterator state in BIDI_IT, advance one character position in the buffer to the next character (in the logical order), resolve the bidi type of that next character, and return that type. */ -bidi_type_t +static bidi_type_t bidi_type_of_next_char (struct bidi_it *bidi_it) { bidi_type_t type; @@ -1643,7 +1648,7 @@ the buffer to the next character (in the logical order), resolve the embedding and implicit levels of that next character, and return the resulting level. */ -int +static int bidi_level_of_next_char (struct bidi_it *bidi_it) { bidi_type_t type;
--- a/src/buffer.c Tue Apr 20 15:30:26 2010 +0900 +++ b/src/buffer.c Tue Apr 20 16:26:02 2010 +0900 @@ -78,9 +78,6 @@ be a DEFVAR_PER_BUFFER for the slot, there is no default value for it; and the corresponding slot in buffer_defaults is not used. - If a slot is -2, then there is no DEFVAR_PER_BUFFER for it, - but there is a default value which is copied into each buffer. - If a slot in this structure corresponding to a DEFVAR_PER_BUFFER is zero, that is a bug */ @@ -94,6 +91,12 @@ /* A Lisp_Object pointer to the above, used for staticpro */ static Lisp_Object Vbuffer_local_symbols; +/* Return the symbol of the per-buffer variable at offset OFFSET in + the buffer structure. */ + +#define PER_BUFFER_SYMBOL(OFFSET) \ + (*(Lisp_Object *)((OFFSET) + (char *) &buffer_local_symbols)) + /* Flags indicating which built-in buffer-local variables are permanent locals. */ static char buffer_permanent_local_flags[MAX_PER_BUFFER_VARS]; @@ -507,7 +510,7 @@ continue; obj = PER_BUFFER_VALUE (from, offset); - if (MARKERP (obj)) + if (MARKERP (obj) && XMARKER (obj)->buffer == from) { struct Lisp_Marker *m = XMARKER (obj); obj = Fmake_marker (); @@ -770,9 +773,7 @@ { Lisp_Object tmp, prop, last = Qnil; for (tmp = b->local_var_alist; CONSP (tmp); tmp = XCDR (tmp)) - if (CONSP (XCAR (tmp)) - && SYMBOLP (XCAR (XCAR (tmp))) - && !NILP (prop = Fget (XCAR (XCAR (tmp)), Qpermanent_local))) + if (!NILP (prop = Fget (XCAR (XCAR (tmp)), Qpermanent_local))) { /* If permanent-local, keep it. */ last = tmp; @@ -822,9 +823,7 @@ int idx = PER_BUFFER_IDX (offset); if ((idx > 0 && (permanent_too - || buffer_permanent_local_flags[idx] == 0)) - /* Is -2 used anywhere? */ - || idx == -2) + || buffer_permanent_local_flags[idx] == 0))) PER_BUFFER_VALUE (b, offset) = PER_BUFFER_DEFAULT (offset); } } @@ -938,59 +937,49 @@ CHECK_SYMBOL (variable); CHECK_BUFFER (buffer); buf = XBUFFER (buffer); - - sym = indirect_variable (XSYMBOL (variable)); - XSETSYMBOL (variable, sym); - - /* Look in local_var_list */ - result = Fassoc (variable, buf->local_var_alist); - if (NILP (result)) + sym = XSYMBOL (variable); + + start: + switch (sym->redirect) { - int offset, idx; - int found = 0; - - /* Look in special slots */ - /* buffer-local Lisp variables start at `undo_list', - tho only the ones from `name' on are GC'd normally. */ - for (offset = PER_BUFFER_VAR_OFFSET (undo_list); - offset < sizeof (struct buffer); - /* sizeof EMACS_INT == sizeof Lisp_Object */ - offset += (sizeof (EMACS_INT))) - { - idx = PER_BUFFER_IDX (offset); - if ((idx == -1 || PER_BUFFER_VALUE_P (buf, idx)) - && SYMBOLP (PER_BUFFER_SYMBOL (offset)) - && EQ (PER_BUFFER_SYMBOL (offset), variable)) - { - result = PER_BUFFER_VALUE (buf, offset); - found = 1; - break; - } - } - - if (!found) - result = Fdefault_value (variable); - } - else - { - Lisp_Object valcontents; - Lisp_Object current_alist_element; - - /* What binding is loaded right now? */ - valcontents = sym->value; - current_alist_element - = XCAR (XBUFFER_LOCAL_VALUE (valcontents)->cdr); - - /* The value of the currently loaded binding is not - stored in it, but rather in the realvalue slot. - Store that value into the binding it belongs to - in case that is the one we are about to use. */ - - Fsetcdr (current_alist_element, - do_symval_forwarding (XBUFFER_LOCAL_VALUE (valcontents)->realvalue)); - - /* Now get the (perhaps updated) value out of the binding. */ - result = XCDR (result); + case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; + case SYMBOL_PLAINVAL: result = SYMBOL_VAL (sym); break; + case SYMBOL_LOCALIZED: + { /* Look in local_var_alist. */ + struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym); + XSETSYMBOL (variable, sym); /* Update In case of aliasing. */ + result = Fassoc (variable, buf->local_var_alist); + if (!NILP (result)) + { + if (blv->fwd) + { /* What binding is loaded right now? */ + Lisp_Object current_alist_element = blv->valcell; + + /* The value of the currently loaded binding is not + stored in it, but rather in the realvalue slot. + Store that value into the binding it belongs to + in case that is the one we are about to use. */ + + XSETCDR (current_alist_element, + do_symval_forwarding (blv->fwd)); + } + /* Now get the (perhaps updated) value out of the binding. */ + result = XCDR (result); + } + else + result = Fdefault_value (variable); + break; + } + case SYMBOL_FORWARDED: + { + union Lisp_Fwd *fwd = SYMBOL_FWD (sym); + if (BUFFER_OBJFWDP (fwd)) + result = PER_BUFFER_VALUE (buf, XBUFFER_OBJFWD (fwd)->offset); + else + result = Fdefault_value (variable); + break; + } + default: abort (); } if (!EQ (result, Qunbound)) @@ -1025,12 +1014,7 @@ if (buf != current_buffer) val = XCDR (elt); - /* If symbol is unbound, put just the symbol in the list. */ - if (EQ (val, Qunbound)) - result = Fcons (XCAR (elt), result); - /* Otherwise, put (symbol . value) in the list. */ - else - result = Fcons (Fcons (XCAR (elt), val), result); + result = Fcons (Fcons (XCAR (elt), val), result); } return result; @@ -1862,8 +1846,7 @@ register struct buffer *b; { register struct buffer *old_buf; - register Lisp_Object tail, valcontents; - Lisp_Object tem; + register Lisp_Object tail; #ifdef USE_MMAP_FOR_BUFFERS if (b->text->beg == NULL) @@ -1935,34 +1918,21 @@ /* Look down buffer's list of local Lisp variables to find and update any that forward into C variables. */ - for (tail = b->local_var_alist; CONSP (tail); tail = XCDR (tail)) + do { - if (CONSP (XCAR (tail)) - && SYMBOLP (XCAR (XCAR (tail))) - && (valcontents = SYMBOL_VALUE (XCAR (XCAR (tail))), - (BUFFER_LOCAL_VALUEP (valcontents))) - && (tem = XBUFFER_LOCAL_VALUE (valcontents)->realvalue, - (BOOLFWDP (tem) || INTFWDP (tem) || OBJFWDP (tem)))) - /* Just reference the variable to cause it to become set for - this buffer. */ - Fsymbol_value (XCAR (XCAR (tail))); + for (tail = b->local_var_alist; CONSP (tail); tail = XCDR (tail)) + { + Lisp_Object var = XCAR (XCAR (tail)); + struct Lisp_Symbol *sym = XSYMBOL (var); + if (sym->redirect == SYMBOL_LOCALIZED /* Just to be sure. */ + && SYMBOL_BLV (sym)->fwd) + /* Just reference the variable + to cause it to become set for this buffer. */ + Fsymbol_value (var); + } } - /* Do the same with any others that were local to the previous buffer */ - - if (old_buf) - for (tail = old_buf->local_var_alist; CONSP (tail); tail = XCDR (tail)) - { - if (CONSP (tail) - && SYMBOLP (XCAR (XCAR (tail))) - && (valcontents = SYMBOL_VALUE (XCAR (XCAR (tail))), - (BUFFER_LOCAL_VALUEP (valcontents))) - && (tem = XBUFFER_LOCAL_VALUE (valcontents)->realvalue, - (BOOLFWDP (tem) || INTFWDP (tem) || OBJFWDP (tem)))) - /* Just reference the variable to cause it to become set for - this buffer. */ - Fsymbol_value (XCAR (XCAR (tail))); - } + while (b != old_buf && (b = old_buf, b)); } /* Switch to buffer B temporarily for redisplay purposes. @@ -2677,23 +2647,22 @@ swap_out_buffer_local_variables (b) struct buffer *b; { - Lisp_Object oalist, alist, sym, buffer; + Lisp_Object oalist, alist, buffer; XSETBUFFER (buffer, b); oalist = b->local_var_alist; for (alist = oalist; CONSP (alist); alist = XCDR (alist)) { - if (CONSP (XCAR (alist)) - && (sym = XCAR (XCAR (alist)), SYMBOLP (sym)) - /* Need not do anything if some other buffer's binding is - now encached. */ - && EQ (XBUFFER_LOCAL_VALUE (SYMBOL_VALUE (sym))->buffer, - buffer)) + Lisp_Object sym = XCAR (XCAR (alist)); + eassert (XSYMBOL (sym)->redirect == SYMBOL_LOCALIZED); + /* Need not do anything if some other buffer's binding is + now encached. */ + if (EQ (SYMBOL_BLV (XSYMBOL (sym))->where, buffer)) { /* Symbol is set up for this buffer's old local value: swap it out! */ - swap_in_global_binding (sym); + swap_in_global_binding (XSYMBOL (sym)); } } } @@ -5162,7 +5131,9 @@ /* Make sure all markable slots in buffer_defaults are initialized reasonably, so mark_buffer won't choke. */ reset_buffer (&buffer_defaults); + eassert (EQ (buffer_defaults.name, make_number (0))); reset_buffer_local_variables (&buffer_defaults, 1); + eassert (EQ (buffer_local_symbols.name, make_number (0))); reset_buffer (&buffer_local_symbols); reset_buffer_local_variables (&buffer_local_symbols, 1); /* Prevent GC from getting confused. */ @@ -5421,33 +5392,41 @@ in the buffer that is current now. */ /* TYPE is nil for a general Lisp variable. - An integer specifies a type; then only LIsp values + An integer specifies a type; then only Lisp values with that type code are allowed (except that nil is allowed too). - LNAME is the LIsp-level variable name. + LNAME is the Lisp-level variable name. VNAME is the name of the buffer slot. DOC is a dummy where you write the doc string as a comment. */ -#define DEFVAR_PER_BUFFER(lname, vname, type, doc) \ - defvar_per_buffer (lname, vname, type, 0) +#define DEFVAR_PER_BUFFER(lname, vname, type, doc) \ + do { \ + static struct Lisp_Buffer_Objfwd bo_fwd; \ + defvar_per_buffer (&bo_fwd, lname, vname, type, 0); \ + } while (0) static void -defvar_per_buffer (namestring, address, type, doc) +defvar_per_buffer (bo_fwd, namestring, address, type, doc) + struct Lisp_Buffer_Objfwd *bo_fwd; char *namestring; Lisp_Object *address; Lisp_Object type; char *doc; { - Lisp_Object sym, val; + struct Lisp_Symbol *sym; int offset; - sym = intern (namestring); - val = allocate_misc (); + sym = XSYMBOL (intern (namestring)); offset = (char *)address - (char *)current_buffer; - XMISCTYPE (val) = Lisp_Misc_Buffer_Objfwd; - XBUFFER_OBJFWD (val)->offset = offset; - XBUFFER_OBJFWD (val)->slottype = type; - SET_SYMBOL_VALUE (sym, val); - PER_BUFFER_SYMBOL (offset) = sym; + bo_fwd->type = Lisp_Fwd_Buffer_Obj; + bo_fwd->offset = offset; + bo_fwd->slottype = type; + sym->redirect = SYMBOL_FORWARDED; + { + /* I tried to do the job without a cast, but it seems impossible. + union Lisp_Fwd *fwd; &(fwd->u_buffer_objfwd) = bo_fwd; */ + SET_SYMBOL_FWD (sym, (union Lisp_Fwd *)bo_fwd); + } + XSETSYMBOL (PER_BUFFER_SYMBOL (offset), sym); if (PER_BUFFER_IDX (offset) == 0) /* Did a DEFVAR_PER_BUFFER without initializing the corresponding
--- a/src/buffer.h Tue Apr 20 15:30:26 2010 +0900 +++ b/src/buffer.h Tue Apr 20 16:26:02 2010 +0900 @@ -107,6 +107,11 @@ #define BUF_BEG(buf) (BEG) #define BUF_BEG_BYTE(buf) (BEG_BYTE) +/* !!!FIXME: all the BUF_BEGV/BUF_ZV/BUF_PT macros are flawed: + on indirect (or base) buffers, that value is only correct if that buffer + is the current_buffer, or if the buffer's text hasn't been modified (via + an indirect buffer) since it was last current. */ + /* Position of beginning of accessible range of buffer. */ #define BUF_BEGV(buf) ((buf)->begv) #define BUF_BEGV_BYTE(buf) ((buf)->begv_byte) @@ -313,7 +318,7 @@ - (ptr - (current_buffer)->text->beg <= (unsigned) (GPT_BYTE - BEG_BYTE) ? 0 : GAP_SIZE) \ + BEG_BYTE) -/* Return character at position POS. */ +/* Return character at byte position POS. */ #define FETCH_CHAR(pos) \ (!NILP (current_buffer->enable_multibyte_characters) \ @@ -327,7 +332,7 @@ /* Variables used locally in FETCH_MULTIBYTE_CHAR. */ extern unsigned char *_fetch_multibyte_char_p; -/* Return character code of multi-byte form at position POS. If POS +/* Return character code of multi-byte form at byte position POS. If POS doesn't point the head of valid multi-byte form, only the byte at POS is returned. No range checking. */ @@ -336,7 +341,7 @@ + (pos) + BEG_ADDR - BEG_BYTE), \ STRING_CHAR (_fetch_multibyte_char_p)) -/* Return character at position POS. If the current buffer is unibyte +/* Return character at byte position POS. If the current buffer is unibyte and the character is not ASCII, make the returning character multibyte. */ @@ -447,7 +452,10 @@ /* The markers that refer to this buffer. This is actually a single marker --- successive elements in its marker `chain' - are the other markers referring to this buffer. */ + are the other markers referring to this buffer. + This is a singly linked unordered list, which means that it's + very cheap to add a marker to the list and it's also very cheap + to move a marker within a buffer. */ struct Lisp_Marker *markers; /* Usually 0. Temporarily set to 1 in decode_coding_gap to @@ -843,6 +851,7 @@ be a Lisp-level local variable for the slot, it has no default value, and the corresponding slot in buffer_defaults is not used. */ + extern struct buffer buffer_local_flags; /* For each buffer slot, this points to the Lisp symbol name @@ -948,7 +957,7 @@ from the start of a buffer structure. */ #define PER_BUFFER_VAR_OFFSET(VAR) \ - ((char *) &buffer_local_flags.VAR - (char *) &buffer_local_flags) + ((char *) &((struct buffer *)0)->VAR - (char *) ((struct buffer *)0)) /* Return the index of buffer-local variable VAR. Each per-buffer variable has an index > 0 associated with it, except when it always @@ -1013,11 +1022,5 @@ #define PER_BUFFER_VALUE(BUFFER, OFFSET) \ (*(Lisp_Object *)((OFFSET) + (char *) (BUFFER))) -/* Return the symbol of the per-buffer variable at offset OFFSET in - the buffer structure. */ - -#define PER_BUFFER_SYMBOL(OFFSET) \ - (*(Lisp_Object *)((OFFSET) + (char *) &buffer_local_symbols)) - /* arch-tag: 679305dd-d41c-4a50-b170-3caf5c97b2d1 (do not change this comment) */
--- a/src/bytecode.c Tue Apr 20 15:30:26 2010 +0900 +++ b/src/bytecode.c Tue Apr 20 16:26:02 2010 +0900 @@ -505,8 +505,9 @@ v1 = vectorp[op]; if (SYMBOLP (v1)) { - v2 = SYMBOL_VALUE (v1); - if (MISCP (v2) || EQ (v2, Qunbound)) + if (XSYMBOL (v1)->redirect != SYMBOL_PLAINVAL + || (v2 = SYMBOL_VAL (XSYMBOL (v1)), + EQ (v2, Qunbound))) { BEFORE_POTENTIAL_GC (); v2 = Fsymbol_value (v1); @@ -597,10 +598,9 @@ /* Inline the most common case. */ if (SYMBOLP (sym) && !EQ (val, Qunbound) - && !XSYMBOL (sym)->indirect_variable - && !SYMBOL_CONSTANT_P (sym) - && !MISCP (XSYMBOL (sym)->value)) - XSYMBOL (sym)->value = val; + && !XSYMBOL (sym)->redirect + && !SYMBOL_CONSTANT_P (sym)) + XSYMBOL (sym)->val.value = val; else { BEFORE_POTENTIAL_GC ();
--- a/src/character.h Tue Apr 20 15:30:26 2010 +0900 +++ b/src/character.h Tue Apr 20 16:26:02 2010 +0900 @@ -296,7 +296,7 @@ /* If P is after LIMIT, advance P to the previous character boundary. Assumes that P is already at a character boundary of the same - mulitbyte form whose beginning address is LIMIT. */ + multibyte form whose beginning address is LIMIT. */ #define PREV_CHAR_BOUNDARY(p, limit) \ do { \
--- a/src/coding.c Tue Apr 20 15:30:26 2010 +0900 +++ b/src/coding.c Tue Apr 20 16:26:02 2010 +0900 @@ -6408,7 +6408,7 @@ { /* We didn't find an 8-bit code. We may have found a null-byte, but it's very - rare that a binary file confirm to + rare that a binary file conforms to ISO-2022. */ src = src_end; coding->head_ascii = src - coding->source;
--- a/src/data.c Tue Apr 20 15:30:26 2010 +0900 +++ b/src/data.c Tue Apr 20 16:26:02 2010 +0900 @@ -91,7 +91,7 @@ Lisp_Object Qinteractive_form; -static Lisp_Object swap_in_symval_forwarding P_ ((Lisp_Object, Lisp_Object)); +static void swap_in_symval_forwarding (struct Lisp_Symbol *, struct Lisp_Buffer_Local_Value *); Lisp_Object Vmost_positive_fixnum, Vmost_negative_fixnum; @@ -582,12 +582,35 @@ register Lisp_Object symbol; { Lisp_Object valcontents; + struct Lisp_Symbol *sym; CHECK_SYMBOL (symbol); - - valcontents = SYMBOL_VALUE (symbol); - - if (BUFFER_LOCAL_VALUEP (valcontents)) - valcontents = swap_in_symval_forwarding (symbol, valcontents); + sym = XSYMBOL (symbol); + + start: + switch (sym->redirect) + { + case SYMBOL_PLAINVAL: valcontents = SYMBOL_VAL (sym); break; + case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; + case SYMBOL_LOCALIZED: + { + struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym); + if (blv->fwd) + /* In set_internal, we un-forward vars when their value is + set to Qunbound. */ + return Qt; + else + { + swap_in_symval_forwarding (sym, blv); + valcontents = BLV_VALUE (blv); + } + break; + } + case SYMBOL_FORWARDED: + /* In set_internal, we un-forward vars when their value is + set to Qunbound. */ + return Qt; + default: abort (); + } return (EQ (valcontents, Qunbound) ? Qnil : Qt); } @@ -824,14 +847,14 @@ hare = tortoise = symbol; - while (hare->indirect_variable) + while (hare->redirect == SYMBOL_VARALIAS) { - hare = XSYMBOL (hare->value); - if (!hare->indirect_variable) + hare = SYMBOL_ALIAS (hare); + if (hare->redirect != SYMBOL_VARALIAS) break; - hare = XSYMBOL (hare->value); - tortoise = XSYMBOL (tortoise->value); + hare = SYMBOL_ALIAS (hare); + tortoise = SYMBOL_ALIAS (tortoise); if (hare == tortoise) { @@ -865,44 +888,46 @@ This does not handle buffer-local variables; use swap_in_symval_forwarding for that. */ +#define do_blv_forwarding(blv) \ + ((blv)->forwarded ? do_symval_forwarding (BLV_FWD (blv)) : BLV_VALUE (blv)) + Lisp_Object do_symval_forwarding (valcontents) - register Lisp_Object valcontents; + register union Lisp_Fwd *valcontents; { register Lisp_Object val; - if (MISCP (valcontents)) - switch (XMISCTYPE (valcontents)) - { - case Lisp_Misc_Intfwd: - XSETINT (val, *XINTFWD (valcontents)->intvar); - return val; - - case Lisp_Misc_Boolfwd: - return (*XBOOLFWD (valcontents)->boolvar ? Qt : Qnil); - - case Lisp_Misc_Objfwd: - return *XOBJFWD (valcontents)->objvar; - - case Lisp_Misc_Buffer_Objfwd: - return PER_BUFFER_VALUE (current_buffer, - XBUFFER_OBJFWD (valcontents)->offset); - - case Lisp_Misc_Kboard_Objfwd: - /* We used to simply use current_kboard here, but from Lisp - code, it's value is often unexpected. It seems nicer to - allow constructions like this to work as intuitively expected: - - (with-selected-frame frame - (define-key local-function-map "\eOP" [f1])) - - On the other hand, this affects the semantics of - last-command and real-last-command, and people may rely on - that. I took a quick look at the Lisp codebase, and I - don't think anything will break. --lorentey */ - return *(Lisp_Object *)(XKBOARD_OBJFWD (valcontents)->offset - + (char *)FRAME_KBOARD (SELECTED_FRAME ())); - } - return valcontents; + switch (XFWDTYPE (valcontents)) + { + case Lisp_Fwd_Int: + XSETINT (val, *XINTFWD (valcontents)->intvar); + return val; + + case Lisp_Fwd_Bool: + return (*XBOOLFWD (valcontents)->boolvar ? Qt : Qnil); + + case Lisp_Fwd_Obj: + return *XOBJFWD (valcontents)->objvar; + + case Lisp_Fwd_Buffer_Obj: + return PER_BUFFER_VALUE (current_buffer, + XBUFFER_OBJFWD (valcontents)->offset); + + case Lisp_Fwd_Kboard_Obj: + /* We used to simply use current_kboard here, but from Lisp + code, it's value is often unexpected. It seems nicer to + allow constructions like this to work as intuitively expected: + + (with-selected-frame frame + (define-key local-function-map "\eOP" [f1])) + + On the other hand, this affects the semantics of + last-command and real-last-command, and people may rely on + that. I took a quick look at the Lisp codebase, and I + don't think anything will break. --lorentey */ + return *(Lisp_Object *)(XKBOARD_OBJFWD (valcontents)->offset + + (char *)FRAME_KBOARD (SELECTED_FRAME ())); + default: abort (); + } } /* Store NEWVAL into SYMBOL, where VALCONTENTS is found in the value cell @@ -913,102 +938,93 @@ BUF non-zero means set the value in buffer BUF instead of the current buffer. This only plays a role for per-buffer variables. */ -void -store_symval_forwarding (symbol, valcontents, newval, buf) - Lisp_Object symbol; - register Lisp_Object valcontents, newval; +#define store_blv_forwarding(blv, newval, buf) \ + do { \ + if ((blv)->forwarded) \ + store_symval_forwarding (BLV_FWD (blv), (newval), (buf)); \ + else \ + SET_BLV_VALUE (blv, newval); \ + } while (0) + +static void +store_symval_forwarding (/* symbol, */ valcontents, newval, buf) + /* struct Lisp_Symbol *symbol; */ + union Lisp_Fwd *valcontents; + register Lisp_Object newval; struct buffer *buf; { - switch (SWITCH_ENUM_CAST (XTYPE (valcontents))) + switch (XFWDTYPE (valcontents)) { - case Lisp_Misc: - switch (XMISCTYPE (valcontents)) + case Lisp_Fwd_Int: + CHECK_NUMBER (newval); + *XINTFWD (valcontents)->intvar = XINT (newval); + break; + + case Lisp_Fwd_Bool: + *XBOOLFWD (valcontents)->boolvar = !NILP (newval); + break; + + case Lisp_Fwd_Obj: + *XOBJFWD (valcontents)->objvar = newval; + + /* If this variable is a default for something stored + in the buffer itself, such as default-fill-column, + find the buffers that don't have local values for it + and update them. */ + if (XOBJFWD (valcontents)->objvar > (Lisp_Object *) &buffer_defaults + && XOBJFWD (valcontents)->objvar < (Lisp_Object *) (&buffer_defaults + 1)) { - case Lisp_Misc_Intfwd: - CHECK_NUMBER (newval); - *XINTFWD (valcontents)->intvar = XINT (newval); - /* This can never happen since intvar points to an EMACS_INT - which is at least large enough to hold a Lisp_Object. - if (*XINTFWD (valcontents)->intvar != XINT (newval)) - error ("Value out of range for variable `%s'", - SDATA (SYMBOL_NAME (symbol))); */ - break; - - case Lisp_Misc_Boolfwd: - *XBOOLFWD (valcontents)->boolvar = !NILP (newval); - break; - - case Lisp_Misc_Objfwd: - *XOBJFWD (valcontents)->objvar = newval; - - /* If this variable is a default for something stored - in the buffer itself, such as default-fill-column, - find the buffers that don't have local values for it - and update them. */ - if (XOBJFWD (valcontents)->objvar > (Lisp_Object *) &buffer_defaults - && XOBJFWD (valcontents)->objvar < (Lisp_Object *) (&buffer_defaults + 1)) + int offset = ((char *) XOBJFWD (valcontents)->objvar + - (char *) &buffer_defaults); + int idx = PER_BUFFER_IDX (offset); + + Lisp_Object tail; + + if (idx <= 0) + break; + + for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) { - int offset = ((char *) XOBJFWD (valcontents)->objvar - - (char *) &buffer_defaults); - int idx = PER_BUFFER_IDX (offset); - - Lisp_Object tail; - - if (idx <= 0) - break; - - for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) - { - Lisp_Object buf; - struct buffer *b; - - buf = Fcdr (XCAR (tail)); - if (!BUFFERP (buf)) continue; - b = XBUFFER (buf); - - if (! PER_BUFFER_VALUE_P (b, idx)) - PER_BUFFER_VALUE (b, offset) = newval; - } + Lisp_Object buf; + struct buffer *b; + + buf = Fcdr (XCAR (tail)); + if (!BUFFERP (buf)) continue; + b = XBUFFER (buf); + + if (! PER_BUFFER_VALUE_P (b, idx)) + PER_BUFFER_VALUE (b, offset) = newval; } - break; - - case Lisp_Misc_Buffer_Objfwd: - { - int offset = XBUFFER_OBJFWD (valcontents)->offset; - Lisp_Object type = XBUFFER_OBJFWD (valcontents)->slottype; - - if (!(NILP (type) || NILP (newval) - || (XINT (type) == LISP_INT_TAG - ? INTEGERP (newval) - : XTYPE (newval) == XINT (type)))) - buffer_slot_type_mismatch (newval, XINT (type)); - - if (buf == NULL) - buf = current_buffer; - PER_BUFFER_VALUE (buf, offset) = newval; - } - break; - - case Lisp_Misc_Kboard_Objfwd: - { - char *base = (char *) FRAME_KBOARD (SELECTED_FRAME ()); - char *p = base + XKBOARD_OBJFWD (valcontents)->offset; - *(Lisp_Object *) p = newval; - } - break; - - default: - goto def; } break; + case Lisp_Fwd_Buffer_Obj: + { + int offset = XBUFFER_OBJFWD (valcontents)->offset; + Lisp_Object type = XBUFFER_OBJFWD (valcontents)->slottype; + + if (!(NILP (type) || NILP (newval) + || (XINT (type) == LISP_INT_TAG + ? INTEGERP (newval) + : XTYPE (newval) == XINT (type)))) + buffer_slot_type_mismatch (newval, XINT (type)); + + if (buf == NULL) + buf = current_buffer; + PER_BUFFER_VALUE (buf, offset) = newval; + } + break; + + case Lisp_Fwd_Kboard_Obj: + { + char *base = (char *) FRAME_KBOARD (SELECTED_FRAME ()); + char *p = base + XKBOARD_OBJFWD (valcontents)->offset; + *(Lisp_Object *) p = newval; + } + break; + default: - def: - valcontents = SYMBOL_VALUE (symbol); - if (BUFFER_LOCAL_VALUEP (valcontents)) - XBUFFER_LOCAL_VALUE (valcontents)->realvalue = newval; - else - SET_SYMBOL_VALUE (symbol, newval); + abort (); /* goto def; */ } } @@ -1017,25 +1033,22 @@ void swap_in_global_binding (symbol) - Lisp_Object symbol; + struct Lisp_Symbol *symbol; { - Lisp_Object valcontents = SYMBOL_VALUE (symbol); - struct Lisp_Buffer_Local_Value *blv = XBUFFER_LOCAL_VALUE (valcontents); - Lisp_Object cdr = blv->cdr; + struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (symbol); /* Unload the previously loaded binding. */ - Fsetcdr (XCAR (cdr), - do_symval_forwarding (blv->realvalue)); + if (blv->fwd) + SET_BLV_VALUE (blv, do_symval_forwarding (blv->fwd)); /* Select the global binding in the symbol. */ - XSETCAR (cdr, cdr); - store_symval_forwarding (symbol, blv->realvalue, XCDR (cdr), NULL); + blv->valcell = blv->defcell; + if (blv->fwd) + store_symval_forwarding (blv->fwd, XCDR (blv->defcell), NULL); /* Indicate that the global binding is set up now. */ - blv->frame = Qnil; - blv->buffer = Qnil; - blv->found_for_frame = 0; - blv->found_for_buffer = 0; + blv->where = Qnil; + SET_BLV_FOUND (blv, 0); } /* Set up the buffer-local symbol SYMBOL for validity in the current buffer. @@ -1045,55 +1058,50 @@ Return the value forwarded one step past the buffer-local stage. This could be another forwarding pointer. */ -static Lisp_Object -swap_in_symval_forwarding (symbol, valcontents) - Lisp_Object symbol, valcontents; +static void +swap_in_symval_forwarding (symbol, blv) + struct Lisp_Symbol *symbol; + struct Lisp_Buffer_Local_Value *blv; { register Lisp_Object tem1; - tem1 = XBUFFER_LOCAL_VALUE (valcontents)->buffer; + eassert (blv == SYMBOL_BLV (symbol)); + + tem1 = blv->where; if (NILP (tem1) - || current_buffer != XBUFFER (tem1) - || (XBUFFER_LOCAL_VALUE (valcontents)->check_frame - && ! EQ (selected_frame, XBUFFER_LOCAL_VALUE (valcontents)->frame))) + || (blv->frame_local + ? !EQ (selected_frame, tem1) + : current_buffer != XBUFFER (tem1))) { - struct Lisp_Symbol *sym = XSYMBOL (symbol); - if (sym->indirect_variable) - { - sym = indirect_variable (sym); - XSETSYMBOL (symbol, sym); - } /* Unload the previously loaded binding. */ - tem1 = XCAR (XBUFFER_LOCAL_VALUE (valcontents)->cdr); - Fsetcdr (tem1, - do_symval_forwarding (XBUFFER_LOCAL_VALUE (valcontents)->realvalue)); + tem1 = blv->valcell; + if (blv->fwd) + SET_BLV_VALUE (blv, do_symval_forwarding (blv->fwd)); /* Choose the new binding. */ - tem1 = assq_no_quit (symbol, current_buffer->local_var_alist); - XBUFFER_LOCAL_VALUE (valcontents)->found_for_frame = 0; - XBUFFER_LOCAL_VALUE (valcontents)->found_for_buffer = 0; - if (NILP (tem1)) - { - if (XBUFFER_LOCAL_VALUE (valcontents)->check_frame) - tem1 = assq_no_quit (symbol, XFRAME (selected_frame)->param_alist); - if (! NILP (tem1)) - XBUFFER_LOCAL_VALUE (valcontents)->found_for_frame = 1; - else - tem1 = XBUFFER_LOCAL_VALUE (valcontents)->cdr; - } - else - XBUFFER_LOCAL_VALUE (valcontents)->found_for_buffer = 1; + { + Lisp_Object var; + XSETSYMBOL (var, symbol); + if (blv->frame_local) + { + tem1 = assq_no_quit (var, XFRAME (selected_frame)->param_alist); + blv->where = selected_frame; + } + else + { + tem1 = assq_no_quit (var, current_buffer->local_var_alist); + XSETBUFFER (blv->where, current_buffer); + } + } + if (!(blv->found = !NILP (tem1))) + tem1 = blv->defcell; /* Load the new binding. */ - XSETCAR (XBUFFER_LOCAL_VALUE (valcontents)->cdr, tem1); - XSETBUFFER (XBUFFER_LOCAL_VALUE (valcontents)->buffer, current_buffer); - XBUFFER_LOCAL_VALUE (valcontents)->frame = selected_frame; - store_symval_forwarding (symbol, - XBUFFER_LOCAL_VALUE (valcontents)->realvalue, - Fcdr (tem1), NULL); + blv->valcell = tem1; + if (blv->fwd) + store_symval_forwarding (blv->fwd, BLV_VALUE (blv), NULL); } - return XBUFFER_LOCAL_VALUE (valcontents)->realvalue; } /* Find the value of a symbol, returning Qunbound if it's not bound. @@ -1106,16 +1114,27 @@ find_symbol_value (symbol) Lisp_Object symbol; { - register Lisp_Object valcontents; - register Lisp_Object val; + struct Lisp_Symbol *sym; CHECK_SYMBOL (symbol); - valcontents = SYMBOL_VALUE (symbol); - - if (BUFFER_LOCAL_VALUEP (valcontents)) - valcontents = swap_in_symval_forwarding (symbol, valcontents); - - return do_symval_forwarding (valcontents); + sym = XSYMBOL (symbol); + + start: + switch (sym->redirect) + { + case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; + case SYMBOL_PLAINVAL: return SYMBOL_VAL (sym); + case SYMBOL_LOCALIZED: + { + struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym); + swap_in_symval_forwarding (sym, blv); + return blv->fwd ? do_symval_forwarding (blv->fwd) : BLV_VALUE (blv); + } + /* FALLTHROUGH */ + case SYMBOL_FORWARDED: + return do_symval_forwarding (SYMBOL_FWD (sym)); + default: abort (); + } } DEFUN ("symbol-value", Fsymbol_value, Ssymbol_value, 1, 1, 0, @@ -1137,26 +1156,25 @@ (symbol, newval) register Lisp_Object symbol, newval; { - return set_internal (symbol, newval, current_buffer, 0); + set_internal (symbol, newval, current_buffer, 0); + return newval; } /* Return 1 if SYMBOL currently has a let-binding which was made in the buffer that is now current. */ static int -let_shadows_buffer_binding_p (symbol) - struct Lisp_Symbol *symbol; +let_shadows_buffer_binding_p (struct Lisp_Symbol *symbol) { - volatile struct specbinding *p; + struct specbinding *p; for (p = specpdl_ptr - 1; p >= specpdl; p--) if (p->func == NULL && CONSP (p->symbol)) { struct Lisp_Symbol *let_bound_symbol = XSYMBOL (XCAR (p->symbol)); - if ((symbol == let_bound_symbol - || (let_bound_symbol->indirect_variable - && symbol == indirect_variable (let_bound_symbol))) + eassert (let_bound_symbol->redirect != SYMBOL_VARALIAS); + if (symbol == let_bound_symbol && XBUFFER (XCDR (XCDR (p->symbol))) == current_buffer) break; } @@ -1164,6 +1182,19 @@ return p >= specpdl; } +static int +let_shadows_global_binding_p (symbol) + Lisp_Object symbol; +{ + struct specbinding *p; + + for (p = specpdl_ptr - 1; p >= specpdl; p--) + if (p->func == NULL && EQ (p->symbol, symbol)) + break; + + return p >= specpdl; +} + /* Store the value NEWVAL into SYMBOL. If buffer-locality is an issue, BUF specifies which buffer to use. (0 stands for the current buffer.) @@ -1172,133 +1203,155 @@ local in every buffer where it is set, then we make it local. If BINDFLAG is nonzero, we don't do that. */ -Lisp_Object +void set_internal (symbol, newval, buf, bindflag) register Lisp_Object symbol, newval; struct buffer *buf; int bindflag; { int voide = EQ (newval, Qunbound); - - register Lisp_Object valcontents, innercontents, tem1, current_alist_element; + struct Lisp_Symbol *sym; + Lisp_Object tem1; if (buf == 0) buf = current_buffer; /* If restoring in a dead buffer, do nothing. */ if (NILP (buf->name)) - return newval; + return; CHECK_SYMBOL (symbol); - if (SYMBOL_CONSTANT_P (symbol) - && (NILP (Fkeywordp (symbol)) - || !EQ (newval, SYMBOL_VALUE (symbol)))) - xsignal1 (Qsetting_constant, symbol); - - innercontents = valcontents = SYMBOL_VALUE (symbol); - - if (BUFFER_OBJFWDP (valcontents)) + if (SYMBOL_CONSTANT_P (symbol)) { - int offset = XBUFFER_OBJFWD (valcontents)->offset; - int idx = PER_BUFFER_IDX (offset); - if (idx > 0 - && !bindflag - && !let_shadows_buffer_binding_p (XSYMBOL (symbol))) - SET_PER_BUFFER_VALUE_P (buf, idx, 1); + if (NILP (Fkeywordp (symbol)) + || !EQ (newval, Fsymbol_value (symbol))) + xsignal1 (Qsetting_constant, symbol); + else + /* Allow setting keywords to their own value. */ + return; } - else if (BUFFER_LOCAL_VALUEP (valcontents)) + + sym = XSYMBOL (symbol); + + start: + switch (sym->redirect) { - /* valcontents is a struct Lisp_Buffer_Local_Value. */ - if (XSYMBOL (symbol)->indirect_variable) - XSETSYMBOL (symbol, indirect_variable (XSYMBOL (symbol))); - - /* What binding is loaded right now? */ - current_alist_element - = XCAR (XBUFFER_LOCAL_VALUE (valcontents)->cdr); - - /* If the current buffer is not the buffer whose binding is - loaded, or if there may be frame-local bindings and the frame - isn't the right one, or if it's a Lisp_Buffer_Local_Value and - the default binding is loaded, the loaded binding may be the - wrong one. */ - if (!BUFFERP (XBUFFER_LOCAL_VALUE (valcontents)->buffer) - || buf != XBUFFER (XBUFFER_LOCAL_VALUE (valcontents)->buffer) - || (XBUFFER_LOCAL_VALUE (valcontents)->check_frame - && !EQ (selected_frame, XBUFFER_LOCAL_VALUE (valcontents)->frame)) - /* Also unload a global binding (if the var is local_if_set). */ - || (EQ (XCAR (current_alist_element), - current_alist_element))) - { - /* The currently loaded binding is not necessarily valid. - We need to unload it, and choose a new binding. */ - - /* Write out `realvalue' to the old loaded binding. */ - Fsetcdr (current_alist_element, - do_symval_forwarding (XBUFFER_LOCAL_VALUE (valcontents)->realvalue)); - - /* Find the new binding. */ - tem1 = Fassq (symbol, buf->local_var_alist); - XBUFFER_LOCAL_VALUE (valcontents)->found_for_buffer = 1; - XBUFFER_LOCAL_VALUE (valcontents)->found_for_frame = 0; - - if (NILP (tem1)) + case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; + case SYMBOL_PLAINVAL: SET_SYMBOL_VAL (sym , newval); return; + case SYMBOL_LOCALIZED: + { + struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym); + Lisp_Object tmp; XSETBUFFER (tmp, buf); + + /* If the current buffer is not the buffer whose binding is + loaded, or if there may be frame-local bindings and the frame + isn't the right one, or if it's a Lisp_Buffer_Local_Value and + the default binding is loaded, the loaded binding may be the + wrong one. */ + if (!EQ (blv->where, + blv->frame_local ? selected_frame : tmp) + /* Also unload a global binding (if the var is local_if_set). */ + || (EQ (blv->valcell, blv->defcell))) + { + /* The currently loaded binding is not necessarily valid. + We need to unload it, and choose a new binding. */ + + /* Write out `realvalue' to the old loaded binding. */ + if (blv->fwd) + SET_BLV_VALUE (blv, do_symval_forwarding (blv->fwd)); + + /* Find the new binding. */ { - /* This buffer still sees the default value. */ - - /* If the variable is not local_if_set, - or if this is `let' rather than `set', - make CURRENT-ALIST-ELEMENT point to itself, - indicating that we're seeing the default value. - Likewise if the variable has been let-bound - in the current buffer. */ - if (bindflag || !XBUFFER_LOCAL_VALUE (valcontents)->local_if_set - || let_shadows_buffer_binding_p (XSYMBOL (symbol))) + XSETSYMBOL (symbol, sym); /* May have changed via aliasing. */ + if (blv->frame_local) { - XBUFFER_LOCAL_VALUE (valcontents)->found_for_buffer = 0; - - if (XBUFFER_LOCAL_VALUE (valcontents)->check_frame) - tem1 = Fassq (symbol, - XFRAME (selected_frame)->param_alist); - - if (! NILP (tem1)) - XBUFFER_LOCAL_VALUE (valcontents)->found_for_frame = 1; - else - tem1 = XBUFFER_LOCAL_VALUE (valcontents)->cdr; + tem1 = Fassq (symbol, XFRAME (selected_frame)->param_alist); + blv->where = selected_frame; } - /* If it's a Lisp_Buffer_Local_Value, being set not bound, - and we're not within a let that was made for this buffer, - create a new buffer-local binding for the variable. - That means, give this buffer a new assoc for a local value - and load that binding. */ else { - tem1 = Fcons (symbol, XCDR (current_alist_element)); - buf->local_var_alist - = Fcons (tem1, buf->local_var_alist); + tem1 = Fassq (symbol, buf->local_var_alist); + blv->where = tmp; } } - - /* Record which binding is now loaded. */ - XSETCAR (XBUFFER_LOCAL_VALUE (valcontents)->cdr, tem1); - - /* Set `buffer' and `frame' slots for the binding now loaded. */ - XSETBUFFER (XBUFFER_LOCAL_VALUE (valcontents)->buffer, buf); - XBUFFER_LOCAL_VALUE (valcontents)->frame = selected_frame; - } - innercontents = XBUFFER_LOCAL_VALUE (valcontents)->realvalue; - - /* Store the new value in the cons-cell. */ - XSETCDR (XCAR (XBUFFER_LOCAL_VALUE (valcontents)->cdr), newval); + blv->found = 1; + + if (NILP (tem1)) + { + /* This buffer still sees the default value. */ + + /* If the variable is a Lisp_Some_Buffer_Local_Value, + or if this is `let' rather than `set', + make CURRENT-ALIST-ELEMENT point to itself, + indicating that we're seeing the default value. + Likewise if the variable has been let-bound + in the current buffer. */ + if (bindflag || !blv->local_if_set + || let_shadows_buffer_binding_p (sym)) + { + blv->found = 0; + tem1 = blv->defcell; + } + /* If it's a local_if_set, being set not bound, + and we're not within a let that was made for this buffer, + create a new buffer-local binding for the variable. + That means, give this buffer a new assoc for a local value + and load that binding. */ + else + { + /* local_if_set is only supported for buffer-local + bindings, not for frame-local bindings. */ + eassert (!blv->frame_local); + tem1 = Fcons (symbol, XCDR (blv->defcell)); + buf->local_var_alist + = Fcons (tem1, buf->local_var_alist); + } + } + + /* Record which binding is now loaded. */ + blv->valcell = tem1; + } + + /* Store the new value in the cons cell. */ + SET_BLV_VALUE (blv, newval); + + if (blv->fwd) + { + if (voide) + /* If storing void (making the symbol void), forward only through + buffer-local indicator, not through Lisp_Objfwd, etc. */ + blv->fwd = NULL; + else + store_symval_forwarding (blv->fwd, newval, buf); + } + break; + } + case SYMBOL_FORWARDED: + { + union Lisp_Fwd *innercontents = SYMBOL_FWD (sym); + if (BUFFER_OBJFWDP (innercontents)) + { + int offset = XBUFFER_OBJFWD (innercontents)->offset; + int idx = PER_BUFFER_IDX (offset); + if (idx > 0 + && !bindflag + && !let_shadows_buffer_binding_p (sym)) + SET_PER_BUFFER_VALUE_P (buf, idx, 1); + } + + if (voide) + { /* If storing void (making the symbol void), forward only through + buffer-local indicator, not through Lisp_Objfwd, etc. */ + sym->redirect = SYMBOL_PLAINVAL; + SET_SYMBOL_VAL (sym, newval); + } + else + store_symval_forwarding (/* sym, */ innercontents, newval, buf); + break; + } + default: abort (); } - - /* If storing void (making the symbol void), forward only through - buffer-local indicator, not through Lisp_Objfwd, etc. */ - if (voide) - store_symval_forwarding (symbol, Qnil, newval, buf); - else - store_symval_forwarding (symbol, innercontents, newval, buf); - - return newval; + return; } /* Access or set a buffer-local symbol's default value. */ @@ -1310,38 +1363,46 @@ default_value (symbol) Lisp_Object symbol; { - register Lisp_Object valcontents; + struct Lisp_Symbol *sym; CHECK_SYMBOL (symbol); - valcontents = SYMBOL_VALUE (symbol); - - /* For a built-in buffer-local variable, get the default value - rather than letting do_symval_forwarding get the current value. */ - if (BUFFER_OBJFWDP (valcontents)) - { - int offset = XBUFFER_OBJFWD (valcontents)->offset; - if (PER_BUFFER_IDX (offset) != 0) - return PER_BUFFER_DEFAULT (offset); - } - - /* Handle user-created local variables. */ - if (BUFFER_LOCAL_VALUEP (valcontents)) + sym = XSYMBOL (symbol); + + start: + switch (sym->redirect) { - /* If var is set up for a buffer that lacks a local value for it, - the current value is nominally the default value. - But the `realvalue' slot may be more up to date, since - ordinary setq stores just that slot. So use that. */ - Lisp_Object current_alist_element, alist_element_car; - current_alist_element - = XCAR (XBUFFER_LOCAL_VALUE (valcontents)->cdr); - alist_element_car = XCAR (current_alist_element); - if (EQ (alist_element_car, current_alist_element)) - return do_symval_forwarding (XBUFFER_LOCAL_VALUE (valcontents)->realvalue); - else - return XCDR (XBUFFER_LOCAL_VALUE (valcontents)->cdr); + case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; + case SYMBOL_PLAINVAL: return SYMBOL_VAL (sym); + case SYMBOL_LOCALIZED: + { + /* If var is set up for a buffer that lacks a local value for it, + the current value is nominally the default value. + But the `realvalue' slot may be more up to date, since + ordinary setq stores just that slot. So use that. */ + struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym); + if (blv->fwd && EQ (blv->valcell, blv->defcell)) + return do_symval_forwarding (blv->fwd); + else + return XCDR (blv->defcell); + } + case SYMBOL_FORWARDED: + { + union Lisp_Fwd *valcontents = SYMBOL_FWD (sym); + + /* For a built-in buffer-local variable, get the default value + rather than letting do_symval_forwarding get the current value. */ + if (BUFFER_OBJFWDP (valcontents)) + { + int offset = XBUFFER_OBJFWD (valcontents)->offset; + if (PER_BUFFER_IDX (offset) != 0) + return PER_BUFFER_DEFAULT (offset); + } + + /* For other variables, get the current value. */ + return do_symval_forwarding (valcontents); + } + default: abort (); } - /* For other variables, get the current value. */ - return do_symval_forwarding (valcontents); } DEFUN ("default-boundp", Fdefault_boundp, Sdefault_boundp, 1, 1, 0, @@ -1381,50 +1442,68 @@ (symbol, value) Lisp_Object symbol, value; { - register Lisp_Object valcontents, current_alist_element, alist_element_buffer; + struct Lisp_Symbol *sym; CHECK_SYMBOL (symbol); - valcontents = SYMBOL_VALUE (symbol); - - /* Handle variables like case-fold-search that have special slots - in the buffer. Make them work apparently like Lisp_Buffer_Local_Value - variables. */ - if (BUFFER_OBJFWDP (valcontents)) + if (SYMBOL_CONSTANT_P (symbol)) + { + if (NILP (Fkeywordp (symbol)) + || !EQ (value, Fdefault_value (symbol))) + xsignal1 (Qsetting_constant, symbol); + else + /* Allow setting keywords to their own value. */ + return value; + } + sym = XSYMBOL (symbol); + + start: + switch (sym->redirect) { - int offset = XBUFFER_OBJFWD (valcontents)->offset; - int idx = PER_BUFFER_IDX (offset); - - PER_BUFFER_DEFAULT (offset) = value; - - /* If this variable is not always local in all buffers, - set it in the buffers that don't nominally have a local value. */ - if (idx > 0) - { - struct buffer *b; - - for (b = all_buffers; b; b = b->next) - if (!PER_BUFFER_VALUE_P (b, idx)) - PER_BUFFER_VALUE (b, offset) = value; - } - return value; + case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; + case SYMBOL_PLAINVAL: return Fset (symbol, value); + case SYMBOL_LOCALIZED: + { + struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym); + + /* Store new value into the DEFAULT-VALUE slot. */ + XSETCDR (blv->defcell, value); + + /* If the default binding is now loaded, set the REALVALUE slot too. */ + if (blv->fwd && EQ (blv->defcell, blv->valcell)) + store_symval_forwarding (blv->fwd, value, NULL); + return value; + } + case SYMBOL_FORWARDED: + { + union Lisp_Fwd *valcontents = SYMBOL_FWD (sym); + + /* Handle variables like case-fold-search that have special slots + in the buffer. + Make them work apparently like Lisp_Buffer_Local_Value variables. */ + if (BUFFER_OBJFWDP (valcontents)) + { + int offset = XBUFFER_OBJFWD (valcontents)->offset; + int idx = PER_BUFFER_IDX (offset); + + PER_BUFFER_DEFAULT (offset) = value; + + /* If this variable is not always local in all buffers, + set it in the buffers that don't nominally have a local value. */ + if (idx > 0) + { + struct buffer *b; + + for (b = all_buffers; b; b = b->next) + if (!PER_BUFFER_VALUE_P (b, idx)) + PER_BUFFER_VALUE (b, offset) = value; + } + return value; + } + else + return Fset (symbol, value); + } + default: abort (); } - - if (!BUFFER_LOCAL_VALUEP (valcontents)) - return Fset (symbol, value); - - /* Store new value into the DEFAULT-VALUE slot. */ - XSETCDR (XBUFFER_LOCAL_VALUE (valcontents)->cdr, value); - - /* If the default binding is now loaded, set the REALVALUE slot too. */ - current_alist_element - = XCAR (XBUFFER_LOCAL_VALUE (valcontents)->cdr); - alist_element_buffer = Fcar (current_alist_element); - if (EQ (alist_element_buffer, current_alist_element)) - store_symval_forwarding (symbol, - XBUFFER_LOCAL_VALUE (valcontents)->realvalue, - value, NULL); - - return value; } DEFUN ("setq-default", Fsetq_default, Ssetq_default, 0, UNEVALLED, 0, @@ -1468,6 +1547,35 @@ /* Lisp functions for creating and removing buffer-local variables. */ +union Lisp_Val_Fwd + { + Lisp_Object value; + union Lisp_Fwd *fwd; + }; + +static struct Lisp_Buffer_Local_Value * +make_blv (struct Lisp_Symbol *sym, int forwarded, union Lisp_Val_Fwd valcontents) +{ + struct Lisp_Buffer_Local_Value *blv + = xmalloc (sizeof (struct Lisp_Buffer_Local_Value)); + Lisp_Object symbol; XSETSYMBOL (symbol, sym); + Lisp_Object tem = Fcons (symbol, (forwarded + ? do_symval_forwarding (valcontents.fwd) + : valcontents.value)); + /* Buffer_Local_Values cannot have as realval a buffer-local + or keyboard-local forwarding. */ + eassert (!(forwarded && BUFFER_OBJFWDP (valcontents.fwd))); + eassert (!(forwarded && KBOARD_OBJFWDP (valcontents.fwd))); + blv->fwd = forwarded ? valcontents.fwd : NULL; + blv->where = Qnil; + blv->frame_local = 0; + blv->local_if_set = 0; + blv->defcell = tem; + blv->valcell = tem; + SET_BLV_FOUND (blv, 0); + return blv; +} + DEFUN ("make-variable-buffer-local", Fmake_variable_buffer_local, Smake_variable_buffer_local, 1, 1, "vMake Variable Buffer Local: ", doc: /* Make VARIABLE become buffer-local whenever it is set. @@ -1485,42 +1593,58 @@ (variable) register Lisp_Object variable; { - register Lisp_Object tem, valcontents, newval; struct Lisp_Symbol *sym; + struct Lisp_Buffer_Local_Value *blv = NULL; + union Lisp_Val_Fwd valcontents; + int forwarded; CHECK_SYMBOL (variable); - sym = indirect_variable (XSYMBOL (variable)); - - valcontents = sym->value; - if (sym->constant || KBOARD_OBJFWDP (valcontents)) - error ("Symbol %s may not be buffer-local", SDATA (sym->xname)); - - if (BUFFER_OBJFWDP (valcontents)) - return variable; - else if (BUFFER_LOCAL_VALUEP (valcontents)) - { - if (XBUFFER_LOCAL_VALUE (valcontents)->check_frame) - error ("Symbol %s may not be buffer-local", SDATA (sym->xname)); - newval = valcontents; - } - else + sym = XSYMBOL (variable); + + start: + switch (sym->redirect) { - if (EQ (valcontents, Qunbound)) - sym->value = Qnil; - tem = Fcons (Qnil, Fsymbol_value (variable)); - XSETCAR (tem, tem); - newval = allocate_misc (); - XMISCTYPE (newval) = Lisp_Misc_Buffer_Local_Value; - XBUFFER_LOCAL_VALUE (newval)->realvalue = sym->value; - XBUFFER_LOCAL_VALUE (newval)->buffer = Fcurrent_buffer (); - XBUFFER_LOCAL_VALUE (newval)->frame = Qnil; - XBUFFER_LOCAL_VALUE (newval)->found_for_buffer = 0; - XBUFFER_LOCAL_VALUE (newval)->found_for_frame = 0; - XBUFFER_LOCAL_VALUE (newval)->check_frame = 0; - XBUFFER_LOCAL_VALUE (newval)->cdr = tem; - sym->value = newval; + case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; + case SYMBOL_PLAINVAL: + forwarded = 0; valcontents.value = SYMBOL_VAL (sym); + if (EQ (valcontents.value, Qunbound)) + valcontents.value = Qnil; + break; + case SYMBOL_LOCALIZED: + blv = SYMBOL_BLV (sym); + if (blv->frame_local) + error ("Symbol %s may not be buffer-local", + SDATA (SYMBOL_NAME (variable))); + break; + case SYMBOL_FORWARDED: + forwarded = 1; valcontents.fwd = SYMBOL_FWD (sym); + if (KBOARD_OBJFWDP (valcontents.fwd)) + error ("Symbol %s may not be buffer-local", + SDATA (SYMBOL_NAME (variable))); + else if (BUFFER_OBJFWDP (valcontents.fwd)) + return variable; + break; + default: abort (); } - XBUFFER_LOCAL_VALUE (newval)->local_if_set = 1; + + if (sym->constant) + error ("Symbol %s may not be buffer-local", SDATA (SYMBOL_NAME (variable))); + + if (!blv) + { + blv = make_blv (sym, forwarded, valcontents); + sym->redirect = SYMBOL_LOCALIZED; + SET_SYMBOL_BLV (sym, blv); + { + Lisp_Object symbol; + XSETSYMBOL (symbol, sym); /* In case `variable' is aliased. */ + if (let_shadows_global_binding_p (symbol)) + error ("Making %s buffer-local while let-bound!", + SDATA (SYMBOL_NAME (variable))); + } + } + + blv->local_if_set = 1; return variable; } @@ -1547,82 +1671,95 @@ (variable) register Lisp_Object variable; { - register Lisp_Object tem, valcontents; + register Lisp_Object tem; + int forwarded; + union Lisp_Val_Fwd valcontents; struct Lisp_Symbol *sym; + struct Lisp_Buffer_Local_Value *blv = NULL; CHECK_SYMBOL (variable); - sym = indirect_variable (XSYMBOL (variable)); - - valcontents = sym->value; - if (sym->constant || KBOARD_OBJFWDP (valcontents) - || (BUFFER_LOCAL_VALUEP (valcontents) - && (XBUFFER_LOCAL_VALUE (valcontents)->check_frame))) - error ("Symbol %s may not be buffer-local", SDATA (sym->xname)); - - if ((BUFFER_LOCAL_VALUEP (valcontents) - && XBUFFER_LOCAL_VALUE (valcontents)->local_if_set) - || BUFFER_OBJFWDP (valcontents)) + sym = XSYMBOL (variable); + + start: + switch (sym->redirect) + { + case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; + case SYMBOL_PLAINVAL: + forwarded = 0; valcontents.value = SYMBOL_VAL (sym); break; + case SYMBOL_LOCALIZED: + blv = SYMBOL_BLV (sym); + if (blv->frame_local) + error ("Symbol %s may not be buffer-local", + SDATA (SYMBOL_NAME (variable))); + break; + case SYMBOL_FORWARDED: + forwarded = 1; valcontents.fwd = SYMBOL_FWD (sym); + if (KBOARD_OBJFWDP (valcontents.fwd)) + error ("Symbol %s may not be buffer-local", + SDATA (SYMBOL_NAME (variable))); + break; + default: abort (); + } + + if (sym->constant) + error ("Symbol %s may not be buffer-local", SDATA (SYMBOL_NAME (variable))); + + if (blv ? blv->local_if_set + : (forwarded && BUFFER_OBJFWDP (valcontents.fwd))) { tem = Fboundp (variable); - /* Make sure the symbol has a local value in this particular buffer, by setting it to the same value it already has. */ Fset (variable, (EQ (tem, Qt) ? Fsymbol_value (variable) : Qunbound)); return variable; } - /* Make sure symbol is set up to hold per-buffer values. */ - if (!BUFFER_LOCAL_VALUEP (valcontents)) + if (!blv) { - Lisp_Object newval; - tem = Fcons (Qnil, do_symval_forwarding (valcontents)); - XSETCAR (tem, tem); - newval = allocate_misc (); - XMISCTYPE (newval) = Lisp_Misc_Buffer_Local_Value; - XBUFFER_LOCAL_VALUE (newval)->realvalue = sym->value; - XBUFFER_LOCAL_VALUE (newval)->buffer = Qnil; - XBUFFER_LOCAL_VALUE (newval)->frame = Qnil; - XBUFFER_LOCAL_VALUE (newval)->local_if_set = 0; - XBUFFER_LOCAL_VALUE (newval)->found_for_buffer = 0; - XBUFFER_LOCAL_VALUE (newval)->found_for_frame = 0; - XBUFFER_LOCAL_VALUE (newval)->check_frame = 0; - XBUFFER_LOCAL_VALUE (newval)->cdr = tem; - sym->value = newval; + blv = make_blv (sym, forwarded, valcontents); + sym->redirect = SYMBOL_LOCALIZED; + SET_SYMBOL_BLV (sym, blv); + { + Lisp_Object symbol; + XSETSYMBOL (symbol, sym); /* In case `variable' is aliased. */ + if (let_shadows_global_binding_p (symbol)) + error ("Making %s local to %s while let-bound!", + SDATA (SYMBOL_NAME (variable)), SDATA (current_buffer->name)); + } } + /* Make sure this buffer has its own value of symbol. */ - XSETSYMBOL (variable, sym); /* Propagate variable indirections. */ + XSETSYMBOL (variable, sym); /* Update in case of aliasing. */ tem = Fassq (variable, current_buffer->local_var_alist); if (NILP (tem)) { + if (let_shadows_buffer_binding_p (sym)) + message ("Making %s buffer-local while locally let-bound!", + SDATA (SYMBOL_NAME (variable))); + /* Swap out any local binding for some other buffer, and make sure the current value is permanently recorded, if it's the default value. */ find_symbol_value (variable); current_buffer->local_var_alist - = Fcons (Fcons (variable, XCDR (XBUFFER_LOCAL_VALUE (sym->value)->cdr)), + = Fcons (Fcons (variable, XCDR (blv->defcell)), current_buffer->local_var_alist); /* Make sure symbol does not think it is set up for this buffer; force it to look once again for this buffer's value. */ - { - Lisp_Object *pvalbuf; - - valcontents = sym->value; - - pvalbuf = &XBUFFER_LOCAL_VALUE (valcontents)->buffer; - if (current_buffer == XBUFFER (*pvalbuf)) - *pvalbuf = Qnil; - XBUFFER_LOCAL_VALUE (valcontents)->found_for_buffer = 0; - } + if (current_buffer == XBUFFER (blv->where)) + blv->where = Qnil; + /* blv->valcell = blv->defcell; + * SET_BLV_FOUND (blv, 0); */ + blv->found = 0; } /* If the symbol forwards into a C variable, then load the binding for this buffer now. If C code modifies the variable before we load the binding in, then that new value will clobber the default binding the next time we unload it. */ - valcontents = XBUFFER_LOCAL_VALUE (sym->value)->realvalue; - if (INTFWDP (valcontents) || BOOLFWDP (valcontents) || OBJFWDP (valcontents)) - swap_in_symval_forwarding (variable, sym->value); + if (blv->fwd) + swap_in_symval_forwarding (sym, blv); return variable; } @@ -1634,31 +1771,43 @@ (variable) register Lisp_Object variable; { - register Lisp_Object tem, valcontents; + register Lisp_Object tem; + struct Lisp_Buffer_Local_Value *blv; struct Lisp_Symbol *sym; CHECK_SYMBOL (variable); - sym = indirect_variable (XSYMBOL (variable)); - - valcontents = sym->value; - - if (BUFFER_OBJFWDP (valcontents)) + sym = XSYMBOL (variable); + + start: + switch (sym->redirect) { - int offset = XBUFFER_OBJFWD (valcontents)->offset; - int idx = PER_BUFFER_IDX (offset); - - if (idx > 0) - { - SET_PER_BUFFER_VALUE_P (current_buffer, idx, 0); - PER_BUFFER_VALUE (current_buffer, offset) - = PER_BUFFER_DEFAULT (offset); - } - return variable; + case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; + case SYMBOL_PLAINVAL: return variable; + case SYMBOL_FORWARDED: + { + union Lisp_Fwd *valcontents = SYMBOL_FWD (sym); + if (BUFFER_OBJFWDP (valcontents)) + { + int offset = XBUFFER_OBJFWD (valcontents)->offset; + int idx = PER_BUFFER_IDX (offset); + + if (idx > 0) + { + SET_PER_BUFFER_VALUE_P (current_buffer, idx, 0); + PER_BUFFER_VALUE (current_buffer, offset) + = PER_BUFFER_DEFAULT (offset); + } + } + return variable; + } + case SYMBOL_LOCALIZED: + blv = SYMBOL_BLV (sym); + if (blv->frame_local) + return variable; + break; + default: abort (); } - if (!BUFFER_LOCAL_VALUEP (valcontents)) - return variable; - /* Get rid of this buffer's alist element, if any. */ XSETSYMBOL (variable, sym); /* Propagate variable indirection. */ tem = Fassq (variable, current_buffer->local_var_alist); @@ -1670,14 +1819,13 @@ loaded, recompute its value. We have to do it now, or else forwarded objects won't work right. */ { - Lisp_Object *pvalbuf, buf; - valcontents = sym->value; - pvalbuf = &XBUFFER_LOCAL_VALUE (valcontents)->buffer; - XSETBUFFER (buf, current_buffer); - if (EQ (buf, *pvalbuf)) + Lisp_Object buf; XSETBUFFER (buf, current_buffer); + if (EQ (buf, blv->where)) { - *pvalbuf = Qnil; - XBUFFER_LOCAL_VALUE (valcontents)->found_for_buffer = 0; + blv->where = Qnil; + /* blv->valcell = blv->defcell; + * SET_BLV_FOUND (blv, 0); */ + blv->found = 0; find_symbol_value (variable); } } @@ -1712,39 +1860,45 @@ (variable) register Lisp_Object variable; { - register Lisp_Object tem, valcontents, newval; + int forwarded; + union Lisp_Val_Fwd valcontents; struct Lisp_Symbol *sym; + struct Lisp_Buffer_Local_Value *blv = NULL; CHECK_SYMBOL (variable); - sym = indirect_variable (XSYMBOL (variable)); - - valcontents = sym->value; - if (sym->constant || KBOARD_OBJFWDP (valcontents) - || BUFFER_OBJFWDP (valcontents)) - error ("Symbol %s may not be frame-local", SDATA (sym->xname)); - - if (BUFFER_LOCAL_VALUEP (valcontents)) + sym = XSYMBOL (variable); + + start: + switch (sym->redirect) { - if (!XBUFFER_LOCAL_VALUE (valcontents)->check_frame) - error ("Symbol %s may not be frame-local", SDATA (sym->xname)); - return variable; + case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; + case SYMBOL_PLAINVAL: + forwarded = 0; valcontents.value = SYMBOL_VAL (sym); + if (EQ (valcontents.value, Qunbound)) + valcontents.value = Qnil; + break; + case SYMBOL_LOCALIZED: + if (SYMBOL_BLV (sym)->frame_local) + return variable; + else + error ("Symbol %s may not be frame-local", + SDATA (SYMBOL_NAME (variable))); + case SYMBOL_FORWARDED: + forwarded = 1; valcontents.fwd = SYMBOL_FWD (sym); + if (KBOARD_OBJFWDP (valcontents.fwd) || BUFFER_OBJFWDP (valcontents.fwd)) + error ("Symbol %s may not be frame-local", + SDATA (SYMBOL_NAME (variable))); + break; + default: abort (); } - if (EQ (valcontents, Qunbound)) - sym->value = Qnil; - tem = Fcons (Qnil, Fsymbol_value (variable)); - XSETCAR (tem, tem); - newval = allocate_misc (); - XMISCTYPE (newval) = Lisp_Misc_Buffer_Local_Value; - XBUFFER_LOCAL_VALUE (newval)->realvalue = sym->value; - XBUFFER_LOCAL_VALUE (newval)->buffer = Qnil; - XBUFFER_LOCAL_VALUE (newval)->frame = Qnil; - XBUFFER_LOCAL_VALUE (newval)->local_if_set = 0; - XBUFFER_LOCAL_VALUE (newval)->found_for_buffer = 0; - XBUFFER_LOCAL_VALUE (newval)->found_for_frame = 0; - XBUFFER_LOCAL_VALUE (newval)->check_frame = 1; - XBUFFER_LOCAL_VALUE (newval)->cdr = tem; - sym->value = newval; + if (sym->constant) + error ("Symbol %s may not be frame-local", SDATA (SYMBOL_NAME (variable))); + + blv = make_blv (sym, forwarded, valcontents); + blv->frame_local = 1; + sym->redirect = SYMBOL_LOCALIZED; + SET_SYMBOL_BLV (sym, blv); return variable; } @@ -1755,7 +1909,6 @@ (variable, buffer) register Lisp_Object variable, buffer; { - Lisp_Object valcontents; register struct buffer *buf; struct Lisp_Symbol *sym; @@ -1768,29 +1921,46 @@ } CHECK_SYMBOL (variable); - sym = indirect_variable (XSYMBOL (variable)); - XSETSYMBOL (variable, sym); - - valcontents = sym->value; - if (BUFFER_LOCAL_VALUEP (valcontents)) + sym = XSYMBOL (variable); + + start: + switch (sym->redirect) { - Lisp_Object tail, elt; - - for (tail = buf->local_var_alist; CONSP (tail); tail = XCDR (tail)) - { - elt = XCAR (tail); - if (EQ (variable, XCAR (elt))) - return Qt; - } + case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; + case SYMBOL_PLAINVAL: return Qnil; + case SYMBOL_LOCALIZED: + { + Lisp_Object tail, elt, tmp; + struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym); + XSETBUFFER (tmp, buf); + + for (tail = buf->local_var_alist; CONSP (tail); tail = XCDR (tail)) + { + elt = XCAR (tail); + if (EQ (variable, XCAR (elt))) + { + eassert (!blv->frame_local); + eassert (BLV_FOUND (blv) || !EQ (blv->where, tmp)); + return Qt; + } + } + eassert (!BLV_FOUND (blv) || !EQ (blv->where, tmp)); + return Qnil; + } + case SYMBOL_FORWARDED: + { + union Lisp_Fwd *valcontents = SYMBOL_FWD (sym); + if (BUFFER_OBJFWDP (valcontents)) + { + int offset = XBUFFER_OBJFWD (valcontents)->offset; + int idx = PER_BUFFER_IDX (offset); + if (idx == -1 || PER_BUFFER_VALUE_P (buf, idx)) + return Qt; + } + return Qnil; + } + default: abort (); } - if (BUFFER_OBJFWDP (valcontents)) - { - int offset = XBUFFER_OBJFWD (valcontents)->offset; - int idx = PER_BUFFER_IDX (offset); - if (idx == -1 || PER_BUFFER_VALUE_P (buf, idx)) - return Qt; - } - return Qnil; } DEFUN ("local-variable-if-set-p", Flocal_variable_if_set_p, Slocal_variable_if_set_p, @@ -1804,40 +1974,29 @@ (variable, buffer) register Lisp_Object variable, buffer; { - Lisp_Object valcontents; - register struct buffer *buf; struct Lisp_Symbol *sym; - if (NILP (buffer)) - buf = current_buffer; - else - { - CHECK_BUFFER (buffer); - buf = XBUFFER (buffer); - } - CHECK_SYMBOL (variable); - sym = indirect_variable (XSYMBOL (variable)); - XSETSYMBOL (variable, sym); - - valcontents = sym->value; - - if (BUFFER_OBJFWDP (valcontents)) - /* All these slots become local if they are set. */ - return Qt; - else if (BUFFER_LOCAL_VALUEP (valcontents)) + sym = XSYMBOL (variable); + + start: + switch (sym->redirect) { - Lisp_Object tail, elt; - if (XBUFFER_LOCAL_VALUE (valcontents)->local_if_set) - return Qt; - for (tail = buf->local_var_alist; CONSP (tail); tail = XCDR (tail)) - { - elt = XCAR (tail); - if (EQ (variable, XCAR (elt))) - return Qt; - } + case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; + case SYMBOL_PLAINVAL: return Qnil; + case SYMBOL_LOCALIZED: + { + struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym); + if (blv->local_if_set) + return Qt; + XSETSYMBOL (variable, sym); /* Update in case of aliasing. */ + return Flocal_variable_p (variable, buffer); + } + case SYMBOL_FORWARDED: + /* All BUFFER_OBJFWD slots become local if they are set. */ + return (BUFFER_OBJFWDP (SYMBOL_FWD (sym)) ? Qt : Qnil); + default: abort (); } - return Qnil; } DEFUN ("variable-binding-locus", Fvariable_binding_locus, Svariable_binding_locus, @@ -1849,30 +2008,40 @@ (variable) register Lisp_Object variable; { - Lisp_Object valcontents; struct Lisp_Symbol *sym; CHECK_SYMBOL (variable); - sym = indirect_variable (XSYMBOL (variable)); + sym = XSYMBOL (variable); /* Make sure the current binding is actually swapped in. */ find_symbol_value (variable); - valcontents = sym->value; - - if (BUFFER_LOCAL_VALUEP (valcontents) - || BUFFER_OBJFWDP (valcontents)) + start: + switch (sym->redirect) { + case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; + case SYMBOL_PLAINVAL: return Qnil; + case SYMBOL_FORWARDED: + { + union Lisp_Fwd *valcontents = SYMBOL_FWD (sym); + if (KBOARD_OBJFWDP (valcontents)) + return Fframe_terminal (Fselected_frame ()); + else if (!BUFFER_OBJFWDP (valcontents)) + return Qnil; + } + /* FALLTHROUGH */ + case SYMBOL_LOCALIZED: /* For a local variable, record both the symbol and which buffer's or frame's value we are saving. */ if (!NILP (Flocal_variable_p (variable, Qnil))) return Fcurrent_buffer (); - else if (BUFFER_LOCAL_VALUEP (valcontents) - && XBUFFER_LOCAL_VALUE (valcontents)->found_for_frame) - return XBUFFER_LOCAL_VALUE (valcontents)->frame; + else if (sym->redirect == SYMBOL_LOCALIZED + && BLV_FOUND (SYMBOL_BLV (sym))) + return SYMBOL_BLV (sym)->where; + else + return Qnil; + default: abort (); } - - return Qnil; } /* This code is disabled now that we use the selected frame to return
--- a/src/dired.c Tue Apr 20 15:30:26 2010 +0900 +++ b/src/dired.c Tue Apr 20 16:26:02 2010 +0900 @@ -935,9 +935,9 @@ Value is nil if specified file cannot be opened. ID-FORMAT specifies the preferred format of attributes uid and gid (see -below) - valid values are 'string and 'integer. The latter is the default, -but we plan to change that, so you should specify a non-nil value for -ID-FORMAT if you use the returned uid or gid. +below) - valid values are 'string and 'integer. The latter is the +default, but we plan to change that, so you should specify a non-nil value +for ID-FORMAT if you use the returned uid or gid. Elements of the attribute list are: 0. t for directory, string (name linked to) for symbolic link, or nil.
--- a/src/dispextern.h Tue Apr 20 15:30:26 2010 +0900 +++ b/src/dispextern.h Tue Apr 20 16:26:02 2010 +0900 @@ -2222,13 +2222,22 @@ MODE_LINE_FACE_ID, etc, depending on what we are displaying. */ int base_face_id; - /* If what == IT_CHARACTER, character and length in bytes. This is - a character from a buffer or string. It may be different from - the character displayed in case that - unibyte_display_via_language_environment is set. - - If what == IT_COMPOSITION, the first component of a composition - and length in bytes of the composition. */ + /* If `what' == IT_CHARACTER, the character and the length in bytes + of its multibyte sequence. The character comes from a buffer or + a string. It may be different from the character displayed in + case that unibyte_display_via_language_environment is set. + + If `what' == IT_COMPOSITION, the first component of a composition + and length in bytes of the composition. + + If `what' is anything else, these tow are undefined (will + probably hold values for the last IT_CHARACTER or IT_COMPOSITION + traversed by the iterator. + + The values are updated by get_next_display_element, so they are + out of sync with the value returned by IT_CHARPOS between the + time set_iterator_to_next advances the position and the time + get_next_display_element loads the new values into c and len. */ int c, len; /* If what == IT_COMPOSITION, iterator substructure for the
--- a/src/eval.c Tue Apr 20 15:30:26 2010 +0900 +++ b/src/eval.c Tue Apr 20 16:26:02 2010 +0900 @@ -767,24 +767,46 @@ CHECK_SYMBOL (new_alias); CHECK_SYMBOL (base_variable); - if (SYMBOL_CONSTANT_P (new_alias)) - error ("Cannot make a constant an alias"); - sym = XSYMBOL (new_alias); + + if (sym->constant) + if (sym->redirect == SYMBOL_VARALIAS) + sym->constant = 0; /* Reset. */ + else + /* Not sure why. */ + error ("Cannot make a constant an alias"); + + switch (sym->redirect) + { + case SYMBOL_FORWARDED: + error ("Cannot make an internal variable an alias"); + case SYMBOL_LOCALIZED: + error ("Don't know how to make a localized variable an alias"); + } + /* http://lists.gnu.org/archive/html/emacs-devel/2008-04/msg00834.html - If n_a is bound, but b_v is not, set the value of b_v to n_a. - This is for the sake of define-obsolete-variable-alias and user - customizations. */ - if (NILP (Fboundp (base_variable)) && !NILP (Fboundp (new_alias))) - XSYMBOL(base_variable)->value = sym->value; - sym->indirect_variable = 1; - sym->value = base_variable; + If n_a is bound, but b_v is not, set the value of b_v to n_a, + so that old-code that affects n_a before the aliasing is setup + still works. */ + if (NILP (Fboundp (base_variable))) + set_internal (base_variable, find_symbol_value (new_alias), NULL, 1); + + { + struct specbinding *p; + + for (p = specpdl_ptr - 1; p >= specpdl; p--) + if (p->func == NULL + && (EQ (new_alias, + CONSP (p->symbol) ? XCAR (p->symbol) : p->symbol))) + error ("Don't know how to make a let-bound variable an alias"); + } + + sym->redirect = SYMBOL_VARALIAS; + SET_SYMBOL_ALIAS (sym, XSYMBOL (base_variable)); sym->constant = SYMBOL_CONSTANT_P (base_variable); LOADHIST_ATTACH (new_alias); - if (!NILP (docstring)) - Fput (new_alias, Qvariable_documentation, docstring); - else - Fput (new_alias, Qvariable_documentation, Qnil); + /* Even if docstring is nil: remove old docstring. */ + Fput (new_alias, Qvariable_documentation, docstring); return base_variable; } @@ -944,7 +966,7 @@ return Qnil; /* If indirect and there's an alias loop, don't check anything else. */ - if (XSYMBOL (variable)->indirect_variable + if (XSYMBOL (variable)->redirect == SYMBOL_VARALIAS && NILP (internal_condition_case_1 (lisp_indirect_variable, variable, Qt, user_variable_p_eh))) return Qnil; @@ -968,11 +990,11 @@ || (!NILP (Fget (variable, intern ("custom-autoload"))))) return Qt; - if (!XSYMBOL (variable)->indirect_variable) + if (!(XSYMBOL (variable)->redirect == SYMBOL_VARALIAS)) return Qnil; /* An indirect variable? Let's follow the chain. */ - variable = XSYMBOL (variable)->value; + XSETSYMBOL (variable, SYMBOL_ALIAS (XSYMBOL (variable))); } } @@ -3263,78 +3285,94 @@ specbind (symbol, value) Lisp_Object symbol, value; { - Lisp_Object valcontents; + struct Lisp_Symbol *sym; + + eassert (!handling_signal); CHECK_SYMBOL (symbol); + sym = XSYMBOL (symbol); if (specpdl_ptr == specpdl + specpdl_size) grow_specpdl (); - /* The most common case is that of a non-constant symbol with a - trivial value. Make that as fast as we can. */ - valcontents = SYMBOL_VALUE (symbol); - if (!MISCP (valcontents) && !SYMBOL_CONSTANT_P (symbol)) - { - specpdl_ptr->symbol = symbol; - specpdl_ptr->old_value = valcontents; - specpdl_ptr->func = NULL; - ++specpdl_ptr; - SET_SYMBOL_VALUE (symbol, value); - } - else + start: + switch (sym->redirect) { - Lisp_Object ovalue = find_symbol_value (symbol); - specpdl_ptr->func = 0; - specpdl_ptr->old_value = ovalue; - - valcontents = XSYMBOL (symbol)->value; - - if (BUFFER_LOCAL_VALUEP (valcontents) - || BUFFER_OBJFWDP (valcontents)) - { - Lisp_Object where, current_buffer; - - current_buffer = Fcurrent_buffer (); - - /* For a local variable, record both the symbol and which - buffer's or frame's value we are saving. */ - if (!NILP (Flocal_variable_p (symbol, Qnil))) - where = current_buffer; - else if (BUFFER_LOCAL_VALUEP (valcontents) - && XBUFFER_LOCAL_VALUE (valcontents)->found_for_frame) - where = XBUFFER_LOCAL_VALUE (valcontents)->frame; + case SYMBOL_VARALIAS: + sym = indirect_variable (sym); XSETSYMBOL (symbol, sym); goto start; + case SYMBOL_PLAINVAL: + { /* The most common case is that of a non-constant symbol with a + trivial value. Make that as fast as we can. */ + specpdl_ptr->symbol = symbol; + specpdl_ptr->old_value = SYMBOL_VAL (sym); + specpdl_ptr->func = NULL; + ++specpdl_ptr; + if (!sym->constant) + SET_SYMBOL_VAL (sym, value); else - where = Qnil; - - /* We're not using the `unused' slot in the specbinding - structure because this would mean we have to do more - work for simple variables. */ - specpdl_ptr->symbol = Fcons (symbol, Fcons (where, current_buffer)); - - /* If SYMBOL is a per-buffer variable which doesn't have a - buffer-local value here, make the `let' change the global - value by changing the value of SYMBOL in all buffers not - having their own value. This is consistent with what - happens with other buffer-local variables. */ - if (NILP (where) - && BUFFER_OBJFWDP (valcontents)) - { - ++specpdl_ptr; - Fset_default (symbol, value); - return; - } + set_internal (symbol, value, 0, 1); + break; } - else - specpdl_ptr->symbol = symbol; - - specpdl_ptr++; - /* We used to do - if (BUFFER_OBJFWDP (ovalue) || KBOARD_OBJFWDP (ovalue)) - store_symval_forwarding (symbol, ovalue, value, NULL); - else - but ovalue comes from find_symbol_value which should never return - such an internal value. */ - eassert (!(BUFFER_OBJFWDP (ovalue) || KBOARD_OBJFWDP (ovalue))); - set_internal (symbol, value, 0, 1); + case SYMBOL_LOCALIZED: case SYMBOL_FORWARDED: + { + Lisp_Object ovalue = find_symbol_value (symbol); + specpdl_ptr->func = 0; + specpdl_ptr->old_value = ovalue; + + eassert (sym->redirect != SYMBOL_LOCALIZED + || (EQ (SYMBOL_BLV (sym)->where, + SYMBOL_BLV (sym)->frame_local ? + Fselected_frame () : Fcurrent_buffer ()))); + + if (sym->redirect == SYMBOL_LOCALIZED + || BUFFER_OBJFWDP (SYMBOL_FWD (sym))) + { + Lisp_Object where, cur_buf = Fcurrent_buffer (); + + /* For a local variable, record both the symbol and which + buffer's or frame's value we are saving. */ + if (!NILP (Flocal_variable_p (symbol, Qnil))) + { + eassert (sym->redirect != SYMBOL_LOCALIZED + || (BLV_FOUND (SYMBOL_BLV (sym)) + && EQ (cur_buf, SYMBOL_BLV (sym)->where))); + where = cur_buf; + } + else if (sym->redirect == SYMBOL_LOCALIZED + && BLV_FOUND (SYMBOL_BLV (sym))) + where = SYMBOL_BLV (sym)->where; + else + where = Qnil; + + /* We're not using the `unused' slot in the specbinding + structure because this would mean we have to do more + work for simple variables. */ + /* FIXME: The third value `current_buffer' is only used in + let_shadows_buffer_binding_p which is itself only used + in set_internal for local_if_set. */ + specpdl_ptr->symbol = Fcons (symbol, Fcons (where, cur_buf)); + + /* If SYMBOL is a per-buffer variable which doesn't have a + buffer-local value here, make the `let' change the global + value by changing the value of SYMBOL in all buffers not + having their own value. This is consistent with what + happens with other buffer-local variables. */ + if (NILP (where) + && sym->redirect == SYMBOL_FORWARDED) + { + eassert (BUFFER_OBJFWDP (SYMBOL_FWD (sym))); + ++specpdl_ptr; + Fset_default (symbol, value); + return; + } + } + else + specpdl_ptr->symbol = symbol; + + specpdl_ptr++; + set_internal (symbol, value, 0, 1); + break; + } + default: abort (); } } @@ -3394,7 +3432,12 @@ if (NILP (where)) Fset_default (symbol, this_binding.old_value); else if (BUFFERP (where)) - set_internal (symbol, this_binding.old_value, XBUFFER (where), 1); + if (!NILP (Flocal_variable_p (symbol, where))) + set_internal (symbol, this_binding.old_value, XBUFFER (where), 1); + /* else if (!NILP (Fbuffer_live_p (where))) + error ("Unbinding local %s to global!", symbol); */ + else + ; else set_internal (symbol, this_binding.old_value, NULL, 1); } @@ -3403,8 +3446,9 @@ /* 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 (!MISCP (SYMBOL_VALUE (this_binding.symbol))) - SET_SYMBOL_VALUE (this_binding.symbol, this_binding.old_value); + if (XSYMBOL (this_binding.symbol)->redirect == SYMBOL_PLAINVAL) + SET_SYMBOL_VAL (XSYMBOL (this_binding.symbol), + this_binding.old_value); else set_internal (this_binding.symbol, this_binding.old_value, 0, 1); }
--- a/src/frame.c Tue Apr 20 15:30:26 2010 +0900 +++ b/src/frame.c Tue Apr 20 16:26:02 2010 +0900 @@ -2298,13 +2298,20 @@ without messing up the symbol's status. */ if (SYMBOLP (prop)) { - Lisp_Object valcontents; - valcontents = SYMBOL_VALUE (prop); - if ((BUFFER_LOCAL_VALUEP (valcontents)) - && XBUFFER_LOCAL_VALUE (valcontents)->check_frame - && XBUFFER_LOCAL_VALUE (valcontents)->found_for_frame - && XFRAME (XBUFFER_LOCAL_VALUE (valcontents)->frame) == f) - swap_in_global_binding (prop); + struct Lisp_Symbol *sym = XSYMBOL (prop); + start: + switch (sym->redirect) + { + case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; + case SYMBOL_PLAINVAL: case SYMBOL_FORWARDED: break; + case SYMBOL_LOCALIZED: + { struct Lisp_Buffer_Local_Value *blv = sym->val.blv; + if (blv->frame_local && BLV_FOUND (blv) && XFRAME (blv->where) == f) + swap_in_global_binding (sym); + break; + } + default: abort (); + } } /* The tty color needed to be set before the frame's parameter @@ -2520,6 +2527,8 @@ || EQ (parameter, Qbackground_mode)) value = Fcdr (Fassq (parameter, f->param_alist)); else + /* FIXME: Avoid this code path at all (as well as code duplication) + by sharing more code with Fframe_parameters. */ value = Fcdr (Fassq (parameter, Fframe_parameters (frame))); }
--- a/src/frame.h Tue Apr 20 15:30:26 2010 +0900 +++ b/src/frame.h Tue Apr 20 16:26:02 2010 +0900 @@ -980,7 +980,7 @@ at ROW/COL. */ #define FRAME_LINE_TO_PIXEL_Y(f, row) \ - ((row < FRAME_TOP_MARGIN (f) ? 0 : FRAME_INTERNAL_BORDER_WIDTH (f)) \ + (((row) < FRAME_TOP_MARGIN (f) ? 0 : FRAME_INTERNAL_BORDER_WIDTH (f)) \ + (row) * FRAME_LINE_HEIGHT (f)) #define FRAME_COL_TO_PIXEL_X(f, col) \
--- a/src/insdel.c Tue Apr 20 15:30:26 2010 +0900 +++ b/src/insdel.c Tue Apr 20 16:26:02 2010 +0900 @@ -54,7 +54,7 @@ Lisp_Object Fcombine_after_change_execute (); /* Non-nil means don't call the after-change-functions right away, - just record an element in Vcombine_after_change_calls_list. */ + just record an element in combine_after_change_list. */ Lisp_Object Vcombine_after_change_calls; /* List of elements of the form (BEG-UNCHANGED END-UNCHANGED CHANGE-AMOUNT)
--- a/src/keyboard.c Tue Apr 20 15:30:26 2010 +0900 +++ b/src/keyboard.c Tue Apr 20 16:26:02 2010 +0900 @@ -1520,7 +1520,6 @@ command_loop_1 () { Lisp_Object cmd; - int lose; Lisp_Object keybuf[30]; int i; int prev_modiff = 0;
--- a/src/lisp.h Tue Apr 20 15:30:26 2010 +0900 +++ b/src/lisp.h Tue Apr 20 16:26:02 2010 +0900 @@ -223,13 +223,7 @@ { Lisp_Misc_Free = 0x5eab, Lisp_Misc_Marker, - Lisp_Misc_Intfwd, - Lisp_Misc_Boolfwd, - Lisp_Misc_Objfwd, - Lisp_Misc_Buffer_Objfwd, - Lisp_Misc_Buffer_Local_Value, Lisp_Misc_Overlay, - Lisp_Misc_Kboard_Objfwd, Lisp_Misc_Save_Value, /* Currently floats are not a misc type, but let's define this in case we want to change that. */ @@ -238,6 +232,18 @@ Lisp_Misc_Limit }; +/* These are the types of forwarding objects used in the value slot + of symbols for special built-in variables whose value is stored in + C variables. */ +enum Lisp_Fwd_Type + { + Lisp_Fwd_Int, /* Fwd to a C `int' variable. */ + Lisp_Fwd_Bool, /* Fwd to a C boolean var. */ + Lisp_Fwd_Obj, /* Fwd to a C Lisp_Object variable. */ + Lisp_Fwd_Buffer_Obj, /* Fwd to a Lisp_Object field of buffers. */ + Lisp_Fwd_Kboard_Obj, /* Fwd to a Lisp_Object field of kboards. */ + }; + #ifndef GCTYPEBITS #define GCTYPEBITS 3 #endif @@ -566,17 +572,19 @@ #define XMISCANY(a) (eassert (MISCP (a)), &(XMISC(a)->u_any)) #define XMISCTYPE(a) (XMISCANY (a)->type) #define XMARKER(a) (eassert (MARKERP (a)), &(XMISC(a)->u_marker)) -#define XINTFWD(a) (eassert (INTFWDP (a)), &(XMISC(a)->u_intfwd)) -#define XBOOLFWD(a) (eassert (BOOLFWDP (a)), &(XMISC(a)->u_boolfwd)) -#define XOBJFWD(a) (eassert (OBJFWDP (a)), &(XMISC(a)->u_objfwd)) #define XOVERLAY(a) (eassert (OVERLAYP (a)), &(XMISC(a)->u_overlay)) #define XSAVE_VALUE(a) (eassert (SAVE_VALUEP (a)), &(XMISC(a)->u_save_value)) + +/* Forwarding object types. */ + +#define XFWDTYPE(a) (a->u_intfwd.type) +#define XINTFWD(a) (eassert (INTFWDP (a)), &((a)->u_intfwd)) +#define XBOOLFWD(a) (eassert (BOOLFWDP (a)), &((a)->u_boolfwd)) +#define XOBJFWD(a) (eassert (OBJFWDP (a)), &((a)->u_objfwd)) #define XBUFFER_OBJFWD(a) \ - (eassert (BUFFER_OBJFWDP (a)), &(XMISC(a)->u_buffer_objfwd)) -#define XBUFFER_LOCAL_VALUE(a) \ - (eassert (BUFFER_LOCAL_VALUEP (a)), &(XMISC(a)->u_buffer_local_value)) + (eassert (BUFFER_OBJFWDP (a)), &((a)->u_buffer_objfwd)) #define XKBOARD_OBJFWD(a) \ - (eassert (KBOARD_OBJFWDP (a)), &(XMISC(a)->u_kboard_objfwd)) + (eassert (KBOARD_OBJFWDP (a)), &((a)->u_kboard_objfwd)) /* Pseudovector types. */ @@ -988,19 +996,32 @@ SYMBOL_INTERNED_IN_INITIAL_OBARRAY = 2 }; +enum symbol_redirect +{ + SYMBOL_PLAINVAL = 4, + SYMBOL_VARALIAS = 1, + SYMBOL_LOCALIZED = 2, + SYMBOL_FORWARDED = 3 +}; + /* In a symbol, the markbit of the plist is used as the gc mark bit */ struct Lisp_Symbol { unsigned gcmarkbit : 1; - /* Non-zero means symbol serves as a variable alias. The symbol - holding the real value is found in the value slot. */ - unsigned indirect_variable : 1; + /* Indicates where the value can be found: + 0 : it's a plain var, the value is in the `value' field. + 1 : it's a varalias, the value is really in the `alias' symbol. + 2 : it's a localized var, the value is in the `blv' object. + 3 : it's a forwarding variable, the value is in `forward'. + */ + enum symbol_redirect redirect : 3; /* Non-zero means symbol is constant, i.e. changing its value - should signal an error. */ - unsigned constant : 1; + should signal an error. If the value is 3, then the var + can be changed, but only by `defconst'. */ + unsigned constant : 2; /* Interned state of the symbol. This is an enumerator from enum symbol_interned. */ @@ -1013,10 +1034,15 @@ Lisp_Object xname; /* Value of the symbol or Qunbound if unbound. If this symbol is a - defvaralias, `value' contains the symbol for which it is an + defvaralias, `alias' contains the symbol for which it is an alias. Use the SYMBOL_VALUE and SET_SYMBOL_VALUE macros to get and set a symbol's value, to take defvaralias into account. */ - Lisp_Object value; + union { + Lisp_Object value; + struct Lisp_Symbol *alias; + struct Lisp_Buffer_Local_Value *blv; + union Lisp_Fwd *fwd; + } val; /* Function value of the symbol or Qunbound if not fboundp. */ Lisp_Object function; @@ -1030,6 +1056,23 @@ /* Value is name of symbol. */ +#define SYMBOL_VAL(sym) \ + (eassert ((sym)->redirect == SYMBOL_PLAINVAL), (sym)->val.value) +#define SYMBOL_ALIAS(sym) \ + (eassert ((sym)->redirect == SYMBOL_VARALIAS), (sym)->val.alias) +#define SYMBOL_BLV(sym) \ + (eassert ((sym)->redirect == SYMBOL_LOCALIZED), (sym)->val.blv) +#define SYMBOL_FWD(sym) \ + (eassert ((sym)->redirect == SYMBOL_FORWARDED), (sym)->val.fwd) +#define SET_SYMBOL_VAL(sym, v) \ + (eassert ((sym)->redirect == SYMBOL_PLAINVAL), (sym)->val.value = (v)) +#define SET_SYMBOL_ALIAS(sym, v) \ + (eassert ((sym)->redirect == SYMBOL_VARALIAS), (sym)->val.alias = (v)) +#define SET_SYMBOL_BLV(sym, v) \ + (eassert ((sym)->redirect == SYMBOL_LOCALIZED), (sym)->val.blv = (v)) +#define SET_SYMBOL_FWD(sym, v) \ + (eassert ((sym)->redirect == SYMBOL_FORWARDED), (sym)->val.fwd = (v)) + #define SYMBOL_NAME(sym) \ LISP_MAKE_RVALUE (XSYMBOL (sym)->xname) @@ -1049,24 +1092,6 @@ #define SYMBOL_CONSTANT_P(sym) XSYMBOL (sym)->constant -/* Value is the value of SYM, with defvaralias taken into - account. */ - -#define SYMBOL_VALUE(sym) \ - (XSYMBOL (sym)->indirect_variable \ - ? indirect_variable (XSYMBOL (sym))->value \ - : XSYMBOL (sym)->value) - -/* Set SYM's value to VAL, taking defvaralias into account. */ - -#define SET_SYMBOL_VALUE(sym, val) \ - do { \ - if (XSYMBOL (sym)->indirect_variable) \ - indirect_variable (XSYMBOL (sym))->value = (val); \ - else \ - XSYMBOL (sym)->value = (val); \ - } while (0) - /*********************************************************************** Hash Tables @@ -1200,9 +1225,11 @@ struct Lisp_Misc_Any /* Supertype of all Misc types. */ { - enum Lisp_Misc_Type type : 16; /* = Lisp_Misc_Marker */ + enum Lisp_Misc_Type type : 16; /* = Lisp_Misc_??? */ unsigned gcmarkbit : 1; int spacer : 15; + /* Make it as long as "Lisp_Free without padding". */ + void *fill; }; struct Lisp_Marker @@ -1225,7 +1252,7 @@ - Fmarker_buffer - Fset_marker: check eq(oldbuf, newbuf) to avoid unchain+rechain. - unchain_marker: to find the list from which to unchain. - - Fkill_buffer: to unchain the markers of current indirect buffer. + - Fkill_buffer: to only unchain the markers of current indirect buffer. */ struct buffer *buffer; @@ -1239,7 +1266,10 @@ struct Lisp_Marker *next; /* This is the char position where the marker points. */ EMACS_INT charpos; - /* This is the byte position. */ + /* This is the byte position. + It's mostly used as a charpos<->bytepos cache (i.e. it's not directly + used to implement the functionality of markers, but rather to (ab)use + markers as a cache for char<->byte mappings). */ EMACS_INT bytepos; }; @@ -1249,9 +1279,7 @@ specified int variable. */ struct Lisp_Intfwd { - int type : 16; /* = Lisp_Misc_Intfwd */ - unsigned gcmarkbit : 1; - int spacer : 15; + enum Lisp_Fwd_Type type; /* = Lisp_Fwd_Int */ EMACS_INT *intvar; }; @@ -1261,9 +1289,7 @@ nil if it is zero. */ struct Lisp_Boolfwd { - int type : 16; /* = Lisp_Misc_Boolfwd */ - unsigned gcmarkbit : 1; - int spacer : 15; + enum Lisp_Fwd_Type type; /* = Lisp_Fwd_Bool */ int *boolvar; }; @@ -1273,9 +1299,7 @@ specified variable. */ struct Lisp_Objfwd { - int type : 16; /* = Lisp_Misc_Objfwd */ - unsigned gcmarkbit : 1; - int spacer : 15; + enum Lisp_Fwd_Type type; /* = Lisp_Fwd_Obj */ Lisp_Object *objvar; }; @@ -1283,11 +1307,9 @@ current buffer. Value is byte index of slot within buffer. */ struct Lisp_Buffer_Objfwd { - int type : 16; /* = Lisp_Misc_Buffer_Objfwd */ - unsigned gcmarkbit : 1; - int spacer : 15; + enum Lisp_Fwd_Type type; /* = Lisp_Fwd_Buffer_Obj */ + int offset; Lisp_Object slottype; /* Qnil, Lisp_Int, Lisp_Symbol, or Lisp_String. */ - int offset; }; /* struct Lisp_Buffer_Local_Value is used in a symbol value cell when @@ -1316,48 +1338,51 @@ struct Lisp_Buffer_Local_Value { - int type : 16; /* = Lisp_Misc_Buffer_Local_Value */ - unsigned gcmarkbit : 1; - int spacer : 11; - /* 1 means that merely setting the variable creates a local binding for the current buffer */ unsigned int local_if_set : 1; - /* 1 means this variable is allowed to have frame-local bindings, - so check for them when looking for the proper binding. */ - unsigned int check_frame : 1; - /* 1 means that the binding now loaded was found - as a local binding for the buffer in the `buffer' slot. */ - unsigned int found_for_buffer : 1; - /* 1 means that the binding now loaded was found - as a local binding for the frame in the `frame' slot. */ - unsigned int found_for_frame : 1; - Lisp_Object realvalue; - /* The buffer and frame for which the loaded binding was found. */ - /* Having both is only needed if we want to allow variables that are - both buffer local and frame local (in which case, we currently give - precedence to the buffer-local binding). I don't think such - a combination is desirable. --Stef */ - Lisp_Object buffer, frame; - - /* A cons cell, (LOADED-BINDING . DEFAULT-VALUE). - - LOADED-BINDING is the binding now loaded. It is a cons cell - whose cdr is the binding's value. The cons cell may be an - element of a buffer's local-variable alist, or an element of a - frame's parameter alist, or it may be this cons cell. - - DEFAULT-VALUE is the variable's default value, seen when the - current buffer and selected frame do not have their own - bindings for the variable. When the default binding is loaded, - LOADED-BINDING is actually this very cons cell; thus, its car - points to itself. */ - Lisp_Object cdr; + /* 1 means this variable can have frame-local bindings, otherwise, it is + can have buffer-local bindings. The two cannot be combined. */ + unsigned int frame_local : 1; + /* 1 means that the binding now loaded was found. + Presumably equivalent to (defcell!=valcell) */ + unsigned int found : 1; + /* If non-NULL, a forwarding to the C var where it should also be set. */ + union Lisp_Fwd *fwd; /* Should never be (Buffer|Kboard)_Objfwd. */ + /* The buffer or frame for which the loaded binding was found. */ + Lisp_Object where; + /* A cons cell that holds the default value. It has the form + (SYMBOL . DEFAULT-VALUE). */ + Lisp_Object defcell; + /* The cons cell from `where's parameter alist. + It always has the form (SYMBOL . VALUE) + Note that if `forward' is non-nil, VALUE may be out of date. + Also if the currently loaded binding is the default binding, then + this is `eq'ual to defcell. */ + Lisp_Object valcell; }; +#define BLV_FOUND(blv) \ + (eassert ((blv)->found == !EQ ((blv)->defcell, (blv)->valcell)), (blv)->found) +#define SET_BLV_FOUND(blv, v) \ + (eassert ((v) == !EQ ((blv)->defcell, (blv)->valcell)), (blv)->found = (v)) + +#define BLV_VALUE(blv) (XCDR ((blv)->valcell)) +#define SET_BLV_VALUE(blv, v) (XSETCDR ((blv)->valcell, v)) + /* START and END are markers in the overlay's buffer, and PLIST is the overlay's property list. */ struct Lisp_Overlay +/* An overlay's real data content is: + - plist + - buffer + - insertion type of both ends + - start & start_byte + - end & end_byte + - next (singly linked list of overlays). + - start_next and end_next (singly linked list of markers). + I.e. 9words plus 2 bits, 3words of which are for external linked lists. +*/ { enum Lisp_Misc_Type type : 16; /* = Lisp_Misc_Overlay */ unsigned gcmarkbit : 1; @@ -1370,9 +1395,7 @@ current kboard. */ struct Lisp_Kboard_Objfwd { - enum Lisp_Misc_Type type : 16; /* = Lisp_Misc_Kboard_Objfwd */ - unsigned gcmarkbit : 1; - int spacer : 15; + enum Lisp_Fwd_Type type; /* = Lisp_Fwd_Kboard_Obj */ int offset; }; @@ -1401,9 +1424,9 @@ #ifdef USE_LSB_TAG /* Try to make sure that sizeof(Lisp_Misc) preserves TYPEBITS-alignment. This assumes that Lisp_Marker is the largest of the alternatives and - that Lisp_Intfwd has the same size as "Lisp_Free w/o padding". */ + that Lisp_Misc_Any has the same size as "Lisp_Free w/o padding". */ char padding[((((sizeof (struct Lisp_Marker) - 1) >> GCTYPEBITS) + 1) - << GCTYPEBITS) - sizeof (struct Lisp_Intfwd)]; + << GCTYPEBITS) - sizeof (struct Lisp_Misc_Any)]; #endif }; @@ -1414,15 +1437,18 @@ { struct Lisp_Misc_Any u_any; /* Supertype of all Misc types. */ struct Lisp_Free u_free; /* Includes padding to force alignment. */ - struct Lisp_Marker u_marker; - struct Lisp_Intfwd u_intfwd; - struct Lisp_Boolfwd u_boolfwd; - struct Lisp_Objfwd u_objfwd; - struct Lisp_Buffer_Objfwd u_buffer_objfwd; - struct Lisp_Buffer_Local_Value u_buffer_local_value; - struct Lisp_Overlay u_overlay; - struct Lisp_Kboard_Objfwd u_kboard_objfwd; - struct Lisp_Save_Value u_save_value; + struct Lisp_Marker u_marker; /* 5 */ + struct Lisp_Overlay u_overlay; /* 5 */ + struct Lisp_Save_Value u_save_value; /* 3 */ + }; + +union Lisp_Fwd + { + struct Lisp_Intfwd u_intfwd; /* 2 */ + struct Lisp_Boolfwd u_boolfwd; /* 2 */ + struct Lisp_Objfwd u_objfwd; /* 2 */ + struct Lisp_Buffer_Objfwd u_buffer_objfwd; /* 2 */ + struct Lisp_Kboard_Objfwd u_kboard_objfwd; /* 2 */ }; /* Lisp floating point type */ @@ -1564,15 +1590,13 @@ #define VECTORP(x) (VECTORLIKEP (x) && !(XVECTOR (x)->size & PSEUDOVECTOR_FLAG)) #define OVERLAYP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Overlay) #define MARKERP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Marker) -#define INTFWDP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Intfwd) -#define BOOLFWDP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Boolfwd) -#define OBJFWDP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Objfwd) -#define BUFFER_OBJFWDP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Buffer_Objfwd) -#define BUFFER_LOCAL_VALUEP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Buffer_Local_Value) -#define SOME_BUFFER_LOCAL_VALUEP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Some_Buffer_Local_Value) -#define KBOARD_OBJFWDP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Kboard_Objfwd) #define SAVE_VALUEP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Save_Value) +#define INTFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Int) +#define BOOLFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Bool) +#define OBJFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Obj) +#define BUFFER_OBJFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Buffer_Obj) +#define KBOARD_OBJFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Kboard_Obj) /* True if object X is a pseudovector whose code is CODE. */ #define PSEUDOVECTORP(x, code) \ @@ -1789,24 +1813,44 @@ #define MANY -2 #define UNEVALLED -1 -extern void defvar_lisp (const char *, Lisp_Object *); -extern void defvar_lisp_nopro (const char *, Lisp_Object *); -extern void defvar_bool (const char *, int *); -extern void defvar_int (const char *, EMACS_INT *); -extern void defvar_kboard (const char *, int); +extern void defvar_lisp (struct Lisp_Objfwd *, const char *, Lisp_Object *); +extern void defvar_lisp_nopro (struct Lisp_Objfwd *, const char *, Lisp_Object *); +extern void defvar_bool (struct Lisp_Boolfwd *, const char *, int *); +extern void defvar_int (struct Lisp_Intfwd *, const char *, EMACS_INT *); +extern void defvar_kboard (struct Lisp_Kboard_Objfwd *, const char *, int); /* Macros we use to define forwarded Lisp variables. These are used in the syms_of_FILENAME functions. */ -#define DEFVAR_LISP(lname, vname, doc) defvar_lisp (lname, vname) -#define DEFVAR_LISP_NOPRO(lname, vname, doc) defvar_lisp_nopro (lname, vname) -#define DEFVAR_BOOL(lname, vname, doc) defvar_bool (lname, vname) -#define DEFVAR_INT(lname, vname, doc) defvar_int (lname, vname) - -#define DEFVAR_KBOARD(lname, vname, doc) \ - defvar_kboard (lname, \ - (int)((char *)(¤t_kboard->vname) \ - - (char *)current_kboard)) +#define DEFVAR_LISP(lname, vname, doc) \ + do { \ + static struct Lisp_Objfwd o_fwd; \ + defvar_lisp (&o_fwd, lname, vname); \ + } while (0) +#define DEFVAR_LISP_NOPRO(lname, vname, doc) \ + do { \ + static struct Lisp_Objfwd o_fwd; \ + defvar_lisp_nopro (&o_fwd, lname, vname); \ + } while (0) +#define DEFVAR_BOOL(lname, vname, doc) \ + do { \ + static struct Lisp_Boolfwd b_fwd; \ + defvar_bool (&b_fwd, lname, vname); \ + } while (0) +#define DEFVAR_INT(lname, vname, doc) \ + do { \ + static struct Lisp_Intfwd i_fwd; \ + defvar_int (&i_fwd, lname, vname); \ + } while (0) + +#define DEFVAR_KBOARD(lname, vname, doc) \ + do { \ + static struct Lisp_Kboard_Objfwd ko_fwd; \ + defvar_kboard (&ko_fwd, \ + lname, \ + (int)((char *)(¤t_kboard->vname) \ + - (char *)current_kboard)); \ + } while (0) @@ -2341,13 +2385,11 @@ extern void args_out_of_range_3 P_ ((Lisp_Object, Lisp_Object, Lisp_Object)) NO_RETURN; extern Lisp_Object wrong_type_argument P_ ((Lisp_Object, Lisp_Object)) NO_RETURN; -extern void store_symval_forwarding P_ ((Lisp_Object, Lisp_Object, - Lisp_Object, struct buffer *)); -extern Lisp_Object do_symval_forwarding P_ ((Lisp_Object)); -extern Lisp_Object set_internal P_ ((Lisp_Object, Lisp_Object, struct buffer *, int)); +extern Lisp_Object do_symval_forwarding (union Lisp_Fwd *); +extern void set_internal (Lisp_Object, Lisp_Object, struct buffer *, int); extern void syms_of_data P_ ((void)); extern void init_data P_ ((void)); -extern void swap_in_global_binding P_ ((Lisp_Object)); +extern void swap_in_global_binding P_ ((struct Lisp_Symbol *)); /* Defined in cmds.c */ EXFUN (Fend_of_line, 1); @@ -3388,6 +3430,7 @@ extern void fatal P_ ((const char *msgid, ...)) NO_RETURN; /* Defined in terminal.c */ +EXFUN (Fframe_terminal, 1); EXFUN (Fdelete_terminal, 2); extern void syms_of_terminal P_ ((void));
--- a/src/lread.c Tue Apr 20 15:30:26 2010 +0900 +++ b/src/lread.c Tue Apr 20 16:26:02 2010 +0900 @@ -3687,7 +3687,8 @@ && EQ (obarray, initial_obarray)) { XSYMBOL (sym)->constant = 1; - XSYMBOL (sym)->value = sym; + XSYMBOL (sym)->redirect = SYMBOL_PLAINVAL; + SET_SYMBOL_VAL (XSYMBOL (sym), sym); } ptr = &XVECTOR (obarray)->contents[XINT (tem)]; @@ -3768,8 +3769,6 @@ error ("Attempt to unintern t or nil"); */ XSYMBOL (tem)->interned = SYMBOL_UNINTERNED; - XSYMBOL (tem)->constant = 0; - XSYMBOL (tem)->indirect_variable = 0; hash = oblookup_last_bucket_number; @@ -3914,35 +3913,31 @@ init_obarray () { Lisp_Object oblength; - int hash; - Lisp_Object *tem; XSETFASTINT (oblength, OBARRAY_SIZE); - Qnil = Fmake_symbol (make_pure_c_string ("nil")); Vobarray = Fmake_vector (oblength, make_number (0)); initial_obarray = Vobarray; staticpro (&initial_obarray); - /* Intern nil in the obarray */ - XSYMBOL (Qnil)->interned = SYMBOL_INTERNED_IN_INITIAL_OBARRAY; - XSYMBOL (Qnil)->constant = 1; - - /* These locals are to kludge around a pyramid compiler bug. */ - hash = hash_string ("nil", 3); - /* Separate statement here to avoid VAXC bug. */ - hash %= OBARRAY_SIZE; - tem = &XVECTOR (Vobarray)->contents[hash]; - *tem = Qnil; Qunbound = Fmake_symbol (make_pure_c_string ("unbound")); - XSYMBOL (Qnil)->function = Qunbound; - XSYMBOL (Qunbound)->value = Qunbound; + /* Set temporary dummy values to Qnil and Vpurify_flag to satisfy the + NILP (Vpurify_flag) check in intern_c_string. */ + Qnil = make_number (-1); Vpurify_flag = make_number (1); + Qnil = intern_c_string ("nil"); + + /* Fmake_symbol inits fields of new symbols with Qunbound and Qnil, + so those two need to be fixed manally. */ + SET_SYMBOL_VAL (XSYMBOL (Qunbound), Qunbound); XSYMBOL (Qunbound)->function = Qunbound; + XSYMBOL (Qunbound)->plist = Qnil; + /* XSYMBOL (Qnil)->function = Qunbound; */ + SET_SYMBOL_VAL (XSYMBOL (Qnil), Qnil); + XSYMBOL (Qnil)->constant = 1; + XSYMBOL (Qnil)->plist = Qnil; Qt = intern_c_string ("t"); - XSYMBOL (Qnil)->value = Qnil; - XSYMBOL (Qnil)->plist = Qnil; - XSYMBOL (Qt)->value = Qt; + SET_SYMBOL_VAL (XSYMBOL (Qt), Qt); XSYMBOL (Qt)->constant = 1; /* Qt is correct even if CANNOT_DUMP. loadup.el will set to nil at end. */ @@ -3981,27 +3976,29 @@ to a C variable of type int. Sample call: DEFVAR_INT ("emacs-priority", &emacs_priority, "Documentation"); */ void -defvar_int (const char *namestring, EMACS_INT *address) +defvar_int (struct Lisp_Intfwd *i_fwd, + const char *namestring, EMACS_INT *address) { - Lisp_Object sym, val; + Lisp_Object sym; sym = intern_c_string (namestring); - val = allocate_misc (); - XMISCTYPE (val) = Lisp_Misc_Intfwd; - XINTFWD (val)->intvar = address; - SET_SYMBOL_VALUE (sym, val); + i_fwd->type = Lisp_Fwd_Int; + i_fwd->intvar = address; + XSYMBOL (sym)->redirect = SYMBOL_FORWARDED; + SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)i_fwd); } /* Similar but define a variable whose value is t if address contains 1, nil if address contains 0. */ void -defvar_bool (const char *namestring, int *address) +defvar_bool (struct Lisp_Boolfwd *b_fwd, + const char *namestring, int *address) { - Lisp_Object sym, val; + Lisp_Object sym; sym = intern_c_string (namestring); - val = allocate_misc (); - XMISCTYPE (val) = Lisp_Misc_Boolfwd; - XBOOLFWD (val)->boolvar = address; - SET_SYMBOL_VALUE (sym, val); + b_fwd->type = Lisp_Fwd_Bool; + b_fwd->boolvar = address; + XSYMBOL (sym)->redirect = SYMBOL_FORWARDED; + SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)b_fwd); Vbyte_boolean_vars = Fcons (sym, Vbyte_boolean_vars); } @@ -4011,20 +4008,22 @@ gc-marked for some other reason, since marking the same slot twice can cause trouble with strings. */ void -defvar_lisp_nopro (const char *namestring, Lisp_Object *address) +defvar_lisp_nopro (struct Lisp_Objfwd *o_fwd, + const char *namestring, Lisp_Object *address) { - Lisp_Object sym, val; + Lisp_Object sym; sym = intern_c_string (namestring); - val = allocate_misc (); - XMISCTYPE (val) = Lisp_Misc_Objfwd; - XOBJFWD (val)->objvar = address; - SET_SYMBOL_VALUE (sym, val); + o_fwd->type = Lisp_Fwd_Obj; + o_fwd->objvar = address; + XSYMBOL (sym)->redirect = SYMBOL_FORWARDED; + SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)o_fwd); } void -defvar_lisp (const char *namestring, Lisp_Object *address) +defvar_lisp (struct Lisp_Objfwd *o_fwd, + const char *namestring, Lisp_Object *address) { - defvar_lisp_nopro (namestring, address); + defvar_lisp_nopro (o_fwd, namestring, address); staticpro (address); } @@ -4032,14 +4031,15 @@ at a particular offset in the current kboard object. */ void -defvar_kboard (const char *namestring, int offset) +defvar_kboard (struct Lisp_Kboard_Objfwd *ko_fwd, + const char *namestring, int offset) { - Lisp_Object sym, val; + Lisp_Object sym; sym = intern_c_string (namestring); - val = allocate_misc (); - XMISCTYPE (val) = Lisp_Misc_Kboard_Objfwd; - XKBOARD_OBJFWD (val)->offset = offset; - SET_SYMBOL_VALUE (sym, val); + ko_fwd->type = Lisp_Fwd_Kboard_Obj; + ko_fwd->offset = offset; + XSYMBOL (sym)->redirect = SYMBOL_FORWARDED; + SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)ko_fwd); } /* Record the value of load-path used at the start of dumping
--- a/src/nsmenu.m Tue Apr 20 15:30:26 2010 +0900 +++ b/src/nsmenu.m Tue Apr 20 16:26:02 2010 +0900 @@ -1709,7 +1709,7 @@ - (Lisp_Object)runDialogAt: (NSPoint)p { - int ret; + NSInteger ret; extern EMACS_TIME timer_check (int do_it_now); /* TODO: add to a header */ /* initiate a session that will be ended by pop_down_menu */
--- a/src/print.c Tue Apr 20 15:30:26 2010 +0900 +++ b/src/print.c Tue Apr 20 16:26:02 2010 +0900 @@ -2267,70 +2267,6 @@ strout ("#<misc free cell>", -1, -1, printcharfun, 0); break; - case Lisp_Misc_Intfwd: - sprintf (buf, "#<intfwd to %ld>", (long) *XINTFWD (obj)->intvar); - strout (buf, -1, -1, printcharfun, 0); - break; - - case Lisp_Misc_Boolfwd: - sprintf (buf, "#<boolfwd to %s>", - (*XBOOLFWD (obj)->boolvar ? "t" : "nil")); - strout (buf, -1, -1, printcharfun, 0); - break; - - case Lisp_Misc_Objfwd: - strout ("#<objfwd to ", -1, -1, printcharfun, 0); - print_object (*XOBJFWD (obj)->objvar, printcharfun, escapeflag); - PRINTCHAR ('>'); - break; - - case Lisp_Misc_Buffer_Objfwd: - strout ("#<buffer_objfwd to ", -1, -1, printcharfun, 0); - print_object (PER_BUFFER_VALUE (current_buffer, - XBUFFER_OBJFWD (obj)->offset), - printcharfun, escapeflag); - PRINTCHAR ('>'); - break; - - case Lisp_Misc_Kboard_Objfwd: - strout ("#<kboard_objfwd to ", -1, -1, printcharfun, 0); - print_object (*(Lisp_Object *) ((char *) current_kboard - + XKBOARD_OBJFWD (obj)->offset), - printcharfun, escapeflag); - PRINTCHAR ('>'); - break; - - case Lisp_Misc_Buffer_Local_Value: - strout ("#<buffer_local_value ", -1, -1, printcharfun, 0); - if (XBUFFER_LOCAL_VALUE (obj)->local_if_set) - strout ("[local-if-set] ", -1, -1, printcharfun, 0); - strout ("[realvalue] ", -1, -1, printcharfun, 0); - print_object (XBUFFER_LOCAL_VALUE (obj)->realvalue, - printcharfun, escapeflag); - if (XBUFFER_LOCAL_VALUE (obj)->found_for_buffer) - strout ("[local in buffer] ", -1, -1, printcharfun, 0); - else - strout ("[buffer] ", -1, -1, printcharfun, 0); - print_object (XBUFFER_LOCAL_VALUE (obj)->buffer, - printcharfun, escapeflag); - if (XBUFFER_LOCAL_VALUE (obj)->check_frame) - { - if (XBUFFER_LOCAL_VALUE (obj)->found_for_frame) - strout ("[local in frame] ", -1, -1, printcharfun, 0); - else - strout ("[frame] ", -1, -1, printcharfun, 0); - print_object (XBUFFER_LOCAL_VALUE (obj)->frame, - printcharfun, escapeflag); - } - strout ("[alist-elt] ", -1, -1, printcharfun, 0); - print_object (XCAR (XBUFFER_LOCAL_VALUE (obj)->cdr), - printcharfun, escapeflag); - strout ("[default-value] ", -1, -1, printcharfun, 0); - print_object (XCDR (XBUFFER_LOCAL_VALUE (obj)->cdr), - printcharfun, escapeflag); - PRINTCHAR ('>'); - break; - case Lisp_Misc_Save_Value: strout ("#<save_value ", -1, -1, printcharfun, 0); sprintf(buf, "ptr=0x%08lx int=%d",
--- a/src/s/darwin.h Tue Apr 20 15:30:26 2010 +0900 +++ b/src/s/darwin.h Tue Apr 20 16:26:02 2010 +0900 @@ -90,6 +90,24 @@ */ #define HAVE_PTYS +/* Run only once. We need a `for'-loop because the code uses + `continue'. */ +#define PTY_ITERATION for (i = 0; i < 1; i++) +#define PTY_NAME_SPRINTF /* none */ +#define PTY_TTY_NAME_SPRINTF /* none */ +/* Note that openpty may fork via grantpt on Mac OS X 10.4/Darwin 8. + But we don't have to block SIGCHLD because it is blocked in the + implementation of grantpt. */ +#define PTY_OPEN \ + do \ + { \ + int slave; \ + if (openpty (&fd, &slave, pty_name, NULL, NULL) == -1) \ + fd = -1; \ + else \ + emacs_close (slave); \ + } \ + while (0) /** * PTYs only work correctly on Darwin 7 or higher. So make the
--- a/src/term.c Tue Apr 20 15:30:26 2010 +0900 +++ b/src/term.c Tue Apr 20 16:26:02 2010 +0900 @@ -2244,7 +2244,7 @@ struct tty_display_info *tty; struct frame *f; { - Lisp_Object tem, val, color_mode_spec; + Lisp_Object tem, val; Lisp_Object color_mode; int mode; extern Lisp_Object Qtty_color_mode; @@ -2256,12 +2256,13 @@ if (INTEGERP (val)) color_mode = val; - else + else if (SYMBOLP (tty_color_mode_alist)) { - tem = (NILP (tty_color_mode_alist) ? Qnil - : Fassq (val, XSYMBOL (tty_color_mode_alist)->value)); + tem = Fassq (val, Fsymbol_value (tty_color_mode_alist)); color_mode = CONSP (tem) ? XCDR (tem) : Qnil; } + else + color_mode = Qnil; mode = INTEGERP (color_mode) ? XINT (color_mode) : 0;
--- a/src/xdisp.c Tue Apr 20 15:30:26 2010 +0900 +++ b/src/xdisp.c Tue Apr 20 16:26:02 2010 +0900 @@ -80,7 +80,39 @@ You will find a lot of redisplay optimizations when you start looking at the innards of redisplay. The overall goal of all these optimizations is to make redisplay fast because it is done - frequently. + frequently. Some of these optimizations are implemented by the + following functions: + + . try_cursor_movement + + This function tries to update the display if the text in the + window did not change and did not scroll, only point moved, and + it did not move off the displayed portion of the text. + + . try_window_reusing_current_matrix + + This function reuses the current matrix of a window when text + has not changed, but the window start changed (e.g., due to + scrolling). + + . try_window_id + + This function attempts to redisplay a window by reusing parts of + its existing display. It finds and reuses the part that was not + changed, and redraws the rest. + + . try_window + + This function performs the full redisplay of a single window + assuming that its fonts were not changed and that the cursor + will not end up in the scroll margins. (Loading fonts requires + re-adjustment of dimensions of glyph matrices, which makes this + method impossible to use.) + + These optimizations are tried in sequence (some can be skipped if + it is known that they are not applicable). If none of the + optimizations were successful, redisplay calls redisplay_windows, + which performs a full redisplay of all windows. Desired matrices. @@ -112,13 +144,16 @@ see in dispextern.h. Glyphs in a desired matrix are normally constructed in a loop - calling get_next_display_element and then produce_glyphs. The call - to produce_glyphs will fill the iterator structure with pixel + calling get_next_display_element and then PRODUCE_GLYPHS. The call + to PRODUCE_GLYPHS will fill the iterator structure with pixel information about the element being displayed and at the same time produce glyphs for it. If the display element fits on the line being displayed, set_iterator_to_next is called next, otherwise the - glyphs produced are discarded. - + glyphs produced are discarded. The function display_line is the + workhorse of filling glyph rows in the desired matrix with glyphs. + In addition to producing glyphs, it also handles line truncation + and continuation, word wrap, and cursor positioning (for the + latter, see also set_cursor_from_row). Frame matrices. @@ -139,7 +174,50 @@ wanted to have without having to move many bytes around. To be honest, there is a little bit more done, but not much more. If you plan to extend that code, take a look at dispnew.c. The function - build_frame_matrix is a good starting point. */ + build_frame_matrix is a good starting point. + + Bidirectional display. + + Bidirectional display adds quite some hair to this already complex + design. The good news are that a large portion of that hairy stuff + is hidden in bidi.c behind only 3 interfaces. bidi.c implements a + reordering engine which is called by set_iterator_to_next and + returns the next character to display in the visual order. See + commentary on bidi.c for more details. As far as redisplay is + concerned, the effect of calling bidi_get_next_char_visually, the + main interface of the reordering engine, is that the iterator gets + magically placed on the buffer or string position that is to be + displayed next. In other words, a linear iteration through the + buffer/string is replaced with a non-linear one. All the rest of + the redisplay is oblivious to the bidi reordering. + + Well, almost oblivious---there are still complications, most of + them due to the fact that buffer and string positions no longer + change monotonously with glyph indices in a glyph row. Moreover, + for continued lines, the buffer positions may not even be + monotonously changing with vertical positions. Also, accounting + for face changes, overlays, etc. becomes more complex because + non-linear iteration could potentially skip many positions with + changes, and then cross them again on the way back... + + One other prominent effect of bidirectional display is that some + paragraphs of text need to be displayed starting at the right + margin of the window---the so-called right-to-left, or R2L + paragraphs. R2L paragraphs are displayed with R2L glyph rows, + which have their reversed_p flag set. The bidi reordering engine + produces characters in such rows starting from the character which + should be the rightmost on display. PRODUCE_GLYPHS then reverses + the order, when it fills up the glyph row whose reversed_p flag is + set, by prepending each new glyph to what is already there, instead + of appending it. When the glyph row is complete, the function + extend_face_to_end_of_line fills the empty space to the left of the + leftmost character with special glyphs, which will display as, + well, empty. On text terminals, these special glyphs are simply + blank characters. On graphics terminals, there's a single stretch + glyph with suitably computed width. Both the blanks and the + stretch glyph are given the face of the background of the line. + This way, the terminal-specific back-end can still draw the glyphs + left to right, even for R2L lines. */ #include <config.h> #include <stdio.h> @@ -11514,7 +11592,7 @@ select_frame_for_redisplay (frame) Lisp_Object frame; { - Lisp_Object tail, symbol, val; + Lisp_Object tail, tem; Lisp_Object old = selected_frame; struct Lisp_Symbol *sym; @@ -11522,20 +11600,18 @@ selected_frame = frame; - do - { - for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail)) - if (CONSP (XCAR (tail)) - && (symbol = XCAR (XCAR (tail)), - SYMBOLP (symbol)) - && (sym = indirect_variable (XSYMBOL (symbol)), - val = sym->value, - (BUFFER_LOCAL_VALUEP (val))) - && XBUFFER_LOCAL_VALUE (val)->check_frame) - /* Use find_symbol_value rather than Fsymbol_value - to avoid an error if it is void. */ - find_symbol_value (symbol); - } while (!EQ (frame, old) && (frame = old, 1)); + do { + for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail)) + if (CONSP (XCAR (tail)) + && (tem = XCAR (XCAR (tail)), + SYMBOLP (tem)) + && (sym = indirect_variable (XSYMBOL (tem)), + sym->redirect == SYMBOL_LOCALIZED) + && sym->val.blv->frame_local) + /* Use find_symbol_value rather than Fsymbol_value + to avoid an error if it is void. */ + find_symbol_value (tem); + } while (!EQ (frame, old) && (frame = old, 1)); }