diff options
109 files changed, 3432 insertions, 2068 deletions
diff --git a/build-aux/gitlog-to-emacslog b/build-aux/gitlog-to-emacslog index 3d61ba1e38..cd93eced98 100755 --- a/build-aux/gitlog-to-emacslog +++ b/build-aux/gitlog-to-emacslog @@ -77,7 +77,7 @@ test -d .git || { # Maybe we should skip all "Merge branch 'master'" messages. # See eg the cairo-related ones. ./build-aux/gitlog-to-changelog \ - --ignore-matching="^; |^Merge branch 'master' of git\.(savannah|sv)\.gnu\.org:/srv/git/emacs$|^Merge remote-tracking branch '.*'$" \ + --ignore-matching="^; |^Merge branch '(master|emacs-[0-9][0-9])' of git\.(savannah|sv)\.gnu\.org:/srv/git/emacs$|^Merge remote-tracking branch '.*'$" \ --ignore-line='^; ' --format='%B' \ "$gen_origin..$new_origin" >"ChangeLog.tmp" || exit diff --git a/configure.ac b/configure.ac index b2fa1eddaf..a5b9bd3d37 100644 --- a/configure.ac +++ b/configure.ac @@ -2103,8 +2103,8 @@ AC_CACHE_CHECK( [[malloc_set_state (malloc_get_state ()); __after_morecore_hook = hook; __malloc_initialize_hook = hook;]])], - [emacs_cv_var_doug_lea_malloc=yes])]) - fi + [emacs_cv_var_doug_lea_malloc=yes]) + fi]) doug_lea_malloc=$emacs_cv_var_doug_lea_malloc system_malloc=$emacs_cv_sanitize_address @@ -2192,9 +2192,6 @@ LIBS="$LIBS_SYSTEM $LIBS" dnl FIXME replace main with a function we actually want from this library. AC_CHECK_LIB(Xbsd, main, LD_SWITCH_X_SITE="$LD_SWITCH_X_SITE -lXbsd") -dnl Check for C11 threads. -AC_CHECK_HEADERS_ONCE(threads.h) - dnl Check for the POSIX thread library. LIB_PTHREAD= AC_CHECK_HEADERS_ONCE(pthread.h) @@ -2202,7 +2199,6 @@ if test "$ac_cv_header_pthread_h" && test "$opsys" != "mingw32"; then AC_CACHE_CHECK([for pthread library], [emacs_cv_pthread_lib], [emacs_cv_pthread_lib=no - OLD_CPPFLAGS=$CPPFLAGS OLD_LIBS=$LIBS for emacs_pthread_lib in 'none needed' -lpthread; do case $emacs_pthread_lib in @@ -2231,8 +2227,7 @@ if test "$ac_cv_header_pthread_h" && test "$opsys" != "mingw32"; then if test "$emacs_cv_pthread_lib" != no; then break fi - done - CPPFLAGS=$OLD_CPPFLAGS]) + done]) if test "$emacs_cv_pthread_lib" != no; then AC_DEFINE([HAVE_PTHREAD], 1, [Define to 1 if you have POSIX threads.]) case $emacs_cv_pthread_lib in diff --git a/doc/emacs/buffers.texi b/doc/emacs/buffers.texi index 5a4d1abfc3..ae64fefbb7 100644 --- a/doc/emacs/buffers.texi +++ b/doc/emacs/buffers.texi @@ -703,5 +703,6 @@ C-b}. To customize this buffer list, use the @code{bs} Custom group MSB global minor mode (``MSB'' stands for ``mouse select buffer'') provides a different and customizable mouse buffer menu which you may prefer. It replaces the bindings of @code{mouse-buffer-menu}, -normally on @kbd{C-Down-Mouse-1}, and the menu bar buffer menu. You -can customize the menu in the @code{msb} Custom group. +normally on @kbd{C-Down-Mouse-1} and @kbd{C-@key{F10}}, and the menu +bar buffer menu. You can customize the menu in the @code{msb} Custom +group. diff --git a/doc/emacs/custom.texi b/doc/emacs/custom.texi index 30e040195e..fc405e3a14 100644 --- a/doc/emacs/custom.texi +++ b/doc/emacs/custom.texi @@ -1133,6 +1133,12 @@ won't confuse other programs that the file is intended for. The example above is for the C programming language, where comments start with @samp{/*} and end with @samp{*/}. +If some unrelated text might look to Emacs as a local variables list, +you can countermand that by inserting a form-feed character (a page +delimiter, @pxref{Pages}) after that text. Emacs only looks for +file-local variables in the last page of a file, after the last page +delimiter. + @findex add-file-local-variable @findex delete-file-local-variable @findex copy-dir-locals-to-file-locals diff --git a/doc/emacs/emacs.texi b/doc/emacs/emacs.texi index d87e8077d3..0030467cdc 100644 --- a/doc/emacs/emacs.texi +++ b/doc/emacs/emacs.texi @@ -538,6 +538,7 @@ Frames and Graphical Displays * Multiple Displays:: How one Emacs instance can talk to several displays. * Frame Parameters:: Changing the colors and other modes of frames. * Scroll Bars:: How to enable and disable scroll bars; how to use them. +* Window Dividers:: Window separators that can be dragged with the mouse. * Drag and Drop:: Using drag and drop to open files and insert text. * Menu Bars:: Enabling and disabling the menu bar. * Tool Bars:: Enabling and disabling the tool bar. @@ -593,6 +594,7 @@ Commands for Human Languages * Sentences:: Moving over and killing sentences. * Paragraphs:: Moving over paragraphs. * Pages:: Moving over pages. +* Quotation Marks:: Inserting quotation marks. * Filling:: Filling or justifying text. * Case:: Changing the case of text. * Text Mode:: The major modes for editing text files. @@ -1168,6 +1170,11 @@ Reporting Bugs * Checklist:: Steps to follow for a good bug report. * Sending Patches:: How to send a patch for GNU Emacs. +Contributing to Emacs Development + +* Coding Standards:: Gnu Emacs coding standards. +* Copyright Assignment:: Assigning copyright to the FSF. + Command Line Arguments for Emacs Invocation * Action Arguments:: Arguments to visit files, load libraries, diff --git a/doc/emacs/frames.texi b/doc/emacs/frames.texi index 95b721fa73..acfdfe25cb 100644 --- a/doc/emacs/frames.texi +++ b/doc/emacs/frames.texi @@ -1265,10 +1265,11 @@ Some text terminals support mouse clicks in the terminal window. In a terminal emulator which is compatible with @command{xterm}, you can use @kbd{M-x xterm-mouse-mode} to give Emacs control over simple uses of the mouse---basically, only non-modified single clicks are -supported. The normal @command{xterm} mouse functionality for such -clicks is still available by holding down the @kbd{SHIFT} key when you -press the mouse button. Xterm Mouse mode is a global minor mode -(@pxref{Minor Modes}). Repeating the command turns the mode off +supported. Newer versions of @command{xterm} also support +mouse-tracking. The normal @command{xterm} mouse functionality for +such clicks is still available by holding down the @kbd{SHIFT} key +when you press the mouse button. Xterm Mouse mode is a global minor +mode (@pxref{Minor Modes}). Repeating the command turns the mode off again. @findex gpm-mouse-mode diff --git a/doc/emacs/killing.texi b/doc/emacs/killing.texi index f05b8cc544..9761ac7d11 100644 --- a/doc/emacs/killing.texi +++ b/doc/emacs/killing.texi @@ -853,6 +853,19 @@ so in a rectangular fashion, and killing and yanking operate on the rectangle. @xref{Killing}. The mode persists only as long as the region is active. +Unlike the standard region, the region-rectangle can have its corners +extended past the end of buffer, or inside stretches of white space +that point normally cannot enter, like the TAB. + +@findex rectangle-exchange-point-and-mark +@findex exchange-point-and-mark@r{, in rectangle-mark-mode} +@kindex C-x C-x@r{, in rectangle-mark-mode} +When the region is in rectangle-mark-mode, @kbd{C-x C-x} runs the +command @code{rectangle-exchange-point-and-mark}, which cycles between +the four corners of the region-rectangle. This comes in handy if you +want to modify the dimensions of the region-rectangle before invoking +an operation on the marked text. + @node CUA Bindings @section CUA Bindings @findex cua-mode diff --git a/doc/emacs/maintaining.texi b/doc/emacs/maintaining.texi index f1a59f8435..359b50321c 100644 --- a/doc/emacs/maintaining.texi +++ b/doc/emacs/maintaining.texi @@ -47,6 +47,17 @@ variable @code{vc-handled-backends} to @code{nil} (@pxref{Customizing VC}). @end ifnottex +@findex vc-refresh-state +@findex vc-state-refresh + To update the VC state information for the file visited in the +current buffer, use the command @code{vc-refresh-state}. This command +is useful when you perform version control commands outside Emacs +(e.g., from the shell prompt), or if you put the buffer's file under a +different version control system, or remove it from version control +entirely. A companion command @code{vc-state-refresh} does the same, +but does not consider switching the version control system or removal +from VC. + @menu * Introduction to VC:: How version control works in general. * VC Mode Line:: How the mode line shows version control status. diff --git a/doc/emacs/mini.texi b/doc/emacs/mini.texi index ed339a967a..869e06424a 100644 --- a/doc/emacs/mini.texi +++ b/doc/emacs/mini.texi @@ -588,13 +588,17 @@ argument into the minibuffer: @table @kbd @item M-p -@itemx @key{UP} Move to the previous item in the minibuffer history, an earlier argument (@code{previous-history-element}). @item M-n -@itemx @key{DOWN} Move to the next item in the minibuffer history (@code{next-history-element}). +@item @key{UP} +@itemx @key{DOWN} +Like @kbd{M-p} and @kbd{M-n}, but move to the previous or next line of +a multi-line item before going to the previous history item +(@code{previous-line-or-history-element} and +@code{next-line-or-history-element}) . @item M-r @var{regexp} @key{RET} Move to an earlier item in the minibuffer history that matches @var{regexp} (@code{previous-matching-history-element}). @@ -609,13 +613,13 @@ Move to a later item in the minibuffer history that matches @kindex DOWN @r{(minibuffer history)} @findex next-history-element @findex previous-history-element - While in the minibuffer, @kbd{M-p} or @key{UP} -(@code{previous-history-element}) moves through the minibuffer history -list, one item at a time. Each @kbd{M-p} fetches an earlier item from -the history list into the minibuffer, replacing its existing contents. -Typing @kbd{M-n} or @key{DOWN} (@code{next-history-element}) moves -through the minibuffer history list in the opposite direction, -fetching later entries into the minibuffer. + While in the minibuffer, @kbd{M-p} (@code{previous-history-element}) +moves through the minibuffer history list, one item at a time. Each +@kbd{M-p} fetches an earlier item from the history list into the +minibuffer, replacing its existing contents. Typing @kbd{M-n} +(@code{next-history-element}) moves through the minibuffer history +list in the opposite direction, fetching later entries into the +minibuffer. If you type @kbd{M-n} in the minibuffer when there are no later entries in the minibuffer history (e.g., if you haven't previously @@ -623,6 +627,14 @@ typed @kbd{M-p}), Emacs tries fetching from a list of default arguments: values that you are likely to enter. You can think of this as moving through the ``future history''. +@findex previous-line-or-history-element +@findex next-line-or-history-element + The arrow keys @kbd{@key{UP}} and @kbd{@key{DOWN}} work like +@kbd{M-p} and @kbd{M-n}, but if the current history item is longer +than a single line, they allow you to move to the previous or next +line of the current history item before going to the previous or next +history item. + If you edit the text inserted by the @kbd{M-p} or @kbd{M-n} minibuffer history commands, this does not change its entry in the history list. However, the edited argument does go at the end of the diff --git a/doc/emacs/misc.texi b/doc/emacs/misc.texi index 03e6613770..41dce521c0 100644 --- a/doc/emacs/misc.texi +++ b/doc/emacs/misc.texi @@ -761,6 +761,10 @@ advancing point, and any terminal input for the subshell comes from text in the buffer. To give input to the subshell, go to the end of the buffer and type the input, terminated by @key{RET}. + By default, when the subshell is invoked interactively, the +@file{*shell*} buffer is displayed in a new window. This behavior can +be customized via @code{display-buffer-alist} (@pxref{Window Choice}). + While the subshell is waiting or running a command, you can switch windows or buffers and perform other editing in Emacs. Emacs inserts the output from the subshell into the Shell buffer whenever it has diff --git a/doc/emacs/package.texi b/doc/emacs/package.texi index 1a6a735d3a..5f80b0afe3 100644 --- a/doc/emacs/package.texi +++ b/doc/emacs/package.texi @@ -59,7 +59,12 @@ The package's version number (e.g., @samp{11.86}). The package's status---normally one of @samp{available} (can be downloaded from the package archive), @samp{installed}, @c @samp{unsigned} (installed, but not signed; @pxref{Package Signing}), -or @samp{built-in} (included in Emacs by default). +or @samp{built-in} (included in Emacs by default). The status +@samp{external} means the package is not built-in and not from the +directory specified by @code{package-user-dir} (@pxref{Package +Files}). External packages are treated much like built-in: they +cannot be deleted through the package menu, and are not considered for +upgrading. The status can also be @samp{new}. This is equivalent to @samp{available}, except that it means the package became newly @@ -106,7 +111,13 @@ line; typing @kbd{x} (see below) will delete the package. @xref{Package Files}, for information about what package deletion entails. +@item ~ +Mark all obsolete packages for deletion +(@code{package-menu-mark-obsolete-for-deletion}). This marks for +deletion all the packages whose status is @samp{obsolete}. + @item u +@itemx @key{DEL} Remove any installation or deletion mark previously added to the current line by an @kbd{i} or @kbd{d} command. @@ -117,6 +128,7 @@ on the new available versions, and a deletion mark on the old installed versions. @item x +@vindex package-menu-async Download and install all packages marked with @kbd{i}, and their dependencies; also, delete all packages marked with @kbd{d} (@code{package-menu-execute}). This also removes the marks. @@ -131,6 +143,14 @@ Filter the package list (@code{package-menu-filter}). This prompts for a keyword (e.g., @samp{games}), then shows only the packages that relate to that keyword. To restore the full package list, type @kbd{q}. + +@item H +Permanently hide packages that match a regexp +(@code{package-menu-hide-package}). + +@item ( +Toggle visibility of old versions of packages and also of versions +from lower-priority archives (@code{package-menu-toggle-hiding}). @end table @noindent @@ -205,6 +225,17 @@ offer different versions of the same package, you may find the option pairs to this list, to ensure that the specified package is only ever downloaded from the specified archive. +@vindex package-archive-priorities +@vindex package-menu-hide-low-priority + Another option that is useful when you have several package archives +enabled is @code{package-archive-priorities}. It specifies the +priority of each archive (higher numbers specify higher priority +archives). By default, archives have the priority of zero, unless +specified otherwise by this option's value. Packages from +lower-priority archives will not be shown in the menu, if the same +package is available from a higher-priority archive. (This is +controlled by the value of @code{package-menu-hide-low-priority}.) + Once a package is downloaded and installed, it is @dfn{loaded} into the current Emacs session. Loading a package is not quite the same as loading a Lisp library (@pxref{Lisp Libraries}); its effect varies diff --git a/doc/emacs/programs.texi b/doc/emacs/programs.texi index f9d9a27e8e..8423b70203 100644 --- a/doc/emacs/programs.texi +++ b/doc/emacs/programs.texi @@ -833,9 +833,36 @@ displayed. The default is 102400. @findex show-paren-mode Show Paren mode, a global minor mode, provides a more powerful kind of automatic matching. Whenever point is before an opening delimiter -or after a closing delimiter, both that delimiter and its opposite -delimiter are highlighted. To toggle Show Paren mode, type @kbd{M-x -show-paren-mode}. +or after a closing delimiter, the delimiter, its matching delimiter, +and optionally the text between them are highlighted. To toggle Show +Paren mode, type @kbd{M-x show-paren-mode}. To customize it, type +@kbd{M-x customize-group @key{RET} paren-showing}. The customizable +options which control the operation of this mode include: + +@itemize @bullet +@item +@code{show-paren-highlight-open-paren} controls whether to highlight +an open paren when point stands just before it, and hence its position +is marked by the cursor anyway. The default is non-@code{nil} (yes). + +@item +@code{show-paren-style} controls whether just the two parens, or also +the space between them get highlighted. The valid options here are +@code{parenthesis} (show the matching paren), @code{expression} +(highlight the entire expression enclosed by the parens), and +@code{mixed} (highlight the matching paren if it is visible, the +expression otherwise). + +@item +@code{show-paren-when-point-inside-paren}, when non-@code{nil}, causes +highlighting also when point is on the inside of a parenthesis. + +@item +@code{show-paren-when-point-in-periphery}, when non-@code{nil}, causes +highlighting also when point is in whitespace at the beginning or end +of a line, and there is a paren at, respectively, the first or last, +or the last, non-whitespace position on the line. +@end itemize @cindex Electric Pair mode @cindex inserting matching parentheses @@ -1234,13 +1261,16 @@ variables that you want to use. @xref{Name Help}. @cindex Eldoc mode @findex eldoc-mode +@findex global-eldoc-mode Eldoc is a buffer-local minor mode that helps with looking up Lisp documentation. When it is enabled, the echo area displays some useful information whenever there is a Lisp function or variable at point; for a function, it shows the argument list, and for a variable it shows the first line of the variable's documentation string. To -toggle Eldoc mode, type @kbd{M-x eldoc-mode}. Eldoc mode can be used -with the Emacs Lisp and Lisp Interaction major modes. +toggle Eldoc mode, type @kbd{M-x eldoc-mode}. There's also a Global +Eldoc mode, which is turned on by default, and affects buffers, such +as @samp{*scratch*}, whose major mode is Emacs Lisp or Lisp +Interaction (@w{@kbd{M-x global-eldoc-mode}} to turn it off globally). @node Hideshow @section Hideshow minor mode @@ -1498,14 +1528,21 @@ with the Foldout package (@pxref{Foldout}). @findex prettify-symbols-mode Prettify Symbols mode is a buffer-local minor mode that replaces -certain strings with more attractive versions for display -purposes. For example, in Emacs Lisp mode, it replaces the string -@samp{lambda} with the Greek lambda character @samp{λ}. You may wish -to use this -in non-programming modes as well. You can customize the mode by -adding more entries to @code{prettify-symbols-alist}. There is also a -global version, @code{global-prettify-symbols-mode}, which enables the -mode in all buffers that support it. +certain strings with more attractive versions for display purposes. +For example, in Emacs Lisp mode, it replaces the string @samp{lambda} +with the Greek lambda character @samp{λ}. You may wish to use this in +non-programming modes as well. You can customize the mode by adding +more entries to @code{prettify-symbols-alist}. More elaborate +customization is available via customizing +@code{prettify-symbols-compose-predicate} if its default value +@code{prettify-symbols-default-compose-p} is not appropriate. There +is also a global version, @code{global-prettify-symbols-mode}, which +enables the mode in all buffers that support it. + + The symbol at point can be shown in its original form. This is +controlled by the variable @code{prettify-symbols-unprettify-at-point}: +if non-@code{nil}, the original form of symbol at point will be +restored for as long as point is at it. @node C Modes diff --git a/doc/emacs/regs.texi b/doc/emacs/regs.texi index d8841caa31..13c03f78a5 100644 --- a/doc/emacs/regs.texi +++ b/doc/emacs/regs.texi @@ -293,9 +293,11 @@ various files. Set the bookmark for the visited file, at point. @item C-x r m @var{bookmark} @key{RET} -@findex bookmark-set Set the bookmark named @var{bookmark} at point (@code{bookmark-set}). +@item C-x r M @var{bookmark} @key{RET} +Like @kbd{C-x r m}, but don't overwrite an existing bookmark. + @item C-x r b @var{bookmark} @key{RET} @findex bookmark-jump Jump to the bookmark named @var{bookmark} (@code{bookmark-jump}). @@ -320,6 +322,12 @@ name. If you name each bookmark after the file it points to, then you can conveniently revisit any of those files with @kbd{C-x r b}, and move to the position of the bookmark at the same time. +@kindex C-x r M +@findex bookmark-set-no-overwrite + The command @kbd{C-x r M} (@code{bookmark-set-no-overwrite}) works +like @kbd{C-x r m}, but it signals an error if the specified bookmark +already exists, instead of overwriting it. + @kindex C-x r l To display a list of all your bookmarks in a separate buffer, type @kbd{C-x r l} (@code{list-bookmarks}). If you switch to that buffer, diff --git a/doc/emacs/rmail.texi b/doc/emacs/rmail.texi index 6e2a60b637..b37f42cc56 100644 --- a/doc/emacs/rmail.texi +++ b/doc/emacs/rmail.texi @@ -282,9 +282,9 @@ current message and select another. @kbd{d} messages already deleted, while @kbd{C-d} (@code{rmail-delete-backward}) moves to the previous nondeleted message. If there is no nondeleted message to move to in the specified direction, the message that was just -deleted remains current. @kbd{d} with a prefix argument is equivalent -to @kbd{C-d}. Note that the Rmail summary versions of these commands -behave slightly differently (@pxref{Rmail Summary Edit}). +deleted remains current. A numeric prefix argument serves as a repeat +count, to allow deletion of several messages in a single command. A +negative argument reverses the meaning of @kbd{d} and @kbd{C-d}. @c mention other hooks, e.g., show message hook? @vindex rmail-delete-message-hook @@ -305,7 +305,8 @@ type @kbd{x} (@code{rmail-expunge}). Until you do this, you can still effect of a @kbd{d} command in most cases. It undeletes the current message if the current message is deleted. Otherwise it moves backward to previous messages until a deleted message is found, and undeletes -that message. +that message. A numeric prefix argument serves as a repeat count, to +allow deletion of several messages in a single command. You can usually undo a @kbd{d} with a @kbd{u} because the @kbd{u} moves back to and undeletes the message that the @kbd{d} deleted. But @@ -974,13 +975,11 @@ different lines. It doesn't matter what Emacs command you use to move point; whichever line point is on at the end of the command, that message is selected in the Rmail buffer. - Almost all Rmail commands work in the summary buffer as well as in the -Rmail buffer. Thus, @kbd{d} in the summary buffer deletes the current -message, @kbd{u} undeletes, and @kbd{x} expunges. (However, in the -summary buffer, a numeric argument to @kbd{d}, @kbd{C-d} and @kbd{u} -serves as a repeat count. A negative argument reverses the meaning of -@kbd{d} and @kbd{C-d}. Also, if there are no more undeleted messages in -the relevant direction, the delete commands go to the first or last + Almost all Rmail commands work in the summary buffer as well as in +the Rmail buffer. Thus, @kbd{d} in the summary buffer deletes the +current message, @kbd{u} undeletes, and @kbd{x} expunges. (However, +in the summary buffer, if there are no more undeleted messages in the +relevant direction, the delete commands go to the first or last message, rather than staying on the current message.) @kbd{o} and @kbd{C-o} output the current message to a FILE; @kbd{r} starts a reply to it; etc. You can scroll the current message while remaining in the @@ -1224,6 +1223,15 @@ tagline (except for buttons for other actions, if there are any). Type the undecoded @acronym{MIME} data. With a prefix argument, this command toggles the display of only an entity at point. +@vindex rmail-mime-prefer-html + If the message has an @acronym{HTML} @acronym{MIME} part, Rmail +displays it in preference to the plain-text part, if Emacs can render +@acronym{HTML}@footnote{ +This capability requires that Emacs be built with @file{libxml2} +support or that you have the Lynx browser installed.}. To prevent +that, and have the plain-text part displayed instead, customize the +variable @code{rmail-mime-prefer-html} to a @code{nil} value. + To prevent Rmail from handling MIME decoded messages, change the variable @code{rmail-enable-mime} to @code{nil}. When this is the case, the @kbd{v} (@code{rmail-mime}) command instead creates a diff --git a/doc/emacs/trouble.texi b/doc/emacs/trouble.texi index 087681b561..4286cfeb73 100644 --- a/doc/emacs/trouble.texi +++ b/doc/emacs/trouble.texi @@ -1065,7 +1065,7 @@ send it to the developers. Sending it to recommended, because that list is coupled to a tracking system that makes it easier to locate patches. If your patch is not complete and you think it needs more discussion, you might want to send it to -@email{emacs-devel@@gnu@@gnu.org} instead. If you revise your patch, +@email{emacs-devel@@gnu.org} instead. If you revise your patch, send it as a followup to the initial topic. We prefer to get the patches as plain text, either inline (be careful diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index e9354cc267..d1ac85a7ca 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -330,7 +330,7 @@ support them, then @code{message-box} uses the echo area, like @code{message}. @end defun -@defun display-message-or-buffer message &optional buffer-name not-this-window frame +@defun display-message-or-buffer message &optional buffer-name action frame This function displays the message @var{message}, which may be either a string or a buffer. If it is shorter than the maximum height of the echo area, as defined by @code{max-mini-window-height}, it is displayed @@ -346,7 +346,7 @@ pop-up buffer is used, defaulting to @file{*Message*}. In the case where @var{message} is a string and displayed in the echo area, it is not specified whether the contents are inserted into the buffer anyway. -The optional arguments @var{not-this-window} and @var{frame} are as for +The optional arguments @var{action} and @var{frame} are as for @code{display-buffer}, and only used if a buffer is displayed. @end defun diff --git a/doc/lispref/elisp.texi b/doc/lispref/elisp.texi index 2d3548f65b..56d303e2e9 100644 --- a/doc/lispref/elisp.texi +++ b/doc/lispref/elisp.texi @@ -467,6 +467,10 @@ Control Structures * Generators:: Generic sequences and coroutines. * Nonlocal Exits:: Jumping out of a sequence. +Conditionals + +* Pattern matching case statement:: How to use @code{pcase}. + Nonlocal Exits * Catch and Throw:: Nonlocal exits for the program's own purposes. @@ -535,6 +539,7 @@ Functions * Function Cells:: Accessing or setting the function definition of a symbol. * Closures:: Functions that enclose a lexical environment. +* Advising Functions:: Adding to the definition of a function. * Obsolete Functions:: Declaring functions obsolete. * Inline Functions:: Defining functions that the compiler will expand inline. @@ -552,6 +557,13 @@ Lambda Expressions * Argument List:: Details and special features of argument lists. * Function Documentation:: How to put documentation in a function. +Advising Emacs Lisp Functions + +* Core Advising Primitives:: Primitives to manipulate advice. +* Advising Named Functions:: Advising named functions. +* Advice combinators:: Ways to compose advice. +* Porting old advice:: Adapting code using the old defadvice. + Macros * Simple Macro:: A basic example. @@ -602,6 +614,7 @@ Loading * Unloading:: How to unload a library that was loaded. * Hooks for Loading:: Providing code to be run when particular libraries are loaded. +* Dynamic Modules:: Modules provide additional Lisp primitives. Byte Compilation @@ -1191,6 +1204,10 @@ Text Properties * Not Intervals:: Why text properties do not use Lisp-visible text intervals. +Parsing HTML and XML + +* Document Object Model:: Access, manipulate and search the @acronym{DOM}. + Non-@acronym{ASCII} Characters * Text Representations:: How Emacs represents text. @@ -1530,9 +1547,12 @@ GNU Emacs Internals * Building Emacs:: How the dumped Emacs is made. * Pure Storage:: Kludge to make preloaded Lisp functions shareable. * Garbage Collection:: Reclaiming space for Lisp objects no longer used. +* Stack-allocated Objects:: Temporary conses and strings on C stack. * Memory Usage:: Info about total size of Lisp objects made so far. +* C Dialect:: What C variant Emacs is written in. * Writing Emacs Primitives:: Writing C code for Emacs. * Object Internals:: Data formats of buffers, windows, processes. +* C Integer Types:: How C integer types are used inside Emacs. Object Internals diff --git a/doc/lispref/eval.texi b/doc/lispref/eval.texi index 662737b754..dfad9fb709 100644 --- a/doc/lispref/eval.texi +++ b/doc/lispref/eval.texi @@ -834,9 +834,9 @@ The value of this variable is a list of the values returned by all the expressions that were read, evaluated, and printed from buffers (including the minibuffer) by the standard Emacs commands which do this. (Note that this does @emph{not} include evaluation in -@file{*ielm*} buffers, nor evaluation using @kbd{C-j} in -@code{lisp-interaction-mode}.) The elements are ordered most recent -first. +@file{*ielm*} buffers, nor evaluation using @kbd{C-j}, @kbd{C-x C-e}, +and similar evaluation commands in @code{lisp-interaction-mode}.) The +elements are ordered most recent first. @example @group diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi index 3c1a87a314..80a4af29f1 100644 --- a/doc/lispref/frames.texi +++ b/doc/lispref/frames.texi @@ -1001,18 +1001,40 @@ parameters of @var{frame} and their values. If @var{frame} is @end defun @defun modify-frame-parameters frame alist -This function alters the parameters of frame @var{frame} based on the -elements of @var{alist}. Each element of @var{alist} has the form -@code{(@var{parm} . @var{value})}, where @var{parm} is a symbol naming a -parameter. If you don't mention a parameter in @var{alist}, its value -doesn't change. If @var{frame} is @code{nil}, it defaults to the selected -frame. +This function alters the frame @var{frame} based on the elements of +@var{alist}. Each element of @var{alist} has the form +@code{(@var{parm} . @var{value})}, where @var{parm} is a symbol naming +a parameter. If you don't mention a parameter in @var{alist}, its +value doesn't change. If @var{frame} is @code{nil}, it defaults to +the selected frame. + +Some parameters are only meaningful for frames on certain kinds of +display (@pxref{Frames}). If @var{alist} includes parameters that are +not meaningful for the @var{frame}'s display, this function will +change its value in the frame's parameter list, but will otherwise +ignore it. + +When @var{alist} specifies more than one parameter whose value can +affect the new size of @var{frame}, the final size of the frame may +differ according to the toolkit used. For example, specifying that a +frame should from now on have a menu and/or tool bar instead of none and +simultaneously specifying the new height of the frame will inevitably +lead to a recalculation of the frame's height. Conceptually, in such +case, this function will try to have the explicit height specification +prevail. It cannot be excluded, however, that the addition (or removal) +of the menu or tool bar, when eventually performed by the toolkit, will +defeat this intention. + +Sometimes, binding @code{frame-inhibit-implied-resize} (@pxref{Implied +Frame Resizing}) to a non-@code{nil} value around calls to this function +may fix the problem sketched here. Sometimes, however, exactly such +binding may be hit by the problem. @end defun @defun set-frame-parameter frame parm value This function sets the frame parameter @var{parm} to the specified -@var{value}. If @var{frame} is @code{nil}, it defaults to the -selected frame. +@var{value}. If @var{frame} is @code{nil}, it defaults to the selected +frame. @end defun @defun modify-all-frames-parameters alist diff --git a/doc/lispref/loading.texi b/doc/lispref/loading.texi index 82de765876..e01f316173 100644 --- a/doc/lispref/loading.texi +++ b/doc/lispref/loading.texi @@ -29,7 +29,15 @@ into a buffer and evaluated there. (Indeed, most code is tested this way.) Most often, the forms are function definitions and variable definitions. -For on-demand loading of external libraries, @pxref{Dynamic Libraries}. + Emacs can also load compiled dynamic modules: shared libraries that +provide additional functionality for use in Emacs Lisp programs, just +like a package written in Emacs Lisp would. When a dynamic module is +loaded, Emacs calls a specially-named initialization function which +the module needs to implement, and which exposes the additional +functions and variables to Emacs Lisp programs. + +For on-demand loading of external libraries which are known in advance +to be required by certain Emacs primitives, @pxref{Dynamic Libraries}. @menu * How Programs Do Loading:: The @code{load} function and others. @@ -43,6 +51,7 @@ For on-demand loading of external libraries, @pxref{Dynamic Libraries}. * Unloading:: How to unload a library that was loaded. * Hooks for Loading:: Providing code to be run when particular libraries are loaded. +* Dynamic Modules:: Modules provide additional Lisp primitives. @end menu @node How Programs Do Loading @@ -1076,3 +1085,53 @@ defined in another library (those meant for outside use), you can do it immediately---there is no need to wait until the library is loaded. If you need to call functions defined by that library, you should load the library, preferably with @code{require} (@pxref{Named Features}). + +@node Dynamic Modules +@section Emacs Dynamic Modules +@cindex dynamic modules + +@c FIXME: This is intentionally incomplete, as the module integration +@c is not yet finished. To be refined later. + A @dfn{dynamic Emacs module} is a shared library that provides +additional functionality for use in Emacs Lisp programs, just like a +package written in Emacs Lisp would. + + Functions that load Emacs Lisp packages can also load dynamic +modules. They recognize dynamic modules by looking at their file-name +extension, a.k.a.@: ``suffix''. This suffix is platform-dependent. + +@defvar module-file-suffix +This variable holds the system-dependent value of the file-name +extension of the module files. Its value is @file{.so} on Posix hosts +and @file{.dll} on MS-Windows. +@end defvar + +@findex emacs_module_init +@vindex plugin_is_GPL_compatible +Every dynamic module should export a C-callable function named +@code{emacs_module_init}, which Emacs will call as part of the call to +@code{load} or @code{require} which loads the module. It should also +export a symbol named @code{plugin_is_GPL_compatible} to indicate that +its code is released under the GPL or compatible license; Emacs will +refuse to load modules that don't export such a symbol. + +If a module needs to call Emacs functions, it should do so through the +API defined and documented in the header file @file{emacs-module.h} +that is part of the Emacs distribution. + +@cindex user-ptr object +Modules can create @code{user-ptr} Lisp objects that embed pointers to +C struct's defined by the module. This is useful for keeping around +complex data structures created by a module, to be passed back to the +module's functions. User-ptr objects can also have associated +@dfn{finalizers} -- functions to be run when the object is GC'ed; this +is useful for freeing any resources allocated for the underlying data +structure, such as memory, open file descriptors, etc. + +@defun user-ptrp object +This function returns @code{t} if its argument is a @code{user-ptr} +object. +@end defun + +Loadable modules in Emacs are enabled by using the +@kbd{--with-modules} option at configure time. diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi index a1747707d1..3b8550e13b 100644 --- a/doc/lispref/modes.texi +++ b/doc/lispref/modes.texi @@ -2509,6 +2509,53 @@ Search-based fontification happens second. @node Font Lock Basics @subsection Font Lock Basics + The Font Lock functionality is based on several basic functions. +Each of these calls the function specified by the corresponding +variable. This indirection allows major modes to modify the way +fontification works in the buffers of that mode, and even use the Font +Lock mechanisms for features that have nothing to do with +fontification. (This is why the description below says ``should'' +when it describes what the functions do: the major mode can customize +the values of the corresponding variables to do something entirely +different.) The variables mentioned below are described in @ref{Other +Font Lock Variables}. + +@ftable @code +@item font-lock-fontify-buffer +This function should fontify the current buffer's accessible portion, +by calling the function specified by +@code{font-lock-fontify-buffer-function}. + +@item font-lock-unfontify-buffer +Used when turning Font Lock off to remove the fontification. Calls +the function specified by @code{font-lock-unfontify-buffer-function}. + +@item font-lock-fontify-region beg end &optional loudly +Should fontify the region between @var{beg} and @var{end}. If +@var{loudly} is non-@code{nil}, should display status messages while +fontifying. Calls the function specified by +@code{font-lock-fontify-region-function}. + +@item font-lock-unfontify-region beg end +Should remove fontification from the region between @var{beg} and +@var{end}. Calls the function specified by +@code{font-lock-unfontify-region-function}. + +@item font-lock-flush &optional beg end +This function should mark the fontification of the region between +@var{beg} and @var{end} as outdated. If not specified or @code{nil}, +@var{beg} and @var{end} default to the beginning and end of the +buffer's accessible portion. Calls the function specified by +@code{font-lock-flush-function}. + +@item font-lock-ensure &optional beg end +This function should make sure the region between @var{beg} and +@var{end} has been fontified. The optional arguments @var{beg} and +@var{end} default to the beginning and the end of the buffer's +accessible portion. Calls the function specified by +@code{font-lock-ensure-function}. +@end ftable + There are several variables that control how Font Lock mode highlights text. But major modes should not set any of these variables directly. Instead, they should set @code{font-lock-defaults} as a buffer-local @@ -2936,6 +2983,22 @@ arguments, the beginning and end of the region. The default value is @code{font-lock-default-unfontify-region}. @end defvar +@defvar font-lock-flush-function +Function to use for declaring that a region's fontification is out of +date. It takes two arguments, the beginning and end of the region. +The default value of this variable is +@code{font-lock-after-change-function}. +@end defvar + +@defvar font-lock-ensure-function +Function to use for making sure a region of the current buffer has +been fontified. It is called with two arguments, the beginning and +end of the region. The default value of this variable is a function +that calls @code{font-lock-default-fontify-buffer} if the buffer is +not fontified; the effect is to make sure the entire accessible +portion of the buffer is fontified. +@end defvar + @defun jit-lock-register function &optional contextual This function tells Font Lock mode to run the Lisp function @var{function} any time it has to fontify or refontify part of the diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi index 1bb5303620..f3679a88f7 100644 --- a/doc/lispref/text.texi +++ b/doc/lispref/text.texi @@ -899,13 +899,25 @@ adds it to the most recent element. It determines automatically (using @code{last-command}) whether the previous command was a kill command, and if so appends the killed text to the most recent entry. -@deffn Command kill-region start end -This function kills the text in the region defined by @var{start} and -@var{end}. The text is deleted but saved in the kill ring, along with -its text properties. The value is always @code{nil}. +@cindex filtering killed text + The commands described below can filter the killed text before they +save it in the kill ring. They call @code{filter-buffer-substring} +(@pxref{Buffer Contents}) to perform the filtering. By default, +there's no filtering, but major and minor modes and hook functions can +set up filtering, so that text saved in the kill ring is different +from what was in the buffer. + +@deffn Command kill-region start end &optional region +This function kills the stretch of text between @var{start} and +@var{end}; but if the optional argument @var{region} is +non-@code{nil}, it ignores @var{start} and @var{end}, and kills the +text in the current region instead. The text is deleted but saved in +the kill ring, along with its text properties. The value is always +@code{nil}. In an interactive call, @var{start} and @var{end} are point and -the mark. +the mark, and @var{region} is always non-@code{nil}, so the command +always kills the text in the current region. If the buffer or text is read-only, @code{kill-region} modifies the kill ring just the same, then signals an error without modifying the buffer. @@ -919,18 +931,20 @@ error if the buffer or text is read-only. Instead, it simply returns, updating the kill ring but not changing the buffer. @end defopt -@deffn Command copy-region-as-kill start end -This command saves the region defined by @var{start} and @var{end} on -the kill ring (including text properties), but does not delete the text -from the buffer. It returns @code{nil}. +@deffn Command copy-region-as-kill start end &optional region +This function saves the stretch of text between @var{start} and +@var{end} on the kill ring (including text properties), but does not +delete the text from the buffer. However, if the optional argument +@var{region} is non-@code{nil}, the function ignores @var{start} and +@var{end}, and saves the current region instead. It always returns +@code{nil}. + +In an interactive call, @var{start} and @var{end} are point and +the mark, and @var{region} is always non-@code{nil}, so the command +always saves the text in the current region. The command does not set @code{this-command} to @code{kill-region}, so a subsequent kill command does not append to the same kill ring entry. - -@c FIXME Why is it better? Why isn't copy-region-as-kill obsolete then? -@c Why is it used in many places in Emacs? -In Lisp programs, it is better to use @code{kill-new} or -@code{kill-append} instead of this command. @xref{Low-Level Kill Ring}. @end deffn @node Yanking @@ -1353,26 +1367,27 @@ appropriate time. @end defun @defun undo-auto-amalgamate +@cindex amalgamating commands, and undo The editor command loop automatically calls @code{undo-boundary} just before executing each key sequence, so that each undo normally undoes the effects of one command. A few exceptional commands are -@emph{amalgamating}: these commands generally cause small changes to -buffers. So with these a boundary is inserted only every 20th command, -so that these can be undone as a group. By default commands +@dfn{amalgamating}: these commands generally cause small changes to +buffers, so with these a boundary is inserted only every 20th command, +allowing to undo them as a group. By default, commands @code{self-insert-command}, which produces self-inserting input characters (@pxref{Commands for Insertion}), and @code{delete-char} which deletes characters (@pxref{Deletion}) are amalgamating. -Where a command affects the contents of several buffers as may happen, -for example, if a function on the @code{post-command-hook} affects a +Where a command affects the contents of several buffers, as may happen, +for example, when a function on the @code{post-command-hook} affects a buffer other than the @code{current-buffer}, then @code{undo-boundary} -will be called in each of them. +will be called in each of the affected buffers. @end defun @defvar undo-auto-current-boundary-timer Some buffers, such as process buffers, can change even when no -commands are executing. In these cases, @code{undo-boundary} is -normally called periodically by the timer in this variable. Setting -this variable to non-@code{nil} prevents this behaviour. +commands are executing. In these cases, @code{undo-boundary} is +normally called periodically by the timer in this variable. Setting +this variable to non-@code{nil} prevents this behavior. @end defvar @defvar undo-in-progress @@ -2347,6 +2362,84 @@ already indented, it calls @code{completion-at-point} to complete the text at point (@pxref{Completion in Buffers}). @end defopt +@cindex literate programming +@cindex multi-mode indentation + Some major modes need to support embedded regions of text whose +syntax belongs to a different major mode. Examples include +@dfn{literate programming} source files that combine documentation and +snippets of source code, Yacc/Bison programs that include snippets of +plain C code, etc. To correctly indent the embedded chunks, the major +mode needs to delegate the indentation to another mode's indentation +engine (e.g., call @code{c-indent-defun} for C code or +@code{python-indent-line} for Python), while providing it with some +context to guide the indentation. The following facilities support +such multi-mode indentation. + +@defvar prog-indentation-context +This variable, when non-@code{nil}, holds the indentation context for +the sub-mode's indentation engine provided by the superior major mode. +The value should be a list of the form @code{(@var{first-column} +@w{(@var{start} . @var{end})} @code{prev-chunk})}. The members of the +list have the following meaning: + +@table @var +@item first-column +The column to be used for top-level constructs. This replaces the +default value of the top-level column used by the sub-mode, usually +zero. +@item start +@itemx end +The region of the code chunk to be indented by the sub-mode. The +value of @var{end} can be @code{nil}, which stands for the value of +@code{point-max}. +@item prev-chunk +If this is non-@code{nil}, it should provide the sub-mode's +indentation engine with a virtual context of the code chunk. Valid +values include: + +@itemize @minus +@item +A string whose contents is the text the sub-mode's indentation engine +should consider to precede the code chunk. The sub-mode's indentation +engine can add text properties to that string, to be reused in +repeated calls with the same string, thus using it as a cache. An +example where this is useful is code chunks that need to be indented +as function bodies, but lack the function's preamble---the string +could then include that missing preamble. +@item +A function. It is expected to be called with the start position of +the current chunk, and should return a cons cell +@w{@code{(@var{prev-start} . @var{prev-end})}} that specifies the +region of the previous code chunk, or @code{nil} if there is no previous +chunk. This is useful in literate-programming sources, where code is +split into chunks, and correct indentation needs to access previous +chunks. +@end itemize +@end table +@end defvar + +The following convenience functions should be used by major mode's +indentation engine in support of invocations as sub-modes of another +major mode. + +@defun prog-first-column +Call this function instead of using a literal value (usually, zero) of +the column number for indenting top-level program constructs. The +function's value is the column number to use for top-level constructs. +When no superior mode is in effect, this function returns zero. +@end defun + +@defun prog-widen +Call this function instead of @code{widen} to remove any restrictions +imposed by the mode's indentation engine and restore the restrictions +recorded in @code{prog-indentation-context}. This prevents the +indentation engine of a sub-mode from inadvertently operating on text +outside of the chunk it was supposed to indent, and preserves the +restriction imposed by the superior mode. When no superior mode is in +effect, this function just calls @code{widen}. +@end defun + + @node Region Indent @subsection Indenting an Entire Region diff --git a/doc/man/etags.1 b/doc/man/etags.1 index fab8901427..7cb6b6cb6a 100644 --- a/doc/man/etags.1 +++ b/doc/man/etags.1 @@ -51,7 +51,7 @@ format understood by \&. Both forms of the program understand the syntax of C, Objective C, C++, Java, Fortran, Ada, Cobol, Erlang, Forth, HTML, LaTeX, Emacs Lisp/Common Lisp, Lua, Makefile, Pascal, Perl, -PHP, PostScript, Python, Prolog, Scheme and +Ruby, PHP, PostScript, Python, Prolog, Scheme and most assembler\-like syntaxes. Both forms read the files specified on the command line, and write a tag table (defaults: \fBTAGS\fP for \fBetags\fP, \fBtags\fP for diff --git a/doc/misc/calc.texi b/doc/misc/calc.texi index 8579d0f16f..02f94469c7 100644 --- a/doc/misc/calc.texi +++ b/doc/misc/calc.texi @@ -12597,7 +12597,6 @@ in this mode. Explicit simplification commands, such as @kbd{=} or @xref{Algebraic Definitions}, for a sample use of No-Simplification mode. - @kindex m N @pindex calc-num-simplify-mode The @kbd{m N} (@code{calc-num-simplify-mode}) command turns off simplification @@ -22463,7 +22462,6 @@ Hyperbolic prefix @kbd{H} can be used similarly; the @kbd{H a s} will replace any hyperbolic functions in the formula with the appropriate combinations of @samp{sinh}s and @samp{cosh}s before simplifying. - @menu * Basic Simplifications:: * Algebraic Simplifications:: @@ -28032,7 +28030,7 @@ column of the Units Table. @noindent The definitions of many units have changed over the years. For example, the meter was originally defined in 1791 as one ten-millionth of the -distance from the equator to the north pole. In order to be more +distance from the Equator to the North Pole. In order to be more precise, the definition was adjusted several times, and now a meter is defined as the distance that light will travel in a vacuum in 1/299792458 of a second; consequently, the speed of light in a @@ -28071,13 +28069,8 @@ of the various temperature scales. The unit of volume ``liters'' can be referred to by either the lower-case @code{l} or the upper-case @code{L}. -The unit @code{A} stands for Amperes; the name @code{Ang} is used -@tex -for \AA ngstroms. -@end tex -@ifnottex -for Angstroms. -@end ifnottex +The unit @code{A} stands for amperes; the name @code{Ang} is used +for angstroms. The unit @code{pt} stands for pints; the name @code{point} stands for a typographical point, defined by @samp{72 point = 1 in}. This is @@ -28099,7 +28092,6 @@ use the @samp{tex} prefix; the unit name for a @TeX{} point will be the unit names for pint and parsec will simply be @samp{pint} and @samp{parsec} instead of @samp{pt} and @samp{pc}. - The unit @code{e} stands for the elementary (electron) unit of charge; because algebra command could mistake this for the special constant @expr{e}, Calc provides the alternate unit name @code{ech} which is @@ -28496,7 +28488,6 @@ a frequency or a midi number to scientific pitch notation. For example, @code{500 Hz} gets converted to @code{B_4 + 21.3094853649 cents} and @code{84} to @code{C_6}. - @kindex l m @pindex calc-midi @tindex midi @@ -28527,7 +28518,6 @@ notation @code{B_3 + 99.9962592773 cents}; with the default value of @code{1}, Calc converts @code{261.625 Hz} to @code{C_4}. - @node Store and Recall, Graphics, Units, Top @chapter Storing and Recalling @@ -29907,7 +29897,7 @@ The @kbd{C-y} command can be given a prefix, which will interpret the text being yanked with a different radix. If the text being yanked can be interpreted as a binary, octal, hexadecimal, or decimal number, then a prefix of @kbd{2}, @kbd{8}, @kbd{6} or @kbd{0} will have Calc -interpret the yanked text as a number in the appropriate base. For example, +interpret the yanked text as a number in the appropriate base. For example, if @samp{111} has just been killed and is yanked into Calc with a command of @kbd{C-2 C-y}, then the number @samp{7} will be put on the stack. If you use the plain prefix @kbd{C-u}, then you will be prompted for a diff --git a/doc/misc/cl.texi b/doc/misc/cl.texi index 1f38ca98c6..0ab2477b86 100644 --- a/doc/misc/cl.texi +++ b/doc/misc/cl.texi @@ -2937,7 +2937,7 @@ error if the argument is not an integer. @defun cl-digit-char-p char radix Test if @var{char} is a digit in the specified @var{radix} (default is -10). If true return the decimal value of digit @var{char} in +10). If it is, return the numerical value of digit @var{char} in @var{radix}. @end defun @@ -3027,9 +3027,10 @@ of @code{cl-truncate}. This function implements the Common Lisp @code{parse-integer} function. It parses an integer in the specified @var{radix} from the substring of @var{string} between @var{start} and @var{end}. Any -leading and trailing whitespace chars are ignored. It signals an error -if the substring between @var{start} and @var{end} cannot be parsed as -an integer unless @var{junk-allowed} is non-nil. +leading and trailing whitespace chars are ignored. The function +signals an error if the substring between @var{start} and @var{end} +cannot be parsed as an integer, unless @var{junk-allowed} is +non-@code{nil}. @end defun @node Random Numbers diff --git a/doc/misc/eudc.texi b/doc/misc/eudc.texi index 33c9a0eb3a..8d59e97b44 100644 --- a/doc/misc/eudc.texi +++ b/doc/misc/eudc.texi @@ -9,11 +9,10 @@ @c %**end of header @copying -This file documents EUDC v1.30b. +This file documents EUDC version 1.40.0. EUDC is the Emacs Unified Directory Client, a common interface to -directory servers using various protocols such as LDAP or the CCSO white -pages directory system (PH/QI) +directory servers and contact information. Copyright @copyright{} 1998, 2000--2015 Free Software Foundation, Inc. @@ -32,7 +31,7 @@ modify this GNU manual.'' @dircategory Emacs network features @direntry -* EUDC: (eudc). Emacs client for directory servers (LDAP, PH). +* EUDC: (eudc). Emacs client for directory servers (LDAP, BBDB). @end direntry @footnotestyle end @@ -41,7 +40,7 @@ modify this GNU manual.'' @title EUDC Manual @subtitle The Emacs Unified Directory Client @author by Oscar Figueiredo -@code{1.30b} +@code{1.40.0} @page @vskip 0pt plus 1fill @@ -83,8 +82,6 @@ Currently supported back-ends are: @item LDAP, Lightweight Directory Access Protocol @item -CCSO PH/QI -@item BBDB, Big Brother's Insidious Database @end itemize @@ -109,7 +106,6 @@ Interface to BBDB to let you insert server records into your own BBDB database @menu * LDAP:: What is LDAP ? -* CCSO PH/QI:: What is CCSO, PH, QI ? * BBDB:: What is BBDB ? @end menu @@ -141,30 +137,6 @@ EUDC requires external support to access LDAP directory servers (@pxref{LDAP Configuration}) -@node CCSO PH/QI -@section CCSO PH/QI - -The Central Computing Services Office (CCSO) of the University of -Illinois at Urbana Champaign created and freely distributed a -directory system that was used by many organizations in the 1990s. -The system records information about people such as their address, -phone number, email, academic information or any other details it was -configured to. Nowadays this system is not widely used. - -The system consists of two parts: a database server traditionally called -@samp{qi} and a command-line client called @samp{ph}. -@ignore -Until 2010, the code could be downloaded from -@url{http://www-dev.cites.uiuc.edu/ph/}. -@end ignore - -The original command-line @samp{ph} client that came with the -@samp{ph/qi} distribution provided additional features that are -not implemented in EUDC, like the possibility to communicate with the -server in login-mode, which made it possible to change records in the -database. - - @node BBDB @section BBDB @@ -175,14 +147,14 @@ and news readers. It is often used as an enhanced email address book. -EUDC considers BBDB as a directory server back end just like LDAP or -PH/QI servers, though BBDB has no client/server protocol and thus always -resides locally on your machine. The point in this is not to offer an +EUDC considers BBDB as a directory server back end just like LDAP, +though BBDB has no client/server protocol and thus always resides +locally on your machine. The point in this is not to offer an alternate way to query your BBDB database (BBDB itself provides much -more flexible ways to do that), but rather to offer an interface to your -local directory that is consistent with the interface to external -directories (LDAP, PH/QI). This is particularly interesting when -performing queries on multiple servers. +more flexible ways to do that), but rather to offer an interface to +your local directory that is consistent with the interface to external +LDAP directories. This is particularly interesting when performing +queries on multiple servers. EUDC also offers a means to insert results from directory queries into your own local BBDB (@pxref{Creating BBDB Records}) @@ -473,7 +445,7 @@ it will be ignored anyway. @defvar eudc-protocol The directory protocol to use to query the server. Currently supported -protocols in this version of EUDC are @code{ph}, @code{ldap} and @code{bbdb}. +protocols in this version of EUDC are @code{ldap} and @code{bbdb}. @end defvar @deffn Command eudc-set-server @@ -510,11 +482,8 @@ attributes are ignored. Default is @code{t}. Directory standards may authorize different instances of the same attribute in a record. For instance the record of a person may contain -several email fields containing different email addresses. When using -a QI directory server this is difficult to distinguish from attributes -having multi-line values such as the postal address that may contain a -line for the street and another one for the zip code and city name. In -both cases, EUDC will consider the attribute duplicated. +several email fields containing different email addresses, in which +case EUDC will consider the attribute duplicated. EUDC has several methods to deal with duplicated attributes. The available methods are: @@ -956,39 +925,6 @@ convenience functions to parse phones and addresses. @end table @end defvar -The default value of the PH-specific value of that variable is -@code{eudc-ph-bbdb-conversion-alist}: - -@lisp -((name . name) - (net . email) - (address . (eudc-bbdbify-address address "Address")) - (phone . ((eudc-bbdbify-phone phone "Phone") - (eudc-bbdbify-phone office_phone "Office Phone")))) -@end lisp - -This means that: - -@itemize @bullet -@item -the @code{name} field of the BBDB record gets its value -from the @code{name} attribute of the directory record -@item -the @code{net} field of the BBDB record gets its value -from the @code{email} attribute of the directory record -@item -the @code{address} field of the BBDB record is obtained by parsing the -@code{address} attribute of the directory record with the function -@code{eudc-bbdbify-address} -@item -two @code{phone} fields are created (when possible) in the BBDB record. -The first one has @cite{Phone} for location and its value is obtained by -parsing the @code{phone} attribute of the PH/QI record with the function -@code{eudc-bbdbify-phone}. The second one has @cite{Office Phone} for location -its value is obtained by parsing the @code{office_phone} attribute of the -PH/QI record with the function @code{eudc-bbdbify-phone}. -@end itemize - @defun eudc-bbdbify-phone phone location This is a convenience function provided for use in @code{eudc-bbdb-conversion-alist}. It parses @var{phone} into a vector diff --git a/doc/misc/ido.texi b/doc/misc/ido.texi index afc323888c..e06d248bec 100644 --- a/doc/misc/ido.texi +++ b/doc/misc/ido.texi @@ -706,7 +706,8 @@ packages. @noindent After @kbd{C-x b} (@code{ido-switch-buffer}), the buffer at the head of the list can be killed by pressing @kbd{C-k}. If the buffer needs -saving, you will be queried before the buffer is killed. +saving, you will be queried before the buffer is killed. @kbd{C-S-b} +buries the buffer at the head of the list. Likewise, after @kbd{C-x C-f}, you can delete (i.e., physically remove) the file at the head of the list with @kbd{C-k}. You will diff --git a/doc/misc/texinfo.tex b/doc/misc/texinfo.tex index f555ce3f65..34fd353a9d 100644 --- a/doc/misc/texinfo.tex +++ b/doc/misc/texinfo.tex @@ -3,7 +3,7 @@ % Load plain if necessary, i.e., if running under initex. \expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi % -\def\texinfoversion{2015-10-29.16} +\def\texinfoversion{2015-12-17.20} % % Copyright 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995, % 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, @@ -158,22 +158,10 @@ \ifx\putwordDefopt\undefined \gdef\putwordDefopt{User Option}\fi \ifx\putwordDeffunc\undefined \gdef\putwordDeffunc{Function}\fi -% Since the category of space is not known, we have to be careful. -\chardef\spacecat = 10 -\def\spaceisspace{\catcode`\ =\spacecat} +% Give the space character the catcode for a space. +\def\spaceisspace{\catcode`\ =10\relax} -% sometimes characters are active, so we need control sequences. -\chardef\ampChar = `\& -\chardef\colonChar = `\: -\chardef\commaChar = `\, \chardef\dashChar = `\- -\chardef\dotChar = `\. -\chardef\exclamChar= `\! -\chardef\hashChar = `\# -\chardef\lquoteChar= `\` -\chardef\questChar = `\? -\chardef\rquoteChar= `\' -\chardef\semiChar = `\; \chardef\slashChar = `\/ \chardef\underChar = `\_ @@ -271,11 +259,18 @@ % % Another complication is to let the user choose whether \thischapter % (\thissection) refers to the chapter (section) in effect at the top -% of a page, or that at the bottom of a page. The solution is -% described on page 260 of The TeXbook. It involves outputting two -% marks for the sectioning macros, one before the section break, and -% one after. I won't pretend I can describe this better than DEK... -% +% of a page, or that at the bottom of a page. + +% \domark is called twice inside \chapmacro, to add one +% mark before the section break, and one after. +% In the second call \prevchapterdefs is the same as \lastchapterdefs, +% and \prevsectiondefs is the same as \lastsectiondefs. +% Then if the page is not broken at the mark, some of the previous +% section appears on the page, and we can get the name of this section +% from \firstmark for @everyheadingmarks top. +% @everyheadingmarks bottom uses \botmark. +% +% See page 260 of The TeXbook. \def\domark{% \toks0=\expandafter{\lastchapterdefs}% \toks2=\expandafter{\lastsectiondefs}% @@ -283,13 +278,14 @@ \toks6=\expandafter{\prevsectiondefs}% \toks8=\expandafter{\lastcolordefs}% \mark{% - \the\toks0 \the\toks2 % 0: top marks (\last...) - \noexpand\or \the\toks4 \the\toks6 % 1: bottom marks (default, \prev...) + \the\toks0 \the\toks2 % 0: marks for @everyheadingmarks top + \noexpand\or \the\toks4 \the\toks6 % 1: for @everyheadingmarks bottom \noexpand\else \the\toks8 % 2: color marks }% } -% \gettopheadingmarks, \getbottomheadingmarks - extract needed part of mark. +% \gettopheadingmarks, \getbottomheadingmarks, +% \getcolormarks - extract needed part of mark. % % \topmark doesn't work for the very first chapter (after the title % page or the contents), so we use \firstmark there -- this gets us @@ -345,28 +341,21 @@ % values in \headline and \footline. % % This is used to check if we are on the first page of a chapter. - \ifcase0\topmark\fi - \ifx\thischapter\empty - % See comment for \gettopheadingmarks - \ifcase0\firstmark\fi - \let\curchaptername\thischaptername - \ifcase1\firstmark\fi - \let\prevchaptername\thischaptername - \else - \let\curchaptername\thischaptername - \ifcase1\topmark\fi - \let\prevchaptername\thischaptername - \fi + \ifcase1\topmark\fi + \let\prevchaptername\thischaptername + \ifcase0\firstmark\fi + \let\curchaptername\thischaptername % \ifodd\pageno \getoddheadingmarks \else \getevenheadingmarks \fi \ifodd\pageno \getoddfootingmarks \else \getevenfootingmarks \fi % \ifx\curchaptername\prevchaptername + \let\thischapterheading\thischapter \else - % If on the first page of a chapter, clear @thischapter so it - % doesn't appear in the headline, because the chapter is already - % shown in the chapter heading. - \def\thischapter{}% + % \thischapterheading is the same as \thischapter except it is blank + % for the first page of a chapter. This is to prevent the chapter name + % being shown twice. + \def\thischapterheading{}% \fi % \global\setbox\headlinebox = \vbox{\commmonheadfootline \makeheadline}% @@ -1164,8 +1153,8 @@ output) for that.)} \def\rgbDarkRed{0.50 0.09 0.12} \def\rgbBlack{0 0 0} % - % k sets the color for filling (usual text, etc.); - % K sets the color for stroking (thin rules, e.g., normal _'s). + % rg sets the color for filling (usual text, etc.); + % RG sets the color for stroking (thin rules, e.g., normal _'s). \def\pdfsetcolor#1{\pdfliteral{#1 rg #1 RG}} % % Set color, and create a mark which defines \thiscolor accordingly, @@ -1416,7 +1405,6 @@ output) for that.)} \normalturnoffactive \def\@{@}% \let\/=\empty - \let\xprocessmacroarg=\eatspaces % in case we are in a macro expansion \makevalueexpandable % do we want to go so far as to use \indexnofonts instead of just % special-casing \var here? @@ -2452,8 +2440,8 @@ end % \catcode`@=11 \def\plainfrenchspacing{% - \sfcode\dotChar =\@m \sfcode\questChar=\@m \sfcode\exclamChar=\@m - \sfcode\colonChar=\@m \sfcode\semiChar =\@m \sfcode\commaChar =\@m + \sfcode`\.=\@m \sfcode`\?=\@m \sfcode`\!=\@m + \sfcode`\:=\@m \sfcode`\;=\@m \sfcode`\,=\@m \def\endofsentencespacefactor{1000}% for @. and friends } \def\plainnonfrenchspacing{% @@ -2641,9 +2629,9 @@ end % Allow line breaks around only a few characters (only). \def\urefcatcodes{% - \catcode\ampChar=\active \catcode\dotChar=\active - \catcode\hashChar=\active \catcode\questChar=\active - \catcode\slashChar=\active + \catcode`\&=\active \catcode`\.=\active + \catcode`\#=\active \catcode`\?=\active + \catcode`\/=\active } { \urefcatcodes @@ -2852,23 +2840,24 @@ end \def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi} % \def\math{% - \tex - \mathunderscore - \let\\ = \mathbackslash - \mathactive - % make the texinfo accent commands work in math mode - \let\"=\ddot - \let\'=\acute - \let\==\bar - \let\^=\hat - \let\`=\grave - \let\u=\breve - \let\v=\check - \let\~=\tilde - \let\dotaccent=\dot - % have to provide another name for sup operator - \let\mathopsup=\sup - $\finishmath + \ifmmode\else % only go into math if not in math mode already + \tex + \mathunderscore + \let\\ = \mathbackslash + \mathactive + % make the texinfo accent commands work in math mode + \let\"=\ddot + \let\'=\acute + \let\==\bar + \let\^=\hat + \let\`=\grave + \let\u=\breve + \let\v=\check + \let\~=\tilde + \let\dotaccent=\dot + % have to provide another name for sup operator + \let\mathopsup=\sup + $\expandafter\finishmath\fi } \def\finishmath#1{#1$\endgroup} % Close the group opened by \tex. @@ -3517,7 +3506,7 @@ end \global\evenfootline={\hfil} \global\oddfootline={\hfil} \global\evenheadline={\line{\folio\hfil\thistitle}} -\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\oddheadline={\line{\thischapterheading\hfil\folio}} \global\let\contentsalignmacro = \chapoddpage } \let\contentsalignmacro = \chappager @@ -3528,8 +3517,8 @@ end \global\pageno=1 \global\evenfootline={\hfil} \global\oddfootline={\hfil} -\global\evenheadline={\line{\thischapter\hfil\folio}} -\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\evenheadline={\line{\thischapterheading\hfil\folio}} +\global\oddheadline={\line{\thischapterheading\hfil\folio}} \global\let\contentsalignmacro = \chappager } \def\HEADINGSon{\HEADINGSdouble} @@ -3540,7 +3529,7 @@ end \global\evenfootline={\hfil} \global\oddfootline={\hfil} \global\evenheadline={\line{\folio\hfil\thistitle}} -\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\oddheadline={\line{\thischapterheading\hfil\folio}} \global\let\contentsalignmacro = \chapoddpage } @@ -3548,8 +3537,8 @@ end \def\HEADINGSsinglex{% \global\evenfootline={\hfil} \global\oddfootline={\hfil} -\global\evenheadline={\line{\thischapter\hfil\folio}} -\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\evenheadline={\line{\thischapterheading\hfil\folio}} +\global\oddheadline={\line{\thischapterheading\hfil\folio}} \global\let\contentsalignmacro = \chappager } @@ -4676,16 +4665,6 @@ end \definedummyword\verb \definedummyword\w \definedummyword\xref - % - % Consider: - % @macro mkind{arg1,arg2} - % @cindex \arg2\ - % @end macro - % @mkind{foo, bar} - % The space after the comma will end up in the temporary definition - % that we make for arg2 (see \parsemargdef ff.). We want all this to be - % expanded for the sake of the index, so we end up just seeing "bar". - \let\xprocessmacroarg\eatspaces } % For testing: output @{ and @} in index sort strings as \{ and \}. @@ -5212,16 +5191,12 @@ end % from @* into spaces. The user might give these in long section % titles, for instance. \def\*{\unskip\space\ignorespaces}% - \def\entrybreak{\hfil\break}% + \def\entrybreak{\hfil\break}% An undocumented command % % A bit of stretch before each entry for the benefit of balancing % columns. \vskip 0pt plus0.5pt % - % Badness calculation for paragraph affected by - - % How much \indexdotfill is stretched, or how much \parfillskip is shrunk - % Number of lines (\linepenalty) - % % Swallow the left brace of the text (first parameter): \afterassignment\doentry \let\temp = @@ -5255,16 +5230,23 @@ end % \ifpdf \pdfgettoks#1.% - \hskip\skip\thinshrinkable\the\toksA + \bgroup\let\domark\relax + \hskip\skip\thinshrinkable\the\toksA + \egroup + % The redefinion of \domark stops marks being added in \pdflink to + % preserve coloured links across page boundaries. Otherwise the marks + % would get in the way of \lastbox in \insertindexentrybox. \else \hskip\skip\thinshrinkable #1% \fi \fi \egroup % end \boxA \ifdim\wd\boxB = 0pt - \global\setbox\entryindexbox=\box\boxA + \global\setbox\entryindexbox=\vbox{\unhbox\boxA}% \else - \global\setbox\entryindexbox=\vbox\bgroup\noindent + \global\setbox\entryindexbox=\vbox\bgroup + \prevdepth=\entrylinedepth + \noindent % We want the text of the entries to be aligned to the left, and the % page numbers to be aligned to the right. % @@ -5333,10 +5315,21 @@ end \newbox\entryindexbox \def\insertindexentrybox{% -\lineskip=.7ex plus .5ex % This comes into effect when the \vbox has a large - % height due to the paragraph in it having several - % lines. -\box\entryindexbox} + \copy\entryindexbox + % The following gets the depth of the last box. This is for even + % line spacing when entries span several lines. + \setbox\dummybox\vbox{% + \unvbox\entryindexbox + \nointerlineskip + \lastbox + \global\entrylinedepth=\prevdepth + }% + % Note that we couldn't simply \unvbox\entryindexbox followed by + % \nointerlineskip\lastbox to remove the last box and then reinstate it, + % because this resets how far the box has been \moveleft'ed to 0. \unvbox + % doesn't affect \prevdepth either. +} +\newdimen\entrylinedepth % Default is no penalty \let\entryorphanpenalty\egroup @@ -5387,16 +5380,35 @@ end % Define two-column mode, which we use to typeset indexes. % Adapted from the TeXbook, page 416, which is to say, % the manmac.tex format used to print the TeXbook itself. -\catcode`\@=11 +\catcode`\@=11 % private names \newbox\partialpage \newdimen\doublecolumnhsize \newdimen\doublecolumntopgap \doublecolumntopgap = 0pt -\newtoks\savedtopmark % Used in \begindoublecolumns +% Use inside an output routine to save \topmark and \firstmark +\def\savemarks{% + \global\savedtopmark=\expandafter{\topmark }% + \global\savedfirstmark=\expandafter{\firstmark }% +} +\newtoks\savedtopmark \newtoks\savedfirstmark +% Set \topmark and \firstmark for next time \output runs. +% Can't be run from withinside \output (because any material +% added while an output routine is active, including +% penalties, is saved for after it finishes). The page so far +% should be empty, otherwise what's on it will be thrown away. +\def\restoremarks{% + \mark{\the\savedtopmark}% + \bgroup\output = {% + \setbox\dummybox=\box\PAGE + }abc\eject\egroup + % "abc" because output routine doesn't fire for a completely empty page. + \mark{\the\savedfirstmark}% +} + \def\begindoublecolumns{\begingroup % ended by \enddoublecolumns % Grab any single-column material above us. \output = {% @@ -5417,22 +5429,15 @@ end \unvbox\PAGE \kern-\topskip \kern\baselineskip }% - % Save \topmark and \firstmark - \global\savedtopmark=\expandafter{\topmark}% - \global\savedfirstmark=\expandafter{\firstmark}% + \savemarks }% \eject % run that output routine to set \partialpage + \restoremarks % % We recover the two marks that the last output routine saved in order % to propagate the information in marks added around a chapter heading, % which could be otherwise be lost by the time the final page is output. % - \mark{\the\savedtopmark}% Only mark in page passed to following \output. - \output = {% - \setbox0=\box\PAGE % clear box 255 - }abc\eject - % - \mark{\the\savedfirstmark}% % % Use the double-column output routine for subsequent pages. \output = {\doublecolumnout}% @@ -5465,12 +5470,14 @@ end \global\advance\vsize by -1\doublecolumntopgap \vsize = 2\vsize \topskip=0pt + \global\entrylinedepth=0pt\relax } % The double-column output routine for all double-column pages except % the last, which is done by \balancecolumns. % \def\doublecolumnout{% + % \splittopskip=\topskip \splitmaxdepth=\maxdepth % Get the available space for the double columns -- the normal % (undoubled) page height minus any material left over from the @@ -5532,6 +5539,7 @@ end \output = {% % Split the last of the double-column material. Leave it on the % current page, no automatic page break. + \savemarks \balancecolumns % % If we end up splitting too much material for the current page, @@ -5545,6 +5553,8 @@ end }% \eject \endgroup % started in \begindoublecolumns + \restoremarks + \box\balancedcolumns % % \pagegoal was set to the doubled \vsize above, since we restarted % the current page. We're now back to normal single-column @@ -5552,6 +5562,8 @@ end % \endgroup where \vsize got restored). \pagegoal = \vsize } +\newbox\balancedcolumns +\setbox\balancedcolumns=\vbox{shouldnt see this}% % % Only called for the last of the double column material. \doublecolumnout % does the others. @@ -5595,7 +5607,7 @@ end \fi \fi % - \pagesofar + \global\setbox\balancedcolumns=\vbox{\pagesofar}% } \catcode`\@ = \other @@ -7612,8 +7624,7 @@ end % Argument is macro body with arguments substituted \def\scanmacro#1{% \newlinechar`\^^M - % Reduce doubled backslashes to one - \def\xprocessmacroarg{\passargtomacro\eatspaces}% + \def\xprocessmacroarg{\eatspaces}% % % Process the macro body under the current catcode regime. \scantokens{#1\texinfoc}\aftermacro% @@ -7629,6 +7640,7 @@ end % to allow macros to open or close groups themselves. } +% Used for copying and captions \def\scanexp#1{% \bgroup % Undo catcode changes of \startcontents and \printindex @@ -7733,6 +7745,7 @@ end % an argument to another Texinfo command. \def\macroargctxt{% \scanctxt + \catcode`\ =\active \catcode`\^^M=\other \catcode`\\=\active } @@ -8127,16 +8140,23 @@ end \egroup\noexpand\scanmacro{\macrobody}}% \else \ifnum\paramno<10\relax % at most 9 + % See non-recursive section below for comments \expandafter\xdef\csname\the\macname\endcsname{% - \bgroup\noexpand\macroargctxt - \noexpand\csname\the\macname @@\endcsname}% + \bgroup + \noexpand\expandafter + \noexpand\macroargctxt + \noexpand\expandafter + \expandafter\noexpand\csname\the\macname @@\endcsname}% \expandafter\xdef\csname\the\macname @@\endcsname##1{% - \expandafter\noexpand\csname\the\macname @@@\endcsname ##1,}% + \noexpand\passargtomacro + \expandafter\noexpand\csname\the\macname @@@\endcsname{##1,}}% + \expandafter\xdef\csname\the\macname @@@\endcsname##1{% + \expandafter\noexpand\csname\the\macname @@@@\endcsname ##1}% \expandafter\expandafter \expandafter\xdef \expandafter\expandafter - \csname\the\macname @@@\endcsname - \paramlist{\egroup\noexpand\scanmacro{\macrobody}}% + \csname\the\macname @@@@\endcsname\paramlist{% + \egroup\noexpand\scanmacro{\macrobody}}% \else % 10 or more \expandafter\xdef\csname\the\macname\endcsname{% \noexpand\getargvals@{\the\macname}{\argl}% @@ -8166,19 +8186,27 @@ end }% \else % at most 9 \ifnum\paramno<10\relax + % @MACNAME sets the context for reading the macro argument + % @MACNAME@@ gets the argument, processes backslashes and appends a + % comma. + % @MACNAME@@@ removes braces surrounding the argument list. + % @MACNAME@@@@ scans the macro body with arguments substituted. \expandafter\xdef\csname\the\macname\endcsname{% - \bgroup\noexpand\macroargctxt - \expandafter\noexpand\csname\the\macname @@\endcsname}% + \bgroup + \noexpand\expandafter % This \expandafter skip any spaces after the + \noexpand\macroargctxt % macro before we change the catcode of space. + \noexpand\expandafter + \expandafter\noexpand\csname\the\macname @@\endcsname}% \expandafter\xdef\csname\the\macname @@\endcsname##1{% - \expandafter\noexpand\csname\the\macname @@@\endcsname ##1,}% + \noexpand\passargtomacro + \expandafter\noexpand\csname\the\macname @@@\endcsname{##1,}}% + \expandafter\xdef\csname\the\macname @@@\endcsname##1{% + \expandafter\noexpand\csname\the\macname @@@@\endcsname ##1}% \expandafter\expandafter \expandafter\xdef \expandafter\expandafter - \csname\the\macname @@@\endcsname - \paramlist{% - \egroup - \noexpand\scanmacro{\macrobody}% - }% + \csname\the\macname @@@@\endcsname\paramlist{% + \egroup\noexpand\scanmacro{\macrobody}}% \else % 10 or more: \expandafter\xdef\csname\the\macname\endcsname{% \noexpand\getargvals@{\the\macname}{\argl}% @@ -8194,71 +8222,96 @@ end \def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}} -{\catcode`\@=0 \catcode`\\=13 -@catcode`@_=11 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +{\catcode`\@=0 \catcode`\\=13 % We need to manipulate \ so use @ as escape +@catcode`@_=11 % private names +@catcode`@!=11 % used as argument separator +% \passargtomacro#1#2 - % Call #1 with a list of tokens #2, with any doubled backslashes in #2 % compressed to one. +% +% This implementation works by expansion, and not execution (so we cannot use +% \def or similar). This reduces the risk of this failing in contexts where +% complete expansion is done with no execution (for example, in writing out to +% an auxiliary file for an index entry). +% +% State is kept in the input stream: the argument passed to +% @look_ahead, @gobble_and_check_finish and @add_segment is +% +% THE_MACRO ARG_RESULT ! {PENDING_BS} NEXT_TOKEN (... rest of input) +% +% where: +% THE_MACRO - name of the macro we want to call +% ARG_RESULT - argument list we build to pass to that macro +% PENDING_BS - either a backslash or nothing +% NEXT_TOKEN - used to look ahead in the input stream to see what's coming next + @gdef@passargtomacro#1#2{% - @def@the_macro{#1}% - @def@pending_backslash{}% - @def@finish{@finish}% - @def@arg_result{}% - @let@next_token=@relax - @add_segment#2\@finish\% -} - -% Input stream is just after a backslash. If the next token is not a -% backslash, process the rest of the argument; otherwise, remove the next -% token. -@gdef@look_ahead{% - @futurelet@next_token@look_aheadzzz} -@gdef@look_aheadzzz{% - @ifx@next_token\% - @let@next=@gobble_and_check_finish - @else - @let@next=@add_segment - @fi@next + @add_segment #1!{}@relax#2\@_finish\% } +@gdef@_finish{@_finishx} @global@let@_finishx@relax -% Double backslash found. Add a single backslash here. -@gdef@gobble_and_check_finish#1{% - @add_the_backslash - @def@pending_backslash{}% - @futurelet@next_token@add_segment +% #1 - THE_MACRO ARG_RESULT +% #2 - PENDING_BS +% #3 - NEXT_TOKEN +% #4 used to look ahead +% +% If the next token is not a backslash, process the rest of the argument; +% otherwise, remove the next token. +@gdef@look_ahead#1!#2#3#4{% + @ifx#4\% + @expandafter@gobble_and_check_finish + @else + @expandafter@add_segment + @fi#1!{#2}#4#4% } -% append a backslash to \arg_result -@gdef@add_the_backslash{% - @expandafter@gdef@expandafter@arg_result@expandafter{@arg_result\}% +% #1 - THE_MACRO ARG_RESULT +% #2 - PENDING_BS +% #3 - NEXT_TOKEN +% #4 should be a backslash, which is gobbled. +% #5 looks ahead +% +% Double backslash found. Add a single backslash, and look ahead. +@gdef@gobble_and_check_finish#1!#2#3#4#5{% + @add_segment#1\!{}#5#5% } +@gdef@is_fi{@fi} + +% #1 - THE_MACRO ARG_RESULT +% #2 - PENDING_BS +% #3 - NEXT_TOKEN +% #4 is input stream until next backslash +% % Input stream is either at the start of the argument, or just after a % backslash sequence, either a lone backslash, or a doubled backslash. -% \next_token contains the first token in the input stream: if it is \finish, -% finish; otherwise, append to \arg_result the segment of the argument up until -% the next backslash. \pending_backslash contains a backslash to represent +% NEXT_TOKEN contains the first token in the input stream: if it is \finish, +% finish; otherwise, append to ARG_RESULT the segment of the argument up until +% the next backslash. PENDING_BACKSLASH contains a backslash to represent % a backslash just before the start of the input stream that has not been -% added to \arg_result. -@gdef@add_segment#1\{% -@ifx@next_token@finish - @let@next=@call_the_macro% +% added to ARG_RESULT. +@gdef@add_segment#1!#2#3#4\{% +@ifx#3@_finish + @call_the_macro#1!% @else - @let@next=@look_ahead - % - % append to @arg_result - % token list registers might be better - @expandafter@expandafter@expandafter@gdef - @expandafter@expandafter@expandafter@arg_result - @expandafter@expandafter@expandafter{% - @expandafter@arg_result - @pending_backslash#1}% - @def@pending_backslash{\}% -@fi@next} + % append the pending backslash to the result, followed by the next segment + @expandafter@is_fi@look_ahead#1#2#4!{\}@fi + % this @fi is discarded by @look_ahead. + % we can't get rid of it with \expandafter because we don't know how + % long #4 is. +} -@gdef@call_the_macro{@expandafter@the_macro@expandafter{@arg_result}} +% #1 - THE_MACRO +% #2 - ARG_RESULT +% #3 discards the res of the conditional in @add_segment, and @is_fi ends the +% conditional. +@gdef@call_the_macro#1#2!#3@fi{@is_fi #1{#2}} } +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \braceorline MAC is used for a one-argument macro MAC. It checks % whether the next non-whitespace character is a {. It sets the context @@ -10818,11 +10871,12 @@ directory should work if nowhere else does.} % this is not a problem. \def\ifusingit#1#2{\ifdim \fontdimen1\font>0pt #1\else #2\fi} -% Turn off all special characters except @ -% (and those which the user can use as if they were ordinary). +% Set catcodes for Texinfo file + +% Active characters for printing the wanted glyph. % Most of these we simply print from the \tt font, but for some, we can % use math or other variants that look better in normal text. - +% \catcode`\"=\active \def\activedoublequote{{\tt\char34}} \let"=\activedoublequote @@ -10832,12 +10886,10 @@ directory should work if nowhere else does.} \catcode`\_=\active \def_{\ifusingtt\normalunderscore\_} -\let\realunder=_ -% Subroutine for the previous macro. \def\_{\leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em } +\let\realunder=_ -\catcode`\|=\active -\def|{{\tt\char124}} +\catcode`\|=\active \def|{{\tt\char124}} \chardef \less=`\< \catcode`\<=\active \def\activeless{{\tt \less}}\let< = \activeless @@ -3,27 +3,163 @@ Debugging GNU Emacs Copyright (C) 1985, 2000-2015 Free Software Foundation, Inc. See the end of the file for license conditions. +** Preliminaries -[People who debug Emacs on Windows using Microsoft debuggers should -read the Windows-specific section near the end of this document.] +This section can be skipped if you are already familiar with building +Emacs with debug info, configuring and starting GDB, and simple GDB +debugging techniques. -** When you debug Emacs with GDB, you should start GDB in the directory +*** Configuring Emacs for debugging + +It is best to configure and build Emacs with special options that will +make the debugging easier. Here's the configure-time options we +recommend (they are in addition to any other options you might need, +such as --prefix): + + CFLAGS='-O0 -g3' ./configure --enable-checking='yes,glyphs' --enable-check-lisp-object-type + +The CFLAGS value is important: debugging optimized code can be very +hard. (If the problem only happens with optimized code, you may need +to enable optimizations. If that happens, try using -Og first, +instead of -O2, as the former will disable some optimizations that +make debugging some code exceptionally hard.) + +Modern versions of GCC support more elaborate debug info that is +available by just using the -g3 compiler switch. Try using -gdwarf-4 +in addition to -g3, and if that fails, try -gdwarf-3. This is +especially important if you have to debug optimized code. More info +about this is available below; search for "analyze failed assertions". + +The 2 --enable-* switches are optional. They don't have any effect on +debugging with GDB, but will compile additional code that might catch +the problem you are debugging much earlier, in the form of assertion +violation. The --enable-checking option also enables additional +functionality useful for debugging display problems; see more about +this below under "Debugging Emacs redisplay problems". + +Emacs needs not be installed to be debugged, you can debug the binary +created in the 'src' directory. + +*** Configuring GDB + +When you debug Emacs with GDB, you should start GDB in the directory where the Emacs executable was made (the 'src' directory in the Emacs source tree). That directory has a .gdbinit file that defines various "user-defined" commands for debugging Emacs. (These commands are described below under "Examining Lisp object values" and "Debugging Emacs Redisplay problems".) +Starting the debugger from Emacs, via the "M-x gdb" command (described +below), when the current buffer visits one of the Emacs C source files +will automatically start GDB in the 'src' directory. + Some GDB versions by default do not automatically load .gdbinit files in the directory where you invoke GDB. With those versions of GDB, you will see a warning when GDB starts, like this: warning: File ".../src/.gdbinit" auto-loading has been declined by your `auto-load safe-path' set to "$debugdir:$datadir/auto-load". -There are several ways to overcome that difficulty, they are all -described in the node "Auto-loading safe path" in the GDB user -manual. If nothing else helps, type "source /path/to/.gdbinit RET" at -the GDB prompt, to unconditionally load the GDB init file. +The simplest way to fix this is to add the following line to your +~/.gdbinit file: + + add-auto-load-safe-path /path/to/emacs/src/.gdbinit + +There are other ways to overcome that difficulty, they are all +described in the node "Auto-loading safe path" in the GDB user manual. +If nothing else helps, type "source /path/to/.gdbinit RET" at the GDB +prompt, to unconditionally load the GDB init file. + +*** Use the Emacs GDB UI front-end + +We recommend using the GUI front-end for GDB provided by Emacs. With +it, you can start GDB by typing "M-x GDB RET". This will suggest the +default binary to debug; if you are going to start a new Emacs +process, change it as needed to point to the correct binary. +Alternatively, if you want to attach the debugger to an already +running Emacs process, change the GDB command shown in the minibuffer +to say this: + + gdb -i=mi -p PID + +where PID is the numerical process ID of the running Emacs process, +displayed by system utilities such as 'top' or 'ps' on Posix hosts and +Task Manager on MS-Windows. + +Once the debugger starts, open the additional windows provided by the +GDB UI, by typing "M-x gdb-many-windows RET". (Alternatively, click +Gud->GDB-MI->Display Other Windows" from the menu bar.) At this +point, make your frame large enough (or full-screen) such that the +windows you just opened have enough space to show the content without +horizontal scrolling. + +You can later restore your window configuration with the companion +command "M-x gdb-restore-windows RET", or by deselecting "Display +Other Windows" from the menu bar. + +*** Setting initial breakpoints + +Before you let Emacs run, you should now set breakpoints in the code +which you want to debug, so that Emacs stops there and lets GDB take +control. If the code which you want to debug is executed under some +rare conditions, or only when a certain Emacs command is manually +invoked, then just set your breakpoint there, let Emacs run, and +trigger the breakpoint by invoking that command or reproducing those +rare conditions. + +If you are less lucky, and the code in question is run very +frequently, you will have to find some way of avoiding triggering your +breakpoint when the conditions for the buggy behavior did not yet +happen. There's no single recipe for this, you will have to be +creative and study the code to see what's appropriate. Some useful +tricks for that: + + . Make your breakpoint conditional on certain buffer or string + position. For example: + + (gdb) break foo.c:1234 if PT >= 9876 + + . Set a break point in some rarely called function, then create the + conditions for the bug, call that rare function, and when GDB gets + control, set the breakpoint in the buggy code, knowing that it + will now be called when the bug happens. + + . If the bug manifests itself as an error message, set a breakpoint + in Fsignal, and when it breaks, look at the backtrace to see what + triggers the error. + +Some additional techniques are described below under "Getting control +to the debugger". + +You are now ready to start your debugging session. + +If you are starting a new Emacs session, type "run", followed by any +command-line arguments (e.g., "-Q") into the *gud-emacs* buffer and +press RET. + +If you attached the debugger to a running Emacs, type "continue" into +the *gud-emacs* buffer and press RET. + +Many variables you will encounter while debugging are Lisp objects. +These are displayed as integer values (or structures, if you used the +"--enable-check-lisp-object-type" option at configure time) that are +hard to interpret, especially if they represent long lists. You can +use the 'pp' command to display them in their Lisp form. That command +displays its output on the standard error stream (on GNU/Linux, you +can redirect that to a file using "M-x redirect-debugging-output"). +This means that if you attach GDB to a running Emacs that was invoked +from a desktop icon, chances are you will not see the output at all, +or it will wind up in an obscure place (check the documentation of +your desktop environment). + +Additional information about displaying Lisp objects can be found +under "Examining Lisp object values" below. + +The rest of this document describes specific useful techniques for +debugging Emacs; we suggest reading it in its entirety the first time +you are about to debug Emacs, then look up your specific issues +whenever you need. + +Good luck! ** When you are trying to analyze failed assertions or backtraces, it is essential to compile Emacs with flags suitable for debugging. @@ -111,6 +247,12 @@ You can also use 'pp value' to print the emacs value directly. To see the current value of a Lisp Variable, use 'pv variable'. +These commands send their output to stderr; if that is closed or +redirected to some file you don't know, you won't see their output. +This is particularly so for Emacs invoked on MS-Windows from the +desktop shortcut. On GNU/Linux, you can use the command +'redirect-debugging-output' to redirect stderr to a file. + Note: It is not a good idea to try 'pr', 'pp', or 'pv' if you know that Emacs is in deep trouble: its stack smashed (e.g., if it encountered SIGSEGV due to stack overflow), or crucial data structures, such as 'obarray', @@ -181,7 +323,7 @@ Then Emacs hits the breakpoint: [...] } -Now we can use 'pr' to print the frame parameters: +Now we can use 'pp' to print the frame parameters: (gdb) pp $->param_alist ((background-mode . light) (display-type . color) [...]) @@ -400,15 +542,16 @@ Debugging with GDB in Emacs offers some advantages over the command line (See the GDB Graphical Interface node of the Emacs manual). There are also some features available just for debugging Emacs: -1) The command gud-pp is available on the tool bar (the 'pp' icon) and +1) The command gud-print is available on the tool bar (the 'p' icon) and allows the user to print the s-expression of the variable at point, in the GUD buffer. 2) Pressing 'p' on a component of a watch expression that is a lisp object in the speedbar prints its s-expression in the GUD buffer. -3) The STOP button on the tool bar is adjusted so that it sends SIGTSTP - instead of the usual SIGINT. +3) The STOP button on the tool bar and the Signals->STOP menu-bar menu + item are adjusted so that they send SIGTSTP instead of the usual + SIGINT. 4) The command gud-pv has the global binding 'C-x C-a C-v' and prints the value of the lisp variable at point. @@ -753,91 +896,6 @@ recovering the contents of Emacs buffers from a core dump file. You might also find those commands useful for displaying the list of buffers in human-readable format from within the debugger. -** Some suggestions for debugging on MS Windows: - - (written by Marc Fleischeuers, Geoff Voelker and Andrew Innes) - -To debug Emacs with Microsoft Visual C++, you either start emacs from -the debugger or attach the debugger to a running emacs process. - -To start emacs from the debugger, you can use the file bin/debug.bat. -The Microsoft Developer studio will start and under Project, Settings, -Debug, General you can set the command-line arguments and Emacs's -startup directory. Set breakpoints (Edit, Breakpoints) at Fsignal and -other functions that you want to examine. Run the program (Build, -Start debug). Emacs will start and the debugger will take control as -soon as a breakpoint is hit. - -You can also attach the debugger to an already running Emacs process. -To do this, start up the Microsoft Developer studio and select Build, -Start debug, Attach to process. Choose the Emacs process from the -list. Send a break to the running process (Debug, Break) and you will -find that execution is halted somewhere in user32.dll. Open the stack -trace window and go up the stack to w32_msg_pump. Now you can set -breakpoints in Emacs (Edit, Breakpoints). Continue the running Emacs -process (Debug, Step out) and control will return to Emacs, until a -breakpoint is hit. - -To examine the contents of a Lisp variable, you can use the function -'debug_print'. Right-click on a variable, select QuickWatch (it has -an eyeglass symbol on its button in the toolbar), and in the text -field at the top of the window, place 'debug_print(' and ')' around -the expression. Press 'Recalculate' and the output is sent to stderr, -and to the debugger via the OutputDebugString routine. The output -sent to stderr should be displayed in the console window that was -opened when the emacs.exe executable was started. The output sent to -the debugger should be displayed in the 'Debug' pane in the Output -window. If Emacs was started from the debugger, a console window was -opened at Emacs' startup; this console window also shows the output of -'debug_print'. - -For example, start and run Emacs in the debugger until it is waiting -for user input. Then click on the 'Break' button in the debugger to -halt execution. Emacs should halt in 'ZwUserGetMessage' waiting for -an input event. Use the 'Call Stack' window to select the procedure -'w32_msp_pump' up the call stack (see below for why you have to do -this). Open the QuickWatch window and enter -"debug_print(Vexec_path)". Evaluating this expression will then print -out the contents of the Lisp variable 'exec-path'. - -If QuickWatch reports that the symbol is unknown, then check the call -stack in the 'Call Stack' window. If the selected frame in the call -stack is not an Emacs procedure, then the debugger won't recognize -Emacs symbols. Instead, select a frame that is inside an Emacs -procedure and try using 'debug_print' again. - -If QuickWatch invokes debug_print but nothing happens, then check the -thread that is selected in the debugger. If the selected thread is -not the last thread to run (the "current" thread), then it cannot be -used to execute debug_print. Use the Debug menu to select the current -thread and try using debug_print again. Note that the debugger halts -execution (e.g., due to a breakpoint) in the context of the current -thread, so this should only be a problem if you've explicitly switched -threads. - -It is also possible to keep appropriately masked and typecast Lisp -symbols in the Watch window, this is more convenient when steeping -though the code. For instance, on entering apply_lambda, you can -watch (struct Lisp_Symbol *) (0xfffffff & args[0]). - -Optimizations often confuse the MS debugger. For example, the -debugger will sometimes report wrong line numbers, e.g., when it -prints the backtrace for a crash. It is usually best to look at the -disassembly to determine exactly what code is being run--the -disassembly will probably show several source lines followed by a -block of assembler for those lines. The actual point where Emacs -crashes will be one of those source lines, but not necessarily the one -that the debugger reports. - -Another problematic area with the MS debugger is with variables that -are stored in registers: it will sometimes display wrong values for -those variables. Usually you will not be able to see any value for a -register variable, but if it is only being stored in a register -temporarily, you will see an old value for it. Again, you need to -look at the disassembly to determine which registers are being used, -and look at those registers directly, to see the actual current values -of these variables. - This file is part of GNU Emacs. @@ -114,31 +114,47 @@ and can contain escape sequences for command keys, quotes, and the like. * Changes in Emacs 25.1 -+++ -** Any file of the form .dir-locals*.el is now considered a dir-local -file, and multiple such files can be used in the same directory. See -the variable `dir-locals-file' for more information. +** Emacs can now load shared/dynamic libraries (modules). +A dynamic Emacs module is a shared library that provides additional +functionality for use in Emacs Lisp programs, just like a package +written in Emacs Lisp would. The functions `load', `require', +`load-file', etc. were extended to load such modules, as they do with +Emacs Lisp packages. The new variable `module-file-suffix' holds the +system-dependent value of the file-name extension (`.so' on Posix +hosts) of the module files. ---- -** `xref-find-definitions' and `describe-function' now display -information about mode local overrides (defined by cedet/mode-local.el -`define-overloadable-function' `define-mode-local-overrides'). +A module should export a C-callable function named +`emacs_module_init', which Emacs will call as part of the call to +`load' or `require' which loads the module. It should also export a +symbol named `plugin_is_GPL_compatible' to indicate that its code is +released under the GPL or compatible license; Emacs will refuse to +load modules that don't export such a symbol. -+++ -** New `display-buffer' action function `display-buffer-use-some-frame'. -This displays the buffer in an existing frame other than the current -frame, and allows the caller to specify a frame predicate to exclude -frames. +If a module needs to call Emacs functions, it should do so through the +API defined and documented in the header file `emacs-module.h'. Note +that any module that provides Lisp-callable functions will have to use +Emacs functions such as `fset' and `funcall', in order to register its +functions with the Emacs Lisp interpreter. -+++ -** New documentation command `describe-symbol'. -Works for functions, variables, faces, etc. It is bound to `C-h o' by -default. +Modules can create `user-ptr' Lisp objects that embed pointers to C +struct's defined by the module. This is useful for keeping around +complex data structures created by a module, to be passed back to the +module's functions. User-ptr objects can also have associated +"finalizers" -- functions to be run when the object is GC'ed; this is +useful for freeing any resources allocated for the underlying data +structure, such as memory, open file descriptors, etc. A new +predicate `user-ptrp' returns non-nil if its argument is a `user-ptr' +object. + +Loadable modules in Emacs are an experimental feature, and subject to +change in future releases. For that reason, their support is disabled +by default, and must be enabled by using the `--with-modules' option +at configure time. +++ -** New function `custom-prompt-customize-unsaved-options' checks for -unsaved customizations and prompts user to customize (if found). It -is intended for adding to 'kill-emacs-query-functions'. +** Any file of the form .dir-locals*.el is now considered a dir-local +file, and multiple such files can be used in the same directory. See +the variable `dir-locals-file' for more information. +++ ** Network security (TLS/SSL certificate validity and the like) is @@ -157,10 +173,16 @@ select-enable-primary is ineffective since the system doesn't have the equivalent of a primary selection. +++ -** terpri gets an optional arg ENSURE to conditionally output a newline. +** New option `switch-to-buffer-in-dedicated-window' allows to customize +how `switch-to-buffer' proceeds interactively when the selected window +is strongly dedicated to its buffer. +++ -** New macro `define-advice'. +** The option `even-window-heights' has been renamed to +`even-window-sizes' and now handles window widths as well. + ++++ +** terpri gets an optional arg ENSURE to conditionally output a newline. +++ ** `insert-register' now leaves point after the inserted text @@ -181,43 +203,7 @@ for use in Emacs bug reports. hiding character but the default `.' can be used by let-binding the variable `read-hide-char'. -** Emacs can now load shared/dynamic libraries (modules). -A dynamic Emacs module is a shared library that provides additional -functionality for use in Emacs Lisp programs, just like a package -written in Emacs Lisp would. The functions `load', `require', -`load-file', etc. were extended to load such modules, as they do with -Emacs Lisp packages. The new variable `module-file-suffix' holds the -system-dependent value of the file-name extension (`.so' on Posix -hosts) of the module files. - -A module should export a C-callable function named -`emacs_module_init', which Emacs will call as part of the call to -`load' or `require' which loads the module. It should also export a -symbol named `plugin_is_GPL_compatible' to indicate that its code is -released under the GPL or compatible license; Emacs will refuse to -load modules that don't export such a symbol. - -If a module needs to call Emacs functions, it should do so through the -API defined and documented in the header file `emacs-module.h'. Note -that any module that provides Lisp-callable functions will have to use -Emacs functions such as `fset' and `funcall', in order to register its -functions with the Emacs Lisp interpreter. - -Modules can create `user-ptr' Lisp objects that embed pointers to C -struct's defined by the module. This is useful for keeping around -complex data structures created by a module, to be passed back to the -module's functions. User-ptr objects can also have associated -"finalizers" -- functions to be run when the object is GC'ed; this is -useful for freeing any resources allocated for the underlying data -structure, such as memory, open file descriptors, etc. A new -predicate `user-ptr-p' returns non-nil if its argument is a `usr-ptr' -object. - -Loadable modules in Emacs are an experimental feature, and subject to -change in future releases. For that reason, their support is disabled -by default, and must be enabled by using the `--with-modules' option -at configure time. - +--- ** New input method: `tamil-dvorak'. @@ -226,26 +212,40 @@ at configure time. +++ ** M-x suggests shorthands and ignores obsolete commands for completion. -** Successive single-char deletions are collapsed in the undo-log just like -successive char insertions. This behaviour can be extended to other -commands, using the `undo-auto--amalgamate' function. +** Changes in undo + ++++ +*** Successive single-char deletions are collapsed in the undo-log just like +successive char insertions. Which commands invoke this behavior is +controlled by the new `undo-auto-amalgamate' function. See the node +"Undo" in the ELisp manual for more details. -** The heuristic used to insert `undo-boundary' after each command has changed, -so that it supports commands which potentially affect multiple buffers. ++++ +*** The heuristic used to insert `undo-boundary' after each command +has changed, so that if a command causes changes in more than just the +current buffer, Emacs now calls `undo-boundary' in every buffer +affected by the command. +++ ** New command `comment-line' bound to `C-x C-;'. -** Unicode names entered via C-x 8 RET now use substring completion by default. +** New and improved facilities for inserting Unicode characters -** C-x 8 now has shorthands for these chars: ‐ ‑ ‒ – — ― ‘ ’ “ ” † ‡ • ′ ″ +--- +*** Unicode names entered via C-x 8 RET now use substring completion by default. + ++++ +*** C-x 8 now has shorthands for these chars: ‐ ‑ ‒ – — ― ‘ ’ “ ” † ‡ • ′ ″ € № ← → ↔ − ≈ ≠ ≤ ≥. As before, you can type C-x 8 C-h to list shorthands. -** New minor mode electric-quote-mode for quoting ‘like this’ and “like this” ++++ +*** New minor mode electric-quote-mode for quoting ‘like this’ and “like this” as you type. See also the new variable ‘text-quoting-style’. +--- ** New minor mode global-eldoc-mode is enabled by default. +--- ** Emacs now supports "bracketed paste mode" when running on a terminal that supports it. This facility allows Emacs to understand pasted chunks of text as strings to be inserted, instead of interpreting each @@ -253,6 +253,7 @@ character in the pasted text as actual user input. This results in a paste experience similar to that under a window system, and significant performance improvements when pasting large amounts of text. ++++ ** Emacs now supports the latest version of the UBA. The Emacs implementation of the Unicode Bidirectional Algorithm (UBA) was updated to support all the latest additions and changes introduced @@ -261,6 +262,7 @@ This includes full support for directional isolates and the Bidirectional Parentheses Algorithm (BPA) specified by these Unicode standards. ++++ ** You can access `mouse-buffer-menu' (C-down-mouse-1) using C-f10. +++ @@ -272,6 +274,16 @@ fontification during full screen scrolling operations, giving less hesitant operation during auto-repeat of C-v, M-v at the cost of possible inaccuracies in the end position. ++++ +** New documentation command `describe-symbol'. +Works for functions, variables, faces, etc. It is bound to `C-h o' by +default. + ++++ +** New function `custom-prompt-customize-unsaved-options' checks for +unsaved customizations and prompts user to customize (if found). It +is intended for adding to 'kill-emacs-query-functions'. + * Changes in Specialized Modes and Packages in Emacs 25.1 @@ -288,50 +300,60 @@ current package keywords are recognized. Set the new option It's meant for use together with `compile': emacs -batch --eval "(checkdoc-file \"subr.el\")" ++++ ** New function `bookmark-set-no-overwrite' bound to C-x r M. It raises an error if a bookmark of that name already exists, unlike `bookmark-set' which silently updates an existing bookmark. ** JSON + --- *** `json-pretty-print' and `json-pretty-print-buffer' now maintain the ordering of object keys by default. + --- *** New commands `json-pretty-print-ordered' and `json-pretty-print-buffer-ordered' pretty prints JSON objects with object keys sorted alphabetically. -** You can recompute the VC state of a file buffer with `M-x vc-refresh-state' ++++ ** Prog mode has some support for multi-mode indentation. -See `prog-indentation-context' and `prog-widen'. +This allows better indentation support in modes that support multiple +programming languages in the same buffer, like literate programming +environments or ANTLR programs with embedded Python code. + +A major mode can provide indentation context for a sub-mode through +the `prog-indentation-context' variable. To support this, modes that +provide indentation should use `prog-widen' instead of `widen' and +`prog-first-column' instead of a literal zero. See the node +"Mode-Specific Indent" in the ELisp manual for more details. ** Prettify Symbols mode + ++++ *** Prettify Symbols mode supports custom composition predicates. By overriding the default `prettify-symbols-compose-predicate', modes can -specify in which contexts a symbol map be composed to some unicode +specify in which contexts a symbol may be displayed as some Unicode character. `prettify-symbols-default-compose-p' is the default which is suitable for most programming languages such as C or Lisp (but not (La)TeX). ++++ *** Symbols can be unprettified while point is inside them. New variable `prettify-symbols-unprettify-at-point' configures this. -** New `xterm-screen-extra-capabilities' config. - -** The `save-place' variable is replaced by a `save-place-mode'. - -** ERC +** Enhanced xterm support -*** Hide message types by network or channel. `erc-hide-list' will -hide all messages of the specified type, where `erc-network-hide-list' -and `erc-channel-hide-list' will only hide the specified message types -for the respective specified targets. - -** Midnight-mode -*** `midnight-mode' is a proper minor mode. -*** clean-buffer-*-regexps can now specify buffers via predicate functions. +--- +*** The new variable `xterm-screen-extra-capabilities' for configuring xterm. +This variable tells Emacs which advanced capabilities are available in +the xterm terminal emulator used to display Emacs text-mode frames. +The default is to check each capability, and use it if available. +(This variable was introduced in Emacs 24.1, but was not announced in +its NEWS.) -** In xterms, killing text now also sets the CLIPBOARD/PRIMARY selection +--- +*** Killing text now also sets the CLIPBOARD/PRIMARY selection in the surrounding GUI (using the OSC-52 escape sequence). This only works if your xterm supports it and enables the `allowWindowOps' options (disabled by default at least in Debian, for security reasons). @@ -340,10 +362,31 @@ Similarly, you can yank the CLIPBOARD/PRIMARY selection (using the OSC-52 escape sequence) if your xterm has the feature enabled but for that you additionally need to add `getSelection' to `xterm-extra-capabilities'. -** xterm-mouse-mode now supports mouse-tracking (if your xterm supports it). ++++ +*** `xterm-mouse-mode' now supports mouse-tracking (if your xterm supports it). + +--- +** The `save-place' variable is replaced by `save-place-mode'. + +** ERC + ++++ +*** ERC can now hide message types by network or channel. +`erc-hide-list' will hide all messages of the specified type, while +`erc-network-hide-list' and `erc-channel-hide-list' will only hide the +specified message types for the respective specified targets. + +** Midnight-mode + +--- +*** `midnight-mode' is now a proper minor mode. + +--- +*** clean-buffer-*-regexps can now specify buffers via predicate functions. ** package.el ++++ *** New "external" package status. An external package is any installed package that's not built-in and not from `package-user-dir', which usually means it's from an entry in @@ -351,14 +394,16 @@ not from `package-user-dir', which usually means it's from an entry in packages, in that they cannot be deleted through the package menu and are not considered for upgrades. -The effect, is that a user can manually place a specific version of a +The effect is that a user can manually place a specific version of a package inside `package-directory-list' and the package menu will always respect that. ++++ *** If a package is available on multiple archives and one has higher priority (as per `package-archive-priorities') only that one is listed. This can be configured with `package-menu-hide-low-priority'. ++++ *** `package-menu-toggle-hiding' now toggles the hiding of packages. This includes the above-mentioned low-priority packages, as well as available packages whose version is lower than the currently installed @@ -366,34 +411,43 @@ version (which were previously impossible to display). This allows users to downgrade a package if a lower version is available. +--- *** When filtering the package menu, keywords starting with "arc:" or "status:" represent package archive or status, respectively, instead of actual keywords. +--- *** Most functions which involve downloading information now take an ASYNC argument. If it is non-nil, package.el performs the download(s) asynchronously. +--- *** New variable `package-menu-async' controls whether the package-menu uses asynchronous downloads. +--- *** `package-install-from-buffer' and `package-install-file' work on directories. This follows the same rules as installing from a .tar file, except the -pkg file is optional. +--- *** Packages which are dependencies of other packages cannot be deleted. The FORCE argument to `package-delete' overrides this. +--- *** New custom variable `package-selected-packages' tracks packages which were installed by the user (as opposed to installed as dependencies). This variable can also be manually customized. +--- *** New command `package-install-user-selected-packages' installs all packages from `package-selected-packages' which are currently missing. +--- *** New command `package-autoremove' removes all packages which were installed strictly as dependencies but are no longer needed. ++++ ** Shell When you invoke `shell' interactively, the *shell* buffer will now @@ -420,20 +474,28 @@ If you need your objects to be named, do it by inheriting from `eieio-named'. *** `constructor' is now an obsolete alias for `make-instance'. ** ido + ++++ *** New command `ido-bury-buffer-at-head' bound to C-S-b Bury the buffer at the head of `ido-matches', analogous to how C-k kills the buffer at head. + +--- *** A prefix argument to `ido-restrict-to-matches' will reverse its meaning, and the list is restricted to those elements that do not match the current input. ** Minibuffer -*** You can use <up> and <down> keys to move point in the multi-line -minibuffer just as in an ordinary buffer. Only when point moves over ++++ +*** You can use <UP> and <DOWN> arrow keys to move through history by lines. +The new commands `next-line-or-history-element' and +`previous-line-or-history-element', bound to <UP> and <DOWN> in the +minibuffer, allow by-line movement through minibuffer history, +similarly to an ordinary buffer. Only when point moves over the bottom/top of the minibuffer it goes to the next/previous history -element. The new commands bound to <up> and <down> in the minibuffer: -`next-line-or-history-element' and `previous-line-or-history-element'. +element. `M-p' and `M-n' still move directly to previous/next history +item as before. ** Search and Replace @@ -487,8 +549,16 @@ this you can tell Edebug not to stop at the start of the first instrumented function. ** ElDoc + ++++ *** New minor mode `global-eldoc-mode' +It is turned on by default, and affects `*scratch*' and other buffers +whose major mode supports Emacs Lisp. + +--- *** `eldoc-documentation-function' now defaults to `ignore' + +--- *** `describe-char-eldoc' displays information about character at point, and can be used as a default value of `eldoc-documentation-function'. It is useful when, for example, one needs to distinguish various spaces (e.g. ] [, @@ -544,31 +614,45 @@ invalid certificates are marked in red. ** Message mode +--- *** text/html messages that contain inline image parts will be transformed into multipart/related messages before sending. -** pcase -*** New UPatterns `quote', `app', `cl-struct', and `eieio'. -*** New UPatterns can be defined with `pcase-defmacro'. +++ -*** New vector QPattern. +** In Show Paren Mode, a parenthesis can be highlighted when point +stands inside it, and certain parens can be highlighted when point is +at BOL or EOL, or in whitespace there. To enable these, customize, +respectively, `show-paren-when-point-inside-paren' or +`show-paren-when-point-in-periphery'. ** Lisp mode *** Strings after `:documentation' are highlighted as docstrings. ** Rectangle editing + ++++ *** Rectangle Mark mode can have corners past EOL or in the middle of a TAB. + ++++ *** C-x C-x in rectangle-mark-mode now cycles through the four corners. *** `string-rectangle' provides on-the-fly preview of the result. -** New font-lock functions font-lock-ensure and font-lock-flush, which -should be used instead of font-lock-fontify-buffer when called from Elisp. ++++ +** New font-lock functions `font-lock-ensure' and `font-lock-flush'. +These should be used in preference to `font-lock-fontify-buffer' when +called from Lisp. + +--- +** Macro `minibuffer-with-setup-hook' can optionally append a function +to `minibuffer-setup-hook'. -** Macro `minibuffer-with-setup-hook' takes (:append FUN) to mean -appending FUN to `minibuffer-setup-hook'. +If the first argument of the macro is of the form `(:append FUN)', +then FUN will be appended to `minibuffer-setup-hook', instead of +prepending it. ** cl-lib -*** New functions cl-fresh-line, cl-digit-char-p and cl-parse-integer. ++++ +*** New functions `cl-fresh-line', `cl-digit-char-p', and `cl-parse-integer'. ** Calendar and diary @@ -616,11 +700,18 @@ The remainder were: ** New js.el option `js-indent-first-init'. +** Info + --- -** `Info-fontify-maximum-menu-size' can be t for no limit. +** Info mode now displays symbol names in fixed-pitch font. +If you want to get the old behavior back, customize the `Info-quoted' +face to use the same definitions as the default face. + +--- +*** `Info-fontify-maximum-menu-size' can be t for no limit. +++ -** `info-display-manual' can now be given a prefix argument which (any +*** `info-display-manual' can now be given a prefix argument which (any non-nil value) directs the command to limit the completion alternatives to currently visited manuals. @@ -629,9 +720,11 @@ alternatives to currently visited manuals. ** Rmail -*** The Rmail commands d, C-d and u take optional repeat counts to delete or -undelete multiple messages. ++++ +*** The Rmail commands `d', `C-d' and `u' take optional repeat counts +to delete or undelete multiple messages. ++++ *** Rmail can now render HTML mail messages if your Emacs was built with libxml2 or if you have the Lynx browser installed. By default, Rmail will display the HTML version of a mail message that has both HTML and @@ -709,6 +802,12 @@ Implemented for Bzr, Git, Hg. As part of this change, the pre-existing *** The new command vc-region-history shows the log+diff of the active region. ++++ +*** You can refresh the VC state of a file buffer with `M-x vc-refresh-state'. +This command is useful when you perform version control commands +outside Emacs (e.g., from the shell prompt), or if you switch the VC +back-end for the buffer's file, or remove it from version control. + *** New option `vc-annotate-background-mode' controls whether the color range from `vc-annotate-color-map' is applied to the background or to the foreground. @@ -779,6 +878,11 @@ easier binding, which is now unoccupied (`M-,'). alias for a private variable. `xref-push-marker-stack' and `xref-pop-marker-stack' should be used to mutate it instead. +--- +*** `xref-find-definitions' and `describe-function' now display +information about mode local overrides (defined by cedet/mode-local.el +`define-overloadable-function' `define-mode-local-overrides'). + ** etags As a result of the above, these commands are now obsolete: `find-tag-other-window', `find-tag-other-frame', `find-tag-regexp', @@ -821,6 +925,8 @@ command line's password prompt. EUDC's BBDB backend now supports BBDB 3. +EUDC's PH backend (eudcb-ph.el) is obsolete. + ** Eshell +++ @@ -1076,6 +1182,12 @@ that happen, `unhandled-file-name-directory' now defaults to calling * Lisp Changes in Emacs 25.1 +** pcase +*** New UPatterns `quote', `app', `cl-struct', `eieio', `seq', and `map'. +*** New UPatterns can be defined with `pcase-defmacro'. ++++ +*** New vector QPattern. + ** syntax-propertize is now automatically called on-demand during forward parsing functions like `forward-sexp'. @@ -1118,6 +1230,9 @@ Area. The output is still logged to the *Messages* buffer. ** A new text property `inhibit-read-only' can be used in read-only buffers to allow certain parts of the text to be writable. ++++ +** New macro `define-advice'. + ** `read-buffer' takes a new `predicate' argument. ** Emacs Lisp now supports generators. @@ -1402,25 +1517,23 @@ windows without "fixing" it. It's supported by `fit-window-to-buffer', `temp-buffer-resize-mode' and `display-buffer'. +++ +** New `display-buffer' action function `display-buffer-use-some-frame'. +This displays the buffer in an existing frame other than the current +frame, and allows the caller to specify a frame predicate to exclude +frames. + ++++ ** New minor mode `window-divider-mode' and options `window-divider-default-places', `window-divider-default-bottom-width' and `window-divider-default-right-width'. -+++ -** New option `switch-to-buffer-in-dedicated-window' allows to customize -how `switch-to-buffer' proceeds interactively when the selected window -is strongly dedicated to its buffer. - -+++ -** The option `even-window-heights' has been renamed to -`even-window-sizes' and now handles window widths as well. - ** Tearoff menus and detachable toolbars for Gtk+ has been removed. Those features have been deprecated in Gtk+ for a long time. -** Miscellaneous +** Etags *** etags no longer qualifies class members by default. + By default, `etags' will not qualify class members for C-like object-oriented languages with their class names and namespaces, and will remove qualifications used explicitly in the code from the tag @@ -1434,6 +1547,16 @@ using -Q might make some class members become "unknown" to `M-.' (`xref-find-definitions'); if so, you can use `C-u M-.' to specify the qualified names by hand. +*** New language Ruby + +Names of modules, classes, methods, and functions are tagged. +Overloaded operators are also tagged. + +*** Improved support for Lua + +Etags now tags functions even if the "function" keyword follows some +whitespace at line beginning. + * Changes in Emacs 25.1 on Non-Free Operating Systems diff --git a/etc/tutorials/TUTORIAL.it b/etc/tutorials/TUTORIAL.it index 300fd223e0..1eb2573955 100644 --- a/etc/tutorials/TUTORIAL.it +++ b/etc/tutorials/TUTORIAL.it @@ -1,36 +1,38 @@ Esercitazione di Emacs. Condizioni d'uso alla fine del file. I comandi di Emacs comportano generalmente l'uso del tasto CONTROL (a -volte indicato con CTRL o CTL) o del tasto META (a volte indicato con EDIT -o ALT). Piuttosto che indicarli per esteso ogni volta, useremo le -seguenti abbreviazioni: - - C-<car> significa che bisogna tenere abbassato il tasto CONTROL mentre si - preme il carattere <car>. Quindi C-f significa: tieni premuto - CONTROL e batti f. - - M-<car> significa che bisogna tenere abbassato il tasto META o EDIT o ALT - mentre si preme il carattere <car>. Se non ci sono tasti META, - EDIT o ALT, al loro posto si può premere e poi rilasciare il - tasto ESC e quindi premere <car>. Useremo <ESC> per indicare il - tasto ESC. +volte indicato con CTRL o CTL) o del tasto META (a volte indicato con +EDIT o ALT). Piuttosto che indicarli per esteso ogni volta, useremo +le seguenti abbreviazioni: + + C-<car> significa che bisogna tenere abbassato il tasto CONTROL + mentre si preme il carattere <car>. Quindi C-f significa: + tieni premuto CONTROL e batti f. + M-<car> significa che bisogna tenere abbassato il tasto META o EDIT + o ALT mentre si preme il carattere <car>. Se non ci sono + tasti META, EDIT o ALT, al loro posto si può premere e poi + rilasciare il tasto ESC e quindi premere <car>. Useremo + <ESC> per indicare il tasto ESC. Nota importante: per chiudere una sessione di lavoro di Emacs usa C-x -C-c. (Due caratteri.) I caratteri ">>" posti al margine sinistro -indicano le direttive per provare a usare un comando. Per esempio: +C-c (due caratteri). Per annullare un comando inserito parzialmente +usa C-g. I caratteri “>>” posti al margine sinistro indicano le +direttive per provare a usare un comando. Per esempio: <<Blank lines inserted here by startup of help-with-tutorial>> ->> Adesso premi C-v (Vedi schermata successiva) per spostarti - alla prossima schermata. (Vai avanti, tieni premuto il tasto - CONTROL mentre premi v). D'ora in poi dovrai fare così ogni volta - che finisci di leggere lo schermo. +[Spaziatura inserita a scopo didattico. Il testo continua sotto] +>> Adesso premi C-v (vedi schermata successiva) per spostarti alla + prossima schermata (vai avanti, tieni premuto il tasto + CONTROL mentre premi v). D'ora in poi dovrai fare così ogni + volta che finisci di leggere la schermata. -Si noti che le ultime due righe di ogni schermata appaiono in cima alla -schermata successiva, favorendo così la continuità di lettura. +Si noti che le ultime due righe di ogni schermata appaiono in cima +alla schermata successiva, favorendo così la continuità di lettura. -La prima cosa che bisogna imparare è come raggiungere un certo punto del -testo. Sai già come andare avanti di una schermata, con C-v. Per -andare indietro di una schermata, premi M-v (tieni premuto il tasto META -e poi premi v, oppure usa <ESC>v se non c'è un tasto META, EDIT o ALT). +La prima cosa che bisogna imparare è come raggiungere un certo punto +del testo. Sai già come andare avanti di una schermata, con C-v. Per +andare indietro di una schermata, premi M-v (tieni premuto il tasto +META e poi premi v, oppure usa <ESC>v se non c'è un tasto META, EDIT o +ALT). >> Ora prova: premi M-v e quindi C-v alcune volte. @@ -38,213 +40,221 @@ e poi premi v, oppure usa <ESC>v se non c'è un tasto META, EDIT o ALT). * SOMMARIO ---------- -I comandi seguenti sono utili per visualizzare le varie parti del testo: +I comandi seguenti sono utili per visualizzare le schermate: - C-v Vai avanti di una schermata - M-v Vai indietro di una schermata - C-l Cancella lo schermo e riscrivi tutto il testo, muovendo - il testo che si trova vicino al cursore al centro dello - schermo. (Il tasto è CONTROL-L, non CONTROL-1.) + C-v Vai avanti di una schermata + M-v Vai indietro di una schermata + C-l Cancella lo schermo e riscrivi tutto il testo, + muovendo il testo che si trova vicino al cursore al + centro dello schermo. (Il tasto è CONTROL-L, + non CONTROL-1.) >> Trova il cursore, osserva quale parte di testo gli è vicina. Premi C-l. Trova di nuovo il cursore e osserva che si trova sullo stesso - punto del testo. + punto del testo, ma ora è al centro della schermata. Se premi C-l + di nuovo, il testo verrà posizionato in cima allo schermo. + Premendo nuovamente C-l verrà posizionato in fondo. + +Puoi anche usare i tasti PagSu (Pag ↑) o PagGiù (Pag ↓) per passare +alle schermate precedenti o successive, se sono presenti sul tuo +terminale, ma C-v e M-v consentono una editazione più efficiente. -* CONTROLLO DEL CURSORE ------------------------ +* CONTROLLO DI BASE DEL CURSORE +------------------------------- -Spostarsi da una schermata all'altra è utile, ma come ci si può spostare -fino ad un certo preciso punto del testo? +Spostarsi da una schermata all'altra è utile, ma come ci si può +spostare fino ad un certo preciso punto del testo? -Ci sono diversi modi per farlo. Il più elementare consiste nell'usare i -comandi C-p, C-b, C-f, C-n. Ognuno di essi muove il cursore di una riga o -di una colonna in una data direzione sullo schermo. La tabella seguente -mostra le direzioni in cui operano questi quattro comandi: +Ci sono diversi modi per farlo. Puoi usare i tasti con le frecce, ma +è più efficiente tenere le mani nella posizione standard e utilizzare +i comandi C-p, C-b, C-f e C-n. Questi caratteri sono equivalenti ai +quattro tasti con le frecce, in questo modo: - Riga precedente, C-p - : - : + Riga precedente, C-p + : + : Indietro, C-b .... Posizione attuale cursore .... Avanti, C-f - : - : + : + : Riga successiva, C-n ->> Sposta il cursore sulla riga centrale del diagramma qui sopra usando - C-n o C-p. Poi usa C-l per portare il diagramma al centro dello - schermo. +>> Sposta il cursore sulla riga centrale del diagramma qui sopra + usando C-n o C-p. Poi usa C-l per portare il diagramma al centro + dello schermo. Le quattro lettere dei comandi sono mnemoniche in inglese: P per -precedente (previous), N per successivo (next), B per indietro (backward) -e F per avanti (forward). Questi sono tutti i comandi elementari per -posizionare il cursore, li userai IN CONTINUAZIONE e conviene perciò -impararli subito. +precedente (previous), N per successivo (next), B per indietro +(backward) e F per avanti (forward). Userai questi comandi elementari +in continuazione. >> Usa alcuni C-n per portare il cursore su questa riga. + >> Muovi il cursore sulla riga con C-f e poi in alto con C-p. Osserva l'effetto di un C-p quando il cursore si trova a metà della riga. -Ogni riga di testo termina con un carattere Newline, che serve a separarla -dalla successiva. È bene che l'ultima riga del tuo file termini con un -carattere Newline, benché Emacs non lo richieda. +Ogni riga di testo termina con un carattere Newline (“a capo”), che +serve a separarla dalla successiva. (Di solito l'ultima riga di un +file termina con un carattere Newline, ma Emacs non lo richiede.) ->> Prova a usare C-b all'inizio di una riga. Sposterà il cursore - alla fine della precedente. Questo avviene perché il cursore ha +>> Prova a usare C-b all'inizio di una riga. Sposterà il cursore alla + fine della precedente. Questo avviene perché il cursore ha superato all'indietro il carattere Newline. -C-f sposta il cursore avanti attravero il carattere Newline proprio come -C-b. +C-f sposta il cursore avanti attraverso il carattere Newline proprio +come C-b. ->> Premi alcune volte C-b per vedere dove si trova il cursore. Poi usa - C-f per tornare alla fine della riga. Usa quindi C-f per andare alla - riga successiva. +>> Premi alcune volte C-b per vedere dove si trova il cursore. Poi + usa C-f per tornare alla fine della riga. Usa quindi C-f per + andare alla riga successiva. -Quando ci si sposta oltre l'inizio o la fine della schermata, il testo che -si trova oltre si sposta sullo schermo, ottenendo uno "scorrimento" -(scrolling). In questo modo Emacs posiziona il cursore sulla parte di -testo desiderata senza doverlo portare fuori dallo schermo visibile. +Quando ci si sposta oltre l'inizio o la fine della schermata, il testo +che si trova oltre si sposta sullo schermo, ottenendo uno +“scorrimento” (scrolling). Questo consente a Emacs di spostare il +cursore sulla parte di testo desiderata mantenendolo all'interno della +schermata. ->> Prova a muovere il cursore al di là della fine dello schermo con C-n e - osserva cosa succede. +>> Prova a muovere il cursore al di là della fine dello schermo con + C-n e osserva cosa succede. -Se lo spostamento di un solo carattere alla volta è troppo lento allora ci -si può muovere di un'intera parola alla volta. M-f (META-f) e M-b -spostano il cursore rispettivamente in avanti e indietro di una parola. +Se lo spostamento di un solo carattere alla volta è troppo lento +allora ci si può muovere di un'intera parola alla volta. M-f (META-f) +e M-b spostano il cursore rispettivamente in avanti e indietro di una +parola. >> Prova alcune volte M-f e M-b. -Quando il cursore è a metà di una parola, M-f lo sposta alla fine della -stessa. Quando è sullo spazio bianco tra due parole, M-f lo sposta alla -fine della parola successiva. M-b funziona in modo simile ma in direzione -opposta. +Quando il cursore è a metà di una parola, M-f lo sposta alla fine +della stessa. Quando è sullo spazio bianco tra due parole, M-f lo +sposta alla fine della parola successiva. M-b funziona in modo simile +ma in direzione opposta. ->> Ora prova M-f e M-b alcune volte, alternandoli con C-f e C-b così da - poter osservare l'azione di M-f e M-b da vari punti tra le parole e - sulle stesse. +>> Ora prova M-f e M-b alcune volte, alternandoli con C-f e C-b così + da poter osservare l'azione di M-f e M-b da vari punti tra le + parole e sulle stesse. -Osserva il parallelo tra C-f e C-b da una parte e M-f e M-b dall'altra. -Molto spesso i caratteri con Meta sono usati per operazioni relative alle -unità definite dal linguaggio (parole, frasi, paragrafi), mentre i -caratteri con Control operano su unità base indipendenti da ciò che si -scrive (caratteri, righe, ecc.). +Osserva il parallelo tra C-f e C-b da una parte e M-f e M-b +dall'altra. Molto spesso i caratteri con Meta sono usati per +operazioni relative alle unità definite dal linguaggio (parole, frasi, +paragrafi), mentre i caratteri con Control operano su unità base +indipendenti da ciò che si scrive (caratteri, righe, ecc.). Questo parallelo funziona anche tra righe e frasi: C-a e C-e spostano -all'inizio o alla fine di una riga, e M-a e M-e all'inizio o alla fine di -una frase. +all'inizio o alla fine di una riga, mentre M-a e M-e all'inizio o alla +fine di una frase. >> Prova due C-a e poi due C-e. Prova due M-a e poi due M-e. Osserva come un C-a ripetuto non abbia effetto, mentre M-a ripetuti -continuano a spostare il cursore all'inizio di frasi precendenti. Sebbene -questi due ultimi comandi non siano perfettamente analoghi, riteniamo che -il loro comportamento sia ragionevole. +continuano a spostare il cursore all'inizio di frasi precedenti. +Sebbene questi due ultimi comandi non siano perfettamente analoghi, +riteniamo che il loro comportamento sia ragionevole. -La posizione del cursore nel testo è anche chiamata "punto". Per meglio -dire, il cursore mostra sullo schermo dove si trova, al momento, il punto -nel testo. +La posizione del cursore nel testo è anche chiamata “punto”. Per +meglio dire, il cursore mostra sullo schermo dove si trova, al +momento, il punto nel testo. -Ecco un sommario delle più semplici operazioni di spostamento del cursore, -compresi i comandi di spostamento di parola in parola o di frase in frase: +Ecco un sommario delle più semplici operazioni di spostamento del +cursore, compresi i comandi di spostamento di parola in parola o di +frase in frase: - C-f Sposta avanti di un carattere - C-b Sposta indietro di un carattere + C-f Sposta avanti di un carattere + C-b Sposta indietro di un carattere - M-f Sposta avanti di una parola - M-b Sposta indietro di una parola + M-f Sposta avanti di una parola + M-b Sposta indietro di una parola - C-n Sposta alla riga successiva - C-p Sposta alla riga precedente + C-n Sposta alla riga successiva + C-p Sposta alla riga precedente - C-a Sposta all'inizio della riga - C-e Sposta alla fine della riga + C-a Sposta all'inizio della riga + C-e Sposta alla fine della riga - M-a Sposta all'inizio della frase - M-e Sposta alla fine della frase + M-a Sposta all'inizio della frase + M-e Sposta alla fine della frase ->> Prova tutti questi comandi alcune volte per fare pratica. Questi sono - i comandi più usati. +>> Prova tutti questi comandi alcune volte per fare pratica. + Questi sono i comandi più usati. Altri due importanti comandi di spostamento del cursore sono M-< (META Minore-di), che sposta all'inizio dell'intero testo, e M-> (META Maggiore-di), che sposta alla fine dell'intero testo. -Su molte tastiere il carattere ">" si raggiunge premendo il tasto SHIFT. -Su queste tastiere bisogna usare il tasto SHIFT assieme a quello META; -senza il tasto SHIFT si otterrebbe un carattere diverso. +Su molte tastiere il carattere “<” trova sopra la virgola, quindi è +necessario tenere premuto il tasto shift (⇑) per ottenerlo. Su questi +terminali dovrai usare il tasto shift per ottenere M-<, perché +altrimenti digiteresti M-virgola. >> Prova M-< adesso per andare all'inizio del tutorial. Poi usa C-v ripetutamente per tornare a questo punto. ->> Prova M-> adesso, per andare alla fine del tutorial. Quindi usa M-v - ripetutamente per tornare a questo punto. -Il cursore si può anche spostare con i tasti freccia, se il terminale li -ha. Noi raccomandiamo di imparare C-b, C-f, C-n e C-p per tre motivi: -primo, funzionano su tutti i terminali; secondo, una volta acquisita -pratica nell'uso di Emacs, ci si accorgerà che raggiungere questi -caratteri di controllo è più rapido che usare i tasti freccia perché non -bisogna spostare le mani dalla posizione di scrittura sulla tastiera; -terzo, una volta acquisita l'abitudine ad usare questi comandi con il -carattere Control, si può allo stesso modo imparare ad usare altri comandi -avanzati di spostamento del cursore. - -Molti comandi di Emacs accettano un argomento numerico che spesso serve a -conteggiare per quante volte vanno ripetuti. Il modo in cui si può -fornire ad un comando il numero di ripetizioni è il seguente: si usa C-u e -quindi si indicano le cifre prima di impartire il comando stesso. Se -esiste un tasto META (o EDIT o ALT) c'è un modo alternativo: si battono le -cifre tenendo premuto il tasto META. Noi consigliamo di imparare il -metodo con C-u perché funziona su tutti i terminali. L'argomento numerico -è anche chiamato "argomento prefisso", perché viene indicato prima del -comando a cui si riferisce. +>> Prova M-> adesso, per andare alla fine del tutorial. Quindi usa + M-v ripetutamente per tornare a questo punto. + +Il cursore si può anche spostare con i tasti freccia, se il terminale +li ha. Noi raccomandiamo di imparare C-b, C-f, C-n e C-p per tre +motivi: primo, funzionano su tutti i terminali; secondo, una volta +acquisita pratica nell'uso di Emacs, ci si accorgerà che raggiungere +questi caratteri di controllo è più rapido che usare i tasti freccia +(perché non bisogna spostare le mani dalla posizione di scrittura +sulla tastiera); terzo, una volta acquisita l'abitudine ad usare +questi comandi con il carattere Control, si può allo stesso modo +imparare ad usare altri comandi avanzati di spostamento del cursore. + +Molti comandi di Emacs accettano un argomento numerico che spesso +serve a conteggiare per quante volte vanno ripetuti. Il modo in cui +si può fornire ad un comando il numero di ripetizioni è il seguente: +si usa C-u e quindi si indicano le cifre prima di impartire il comando +stesso. Se esiste un tasto META (o EDIT o ALT) c'è un modo +alternativo: si battono le cifre tenendo premuto il tasto META. Noi +consigliamo di imparare il metodo con C-u perché funziona su tutti i +terminali. L'argomento numerico è anche chiamato “argomento +prefisso”, perché viene indicato prima del comando a cui si riferisce. Per esempio, C-u 8 C-f sposta il cursore in avanti di otto caratteri. ->> Prova ad usare C-n, o C-p, con un argomento numerico per spostare il - cursore su una riga vicina a questa con un solo comando. +>> Prova ad usare C-n, o C-p, con un argomento numerico per spostare + il cursore su una riga vicina a questa con un solo comando. -La maggior parte dei comandi usa l'argomento numerico come numero delle -ripetizioni da effettuare, tuttavia alcuni lo usano in modo diverso. -Altri comandi (ma nessuno di quelli imparati fino ad ora) lo usano come -indicatore di alternativa: la presenza di un argomento prefisso, -indipendentemente dal suo valore, modifica il comportamento del comando. +La maggior parte dei comandi usa l'argomento numerico come numero +delle ripetizioni da effettuare, tuttavia alcuni lo usano in modo +diverso. Altri comandi (ma nessuno di quelli imparati fino ad ora) lo +usano come indicatore di alternativa: la presenza di un argomento +prefisso, indipendentemente dal suo valore, modifica il comportamento +del comando. -C-v e M-v sono un'altra eccezione. Quando gli si fornisce un argomento -spostano l'area di testo visualizzato in alto o in basso del numero di -righe indicato invece che del numero di schermate. Per esempio, C-u 8 C-v -fa scorrere lo schermo di 8 righe. +C-v e M-v sono un'altra eccezione. Quando gli si fornisce un +argomento spostano l'area di testo visualizzato in alto o in basso del +numero di righe indicato invece che del numero di schermate. Per +esempio, C-u 8 C-v fa scorrere lo schermo di 8 righe. >> Ora prova con C-u 8 C-v. -La schermata si sposta di 8 righe verso l'alto. Se vuoi tornare di nuovo -in basso puoi usare un argomento numerico con M-v. +La schermata si sposta di 8 righe verso l'alto. Se vuoi tornare di +nuovo in basso puoi usare un argomento numerico con M-v. -Quando si usa un sistema a finestre, come X11 o MS-Windows, ci dovrebbe +Quando si usa un sistema a finestre, come X o MS-Windows, ci dovrebbe essere un'area rettangolare allungata chiamata barra di scorrimento a un lato della finestra di Emacs. Si può far scorrere il testo con un click del mouse nella barra di scorrimento. ->> Prova a premere il pulsante centrale del mouse sopra all'area - evidenziata nella barra di scorrimento. Verrà visualizzata una parte - del testo, più verso l'inizio o la fine, a seconda del punto della - barra che il puntatore indicava mentre premevi il pulsante del mouse. ->> Prova a spostare il mouse in su e in giù mentre tieni premuto il - pulsante centrale. Osserva come il testo scorre in su e in giù mentre - muovi il mouse. +Se il tuo mouse dispone di una rotellina, puoi usare anche quella per +far scorrere il testo. * QUANDO EMACS SI BLOCCA ------------------------ -Se Emacs smette di rispondere ai comandi può essere fermato in modo sicuro -premendo C-g. Si può usare C-g per fermare un comando che sta impiegando -troppo tempo per l'esecuzione. +Se Emacs smette di rispondere ai comandi può essere fermato in modo +sicuro premendo C-g. Si può usare C-g per fermare un comando che sta +impiegando troppo tempo per l'esecuzione. -Si può anche usare C-g per annullare un argomento numerico o l'esecuzione -di un comando che non si vuole più portare a termine. +Si può anche usare C-g per annullare un argomento numerico o +l'esecuzione di un comando che non si vuole più portare a termine. ->> Batti C-u 100 per indicare un argomento numerico di 100, quindi premi - C-g. Ora premi C-f. Il cursore si sposta in avanti di un solo - carattere perché hai annullato l'argomento numerico con C-g. +>> Batti C-u 100 per indicare un argomento numerico di 100, quindi + premi C-g. Ora premi C-f. Il cursore si sposta in avanti di un + solo carattere perché hai annullato l'argomento numerico con C-g. Se hai premuto <ESC> per errore puoi annullare con C-g. @@ -252,170 +262,194 @@ Se hai premuto <ESC> per errore puoi annullare con C-g. * COMANDI DISATTIVATI --------------------- -Alcuni comandi di Emacs sono "disattivati", così da evitare che utenti +Alcuni comandi di Emacs sono “disattivati”, così da evitare che utenti principianti possano usarli per errore. -Se si inserisce uno dei comandi disattivati Emacs mostra un messaggio in -cui dice quale sia il comando e chiede se davvero si vuole procedere con -l'esecuzione. +Se si inserisce uno dei comandi disattivati Emacs mostra un messaggio +in cui dice quale sia il comando e chiede se davvero si vuole +procedere con l'esecuzione. Se effettivamente si vuole provare il comando bisogna premere la barra -spaziatrice come risposta a questa domanda. Normalmente, se non si vuole -eseguire il comando disattivato, bisogna rispondere alla domanda con "n". +spaziatrice come risposta a questa domanda. Normalmente, se non si +vuole eseguire il comando disattivato, bisogna rispondere alla domanda +con "n". ->> Prova C-x C-l (che è un comando disattivato), poi rispondi con "n" alla - domanda. +>> Prova C-x C-l (che è un comando disattivato), poi rispondi con “n” + alla domanda. * FINESTRE ---------- -Emacs può avere diverse finestre, ognuna contenente il suo testo. +Emacs può avere diverse “finestre”, ognuna contenente il suo testo. Spiegheremo dopo come usare finestre multiple. Adesso ci occupiamo di -come eliminare le finestre in più e tornare alla scrittura con una sola -finestra. È semplice: +come eliminare le finestre in più e tornare alla scrittura con una +sola finestra. È semplice: - C-x 1 Una finestra (cioè, elimina tutte le altre finestre). + C-x 1 Una finestra (cioè, elimina tutte le altre finestre). È un CONTROL-x seguito dalla cifra 1. C-x 1 espande la finestra che -continene il cursore su tutto lo schermo ed elimina tutte le altre +contiene il cursore su tutto lo schermo ed elimina tutte le altre finestre. >> Sposta il cursore su questa riga e poi batti C-u 0 C-l. + >> Batti C-h k C-f. Osserva come questa finestra viene rimpicciolita mentre ne appare un'altra che contiene la spiegazione del comando CONTROL-f. + >> Batti C-x 1 e guarda come la finestra contenente la spiegazione scompare. -Questo comando è diverso da tutti quelli imparati finora perché contiene -due caratteri. Inizia con il carattere CONTROL-x. C'è un'ampia serie di -comandi che iniziano con CONTROL-x; molti di essi riguardano finestre, -file, buffer, e cose simili. Questi comandi possono essere lunghi due, -tre o quattro caratteri. +C'è un'ampia serie di comandi che iniziano con CONTROL-x; molti di +essi riguardano finestre, file, buffer e cose simili. Questi comandi +possono essere lunghi due, tre o quattro caratteri. * INSERIMENTO E CANCELLAZIONE ----------------------------- Per inserire del testo basta premere i tasti corrispondenti alle varie -lettere che lo compongono. I caratteri visibili, come A, 7, *, ecc., sono -considerati testo e inseriti immediatamente. Si usa <Return> (il tasto -Invio) per inserire un carattere Newline. - -L'ultimo carattere inserito si cancella usando <Delete>. <Delete> è un -tasto che si trova sulla tastiera e che potrebbe essere etichettato come -"Del" o "Canc". Spesso il tasto "Backspace" (quello con la freccia -rivolta verso sinistra sopra il tasto Invio) serve da <Delete>, ma non -sempre! - -Più in generale <Delete> cancella il carattere posto immediatamente prima -della posizione attuale del cursore. - ->> Prova questo adesso - batti alcuni caratteri e poi cancellali con - <Delete> ripetuto alcune volte. Non preoccuparti delle modifiche fatte - a questo file: l'esercitazione principale rimarrà intatta, quella che - stai usando ne è una tua copia personale. - -Quando una riga di testo diventa troppo lunga per essere visualizzata su -una riga di schermo essa viene "continuata" su una seconda riga dello -schermo. Un carattere barra retroversa («\») posto accanto al margine -sinistro indica la prosecuzione della riga precedente. Quando si usa un -sistema a finestre grafico, invece della barra retroversa comparirà una -piccola freccia ricurva. +lettere che lo compongono. I caratteri visibili, come A, 7, *, ecc., +sono considerati testo e inseriti immediatamente. Per inserire un +Newline usa il tasto <Invio> (a volte contrassegnato col simbolo ↲). + +Per cancellare il carattere immediatamente prima del cursore, digita +<DEL>: solitamente è un tasto più largo del normale etichettato con +“Backspace” o con una freccia che punta a sinistra, sopra il tasto +<Invio>; generalmente elimina l'ultimo carattere inserito + +Può esserci un altro tasto etichettato “Canc”, ma non è quello a cui +ci riferiamo con <DEL>. + +>> Prova questo adesso: batti alcuni caratteri e poi cancellali con + <DEL> ripetuto alcune volte. Non preoccuparti delle modifiche + fatte a questo file: l'esercitazione principale rimarrà intatta, + quella che stai usando ne è una tua copia personale. + +Quando una riga di testo diventa troppo lunga per essere visualizzata +su una riga di schermo viene spezzata e “continua” su una seconda riga +dello schermo. Se stai usando un sistema a finestre grafico, +compaiono delle piccole frecce ricurve ai lati del testo (nelle +“frange” sinistra e destra), indicando che la riga continua. Su un +terminale testuale, la continuazione viene indicata da una barra +rovescia (“\”) nell'ultima colonna a destra. >> Inserisci del testo fino a raggiungere il margine destro e poi continua. Vedrai apparire la prosecuzione della riga. ->> Usa <Delete> per cancellare il testo fino a quando la riga di testo è + +>> Usa <DEL> per cancellare il testo fino a quando la riga di testo è di nuovo tutta contenuta in una sola riga dello schermo. La prosecuzione alla riga successiva scompare. -Si può cancellare un carattere Newline ("a capo", è un carattere che ha un -effetto ma non viene visualizzato esplicitamente) proprio come ogni altro. +Si può cancellare un carattere Newline proprio come ogni altro. Quando si cancella il carattere Newline che separa due righe queste -vengono unite in una riga sola. Se la riga risultante è troppo lunga per -essere contenuta dallo schermo allora sarà continuata nella riga +vengono unite in una riga sola. Se la riga risultante è troppo lunga +per essere contenuta dallo schermo allora sarà continuata nella riga successiva. ->> Muovi il cursore all'inizio di una riga e poi premi <Delete>. Questo +>> Muovi il cursore all'inizio di una riga e poi premi <DEL>. Questo unisce la riga alla precedente. + >> Premi <Invio> per inserire di nuovo il carattere Newline che hai cancellato. -Si ricordi che la maggior parte dei comandi di Emacs può ricevere un -argomento numerico, compresi i caratteri per inserire il testo. Quando si -ripete un carattere di testo questo viene inserito un certo numero di -volte. +Il tasto <Invio> è speciale in quanto può implicare più del semplice +inserimento di un carattere Newline. A seconda del testo circostante, +può inserire degli spazi dopo l'“a capo” in modo tale che inserendo +ulteriori caratteri nella nuova riga, il testo rimanga allineato con +quello nelle righe precedenti. Questo comportamento (cioè quando +premendo un tasto vengono eseguite ulteriori azioni rispetto al +semplice inserimento del carattere stesso) viene chiamato “elettrico”. + +>> Questo è un esempio del comportamento “elettrico” di <Invio> + Inserisci un <Invio> alla fine di questa riga. ->> Prova adesso - inserisci C-u 8 * per ottenere ********. +Dovresti vedere che dopo essere andato a capo, Emacs ha inserito degli +spazi per allineare il cursore sotto la “I” di “Inserisci”. -Fino ad ora si è visto il modo più semplice di inserire testo in Emacs e -di correggere gli errori. In modo analogo è possibile cancellare parola -per parola o riga per riga. Ecco un sommario delle operazioni di +Ricorda che la maggior parte dei comandi di Emacs può ricevere un +argomento numerico, compresi i caratteri per inserire il testo. +Quando si ripete un carattere di testo questo viene inserito un certo +numero di volte. + +>> Prova adesso: inserisci C-u 8 * per ottenere ********. + +Fino ad ora si è visto il modo più semplice di inserire testo in Emacs +e di correggere gli errori. In modo analogo è possibile cancellare +parole o righe di testo. Ecco un sommario delle operazioni di cancellazione: - <Delete> cancella il carattere posto subito prima del cursore - C-d cancella il carattere posto subito dopo il cursore - - M-<Delete> elimina la parola posta prima del cursore - M-d elimina la parola posta subito dopo il cursore - - C-k cancella dalla posizione del cursore fino a fine riga - M-k cancella fino alla fine della frase corrente. - -Si osservi che <Delete> e C-d da una parte e M-<Delete> e M-d dall'altra -estendono il parallelo tra C-f e M-f (a dire il vero, <Delete> non è un -vero e proprio carattere di controllo, ma non preoccupiamoci di questo). -C-k è simile a C-e e M-k è simile a M-e, nel senso che i primi operano su -righe e i secondi su frasi. - -Si può anche cancellare una qualsiasi parte del buffer in modo uniforme: -si sposta il cursore alla fine di quella parte e poi si usa C-@ o C-SPC -(uno o l'altro, SPC è la Barra Spaziatrice), poi si muove il cursore -all'altro estremo della zona e si preme C-w. Questo cancella tutto il -testo posto tra i due estremi. - ->> Sposta il cursore sulla P all'inizio del paragrafo precedente. Premi - C-SPC. Emacs dovrebbe mostrarti il messaggio "Mark set" nella parte - bassa dello schermo. Muovi il cursore sulla s di "estremi" del - paragrafo precedente. Premi C-w. Questo cancellerà il testo a partire - dalla "P" e fino alla lettera che precede "s". - -La differenza tra "killing" (eliminazione) e "deleting" (cancellazione) è -che il testo "eliminato" può essere inserito di nuovo, mentre quello che -viene cancellato non si può recuperare. L'operazione di reinserimento del -testo soppresso si chiama "yanking". In genere i comandi che possono -rimuovere molto testo fanno un'operazione di eliminazione (così da poterlo -eventualmente reinserire), mentre i comandi che rimuovono un solo -carattere o solo righe vuote e spazi effettuano una cancellazione (quindi -non è possibile recuperare quel testo). - ->> Muovi il cursore all'inizio di una riga non vuota. Usa C-k per - eliminare il testo di quella riga. Premi C-k una seconda volta. Ti - accorgerai di come viene cancellato il carattere Newline posto dopo la - riga stessa. + <DEL> cancella il carattere posto subito prima del cursore + C-d cancella il carattere posto subito dopo il cursore + + M-<DEL> elimina la parola posta prima del cursore + M-d elimina la parola posta subito dopo il cursore + + C-k cancella dalla posizione del cursore fino a fine riga + M-k cancella fino alla fine della frase corrente. + +Si osservi che <DEL> e C-d da una parte e M-<DEL> e M-d dall'altra +estendono il parallelo tra C-f e M-f (a dire il vero, <DEL> non è un +vero e proprio carattere di controllo, ma non preoccupiamoci di +questo). C-k è simile a C-e e M-k è simile a M-e, nel senso che i +primi operano su righe e i secondi su frasi. + +Si può anche cancellare una qualsiasi parte del buffer in modo +uniforme: si sposta il cursore alla fine di quella parte e poi si usa +C-<SPC> (<SPC> è la barra spaziatrice), poi si muove il cursore +all'altro estremo della zona. Una volta fatto, Emacs evidenzia il +testo compreso tra il cursore e la posizione dove hai digitato +C-<SPC>. A questo punto premendo C-w il testo evidenziato viene +eliminato. + +>> Sposta il cursore sulla “S” all'inizio del paragrafo precedente. +>> Premi C-<SPC>. Emacs dovrebbe mostrarti il messaggio "Mark set" + nella parte bassa dello schermo. +>> Muovi il cursore sulla “o” di “sposta”, nella seconda riga del + paragrafo. +>> Premi C-w. Questo eliminerà il testo a partire dalla "S" e fino + alla lettera che precede “o”. + +La differenza tra “eliminazione” (“killing”) e “cancellazione” +(“deleting”) è che il testo “eliminato” può essere inserito di nuovo +(in qualsiasi posizione), mentre quello che viene cancellato non può +essere reinserito nello stesso modo (si può comunque annullare una +cancellazione, vedi sotto). L'operazione di reinserimento del testo +cancellato si chiama “yanking”. In genere i comandi che possono +rimuovere molto testo lo eliminano (così da poterlo eventualmente +reinserire), mentre i comandi che rimuovono un solo carattere o solo +righe vuote e spazi effettuano una cancellazione (quindi non è +possibile recuperare quel testo). <DEL> e C-d eseguono una +cancellazione nel caso più semplice, senza un argomento. Con un +argomento invece eliminano il testo. + +>> Muovi il cursore all'inizio di una riga non vuota, poi usa C-k per + eliminare il testo di quella riga. +>> Premi C-k una seconda volta. Ti accorgerai di come viene + eliminato il carattere Newline posto dopo la riga stessa. Si noti che un singolo C-k elimina il contenuto di una sola riga, un -secondo C-k cancella la riga stessa, e fa spostare in alto tutte le righe -successive. C-k usa un eventuale argomento numerico in modo speciale: -elimina quel numero di righe ed il loro contenuto. Non è una semplice -ripetizione del comando. C-u 2 C-k elimina due righe e i rispettivi -caratteri Newline; battere due volte C-k sarebbe diverso. - -Recuperare il testo eliminato è un'operazione chiamata "yanking". -(Significa "strappare", si deve pensare di riprendere del testo che era -stato portato via). Si può recuperare il testo che è stato eliminato sia -nella sua posizione originaria che in un altro punto del buffer o anche in -un diverso file. Si può reinserire diverse volte, facendone copie -multiple. +secondo C-k elimina la riga stessa, facendo spostare in alto tutte le +righe successive. C-k usa un eventuale argomento numerico in modo +speciale: elimina quel numero di righe ED il loro contenuto. Non è +una semplice ripetizione del comando. C-u 2 C-k elimina due righe e i +rispettivi caratteri Newline; battere due volte C-k sarebbe diverso. + +Puoi reinserire il testo eliminato sia nella stessa posizione dove è +stato rimosso, in un altro punto del testo che stai modificando, +oppure in un file diverso. Puoi reinserire lo stesso testo diverse +volte, facendone copie multiple. Altri editor usano termini diversi +per queste operazioni, tipicamente “taglia” e “incolla” (consulta il +Glossario nel manuale di Emacs). Il comando per fare "yanking" è C-y. Inserisce il testo eliminato per ultimo nel punto in cui si trova attualmente il cursore. >> Prova: premi C-y per recuperare il testo di prima. -Se si eseguono operazioni di eliminazione immediatamente successive il -testo eliminato è considerato un tutt'uno e quindi un solo C-y inserirà +Se si eseguono operazioni di eliminazione consecutive il testo +eliminato è considerato un tutt'uno e quindi un solo C-y inserirà quelle righe tutte assieme. >> Prova adesso, premi C-k alcune volte. @@ -423,56 +457,55 @@ quelle righe tutte assieme. Adesso, per recuperare il testo eliminato: >> Premi C-y. Sposta il cursore alcune righe più in basso e premi di - nuovo C-y. Hai appena visto come copiare una parte di testo. + nuovo C-y. Hai appena visto come duplicare una parte di testo. Cosa succede se c'è del testo da recuperare tra quello eliminato ma è stato eliminato altro testo dopo di esso? C-y restituirebbe il testo -dell'ultima eliminazione, tuttavia il testo eliminato in precedenza non è -perso. Si recupera con il comando M-y. Dopo aver usato C-y per -recuperare il testo più recentemente eliminato, un M-y sostituisce quel -testo con quello dell'eliminazione precedente. Premere M-y altre volte -recupera il testo delle eliminazioni via via precedenti. Quando è stato -trovato il testo cercato non si deve fare altro per tenerlo. Si può -andare avanti con la scrittura lasciando il testo recuperato dove si -trova. - -Quando si usa M-y un certo numero di volte si arriva di nuovo al testo di -partenza (quello eliminato per ultimo). - ->> Elimina una riga, sposta il cursore, elimina un'altra riga. Usa C-y per - recuperare la seconda riga eliminata. Premi M-y e verrà sostituita - dalla riga eliminata prima. Usa di nuovo M-y e osserva cosa succede. - Continua fino a quando non ritrovi la riga che avevi eliminato per - seconda. Se vuoi puoi usare un argomento numerico sia positivo che - negativo per M-y. +dell'ultima eliminazione, tuttavia il testo eliminato in precedenza +non è perso. Si recupera con il comando M-y. Dopo aver usato C-y per +recuperare il testo più recentemente eliminato, un M-y sostituisce +quel testo con quello dell'eliminazione precedente. Premendo M-y in +successione si recupera il testo delle eliminazioni via via +precedenti. Quando è stato trovato il testo cercato non si deve fare +altro per tenerlo. Si può andare avanti con la scrittura lasciando il +testo recuperato dove si trova. + +Quando si usa M-y un certo numero di volte si arriva di nuovo al testo +di partenza (quello eliminato per ultimo). + +>> Elimina una riga, sposta il cursore, elimina un'altra riga. + Premi C-y per recuperare la seconda riga eliminata. + Premi M-y e verrà sostituita dalla riga eliminata prima. + Usa di nuovo M-y e osserva cosa succede. Continua fino a quando + non ritrovi la riga che avevi eliminato per seconda. Se vuoi puoi + usare un argomento numerico sia positivo che negativo per M-y. * ANNULLAMENTO -------------- Se si modifica il testo e subito dopo ci si accorge di aver fatto un -errore si può annullare la modifica con il comando di annullamento C-x u. +errore si può annullare la modifica con il comando di annullamento, +C-/. -Normalmente C-x u annulla le modifiche fatte da un solo comando; se si usa -C-x u alcune volte di seguito ogni ripetizione annulla un comando -precedente. +Normalmente C-/ annulla le modifiche fatte da un solo comando; se si +usa C-/ di seguito ogni ripetizione annulla un ulteriore comando. -Ci sono due eccezioni: i comandi che non modificano il testo non contano, -tra questi i comandi di spostamento del cursore e quelli di scorrimento -del testo; i caratteri inseriti nel testo sono gestiti in gruppi, fino a -20 elementi, ciò per ridurre il numero di C-x u da usare per annullare -l'inserimento del testo. +Ci sono due eccezioni: i comandi che non modificano il testo non +contano, tra questi i comandi di spostamento del cursore e quelli di +scorrimento del testo; i caratteri inseriti nel testo sono gestiti in +gruppi, fino a 20 elementi (al fine di ridurre il numero di C-/ da +usare per annullare l'inserimento del testo). ->> Elimina questa riga con C-k poi usa C-x u e guardala ricomparire. +>> Elimina questa riga con C-k poi usa C-/ e dovrebbe ricomparire. -C-_ è un comando di annullamento alternativo; funziona come C-x u ma è più -semplice da inserire più volte di seguito. Lo svantaggio di C-_ è che su -alcune tastiere non è di inserimento immediato. Ecco perché abbiamo -previsto anche C-x u. Su alcuni terminali si può ottenere C-_ dal simbolo -/ mentre si tiene premuto il tasto CONTROL. +C-_ è un comando di annullamento alternativo, funziona esattamente +come C-/. Su alcuni terminali, la sequenza C-/ invia effettivamente +C-_ a Emacs. Alternativamente, anche C-x u ha la stessa funzione di +C-/, ma è leggermente più scomoda da inserire. -Un argomento numerico per C-x u o C-_ agisce come numero delle ripetizioni -da effettuare. +Un argomento numerico per C-/, C-_ o C-x u agisce come numero delle +ripetizioni da effettuare. Si può annullare la cancellazione del testo proprio come se ne annulla l'eliminazione. La distinzione tra l'eliminazione e la cancellazione @@ -483,337 +516,361 @@ differenza rispetto all'operazione di annullamento. * FILE ------ -Per conservare in modo permanente il testo inserito biaogna conservarlo in -un file, altrimenti sarà perso al termine dell'esecuzione di Emacs. Per -inserire il testo in un file bisogna aprire quel file prima di comporre il -testo. (Questa operazione si chiama anche "visita" del file.) - -Aprire un file significa osservarne il contenuto all'interno di Emacs. -Per molti versi è come se si operasse sul file stesso, tuttavia le -modifiche apportate al contenuto non sono definitive fino a quando non si -"salva" il file. Tutto questo avviene in modo tale da evitare di lasciare -un file su disco quando è modificato solo in parte. Persino quando si -salva il file Emacs conserva il contenuto originale dello stesso in un -file con un altro nome, nel caso in cui si capisca più tardi che le -modifiche sono state un errore. - -Osservando la parte bassa dello schermo si noti che c'è una riga che -inizia e finisce con dei trattini e che all'inizio contiene questo testo -"--:-- TUTORIAL.it" o qualcosa di simile. Questa parte dello schermo -normalmente mostra il nome del file che si sta "visitando". In questo -momento si "visita" un file che si chiama "TUTORIAL.it" che è poi una -copia dell'esercitazione di Emacs. Quando si apre un file con Emacs il -suo nome apparirà sempre in quel punto preciso. - -Una caratteristica particolare del comando per aprire i file è che bisogna -fornirgli il nome del file. Diciamo in questo caso che il comando "legge -un argomento dal terminale" (l'argomento è proprio il nome del file). -Dopo aver scritto il comando - - C-x C-f Trova un file +Per conservare in modo permanente il testo inserito bisogna +conservarlo in un file, altrimenti sarà perso al termine +dell'esecuzione di Emacs. Per inserire il testo in un file bisogna +aprire quel file prima di comporre il testo. (Questa operazione si +chiama anche “visita” del file.) + +Aprire un file implica vederne il contenuto all'interno di Emacs. Per +molti versi è come se si operasse sul file stesso, tuttavia le +modifiche apportate al contenuto non sono definitive fino a quando non +si “salva” il file. Tutto questo avviene in modo tale da evitare di +lasciare un file su disco quando è modificato solo in parte. Persino +quando si salva il file Emacs conserva il contenuto originale dello +stesso in un file con un altro nome, nel caso in cui si capisca più +tardi che le modifiche sono state un errore. + +Osservando la parte bassa dello schermo puoi notare una riga che +inizia qualcosa del tipo “--:-- TUTORIAL.it”. Questa parte dello +schermo normalmente mostra il nome del file che si sta “visitando”. +In questo momento stai osservando la tua copia personale +dell'esercitazione di Emacs, chiamata “TUTORIAL.it”. Quando si apre +un file con Emacs il suo nome apparirà sempre in quel punto preciso. + +Una caratteristica particolare del comando per aprire i file è che +bisogna fornirgli il nome del file. Diciamo in questo caso che il +comando “legge un argomento dal terminale” (l'argomento è proprio il +nome del file). Dopo aver scritto il comando + + C-x C-f Trova un file Emacs chiede il nome del file. Il nome che si inserisce compare nella -riga più in basso sullo schermo. La riga di fondo è chiamata "minibuffer" -quando viene usato per questo genere di operazioni di inserimento. Si -possono usare i consueti comandi di Emacs per operare sul nome del file. +riga più in basso sullo schermo. La riga di fondo è chiamata +“minibuffer” quando viene usato per questo genere di operazioni di +inserimento. Si possono usare i consueti comandi di Emacs per operare +sul nome del file. Mentre si inserisce il nome del file (oppure ogni altro testo nel -minibuffer), si può annullare il comando con un C-g. +minibuffer), è possibile annullare l'operazione usando C-g. ->> Premi C-x C-f, poi premi C-g. Questo vuota il "minibuffer" e +>> Premi C-x C-f, poi premi C-g. Questo annulla il minibuffer e interrompe l'esecuzione del comando C-x C-f che stava usando il - "minibuffer". Quindi non sarà aperto alcun file. + minibuffer. Quindi non sarà aperto alcun file. -Quando si finisce di indicare il nome del file bisogna premere <Invio> per -portare a termine il comando. Il comando C-x C-f inizia il suo lavoro e -trova il file che è stato scelto. Il "minibuffer" scompare quando il -comando C-x C-f ha terminato l'esecuzione. +Quando hai finito di indicare il nome del file, premi <Invio> per +portare a termine il comando. Il minibuffer scompare e il comando C-x +C-f inizia il suo lavoro e trova il file che è stato scelto. Subito dopo, il contenuto del file compare sullo schermo e si può -modificare a piacere. Quando si desidera rendere permanenti le modifiche -si usa il comando +modificare a piacere. Quando si desidera rendere permanenti le +modifiche si usa il comando - C-x C-s Salva il file + C-x C-s Salva il file Questo copia il testo contenuto in Emacs nel file su disco. La prima -volta che si effetta questa operazione Emacs dà un nuovo nome al file -originale in modo da conservarlo. Il nuovo nome è ottenuto aggiungendo un -carattere "~" alla fine del nome originale. - -Quando il salvataggio è terminato Emacs mostra il nome del file appena -scritto. Si dovrebbero salvare le modifiche piuttosto spesso in modo da -non perdere troppo lavoro se per caso il sistema dovesse bloccarsi. - ->> Usa C-x C-f per salvare la tua copia di questa esercitazione. Questo - dovrebbe mostrare il messaggio "Wrote ...TUTORIAL.it" nella parte bassa - dello schermo. +volta che si effettua questa operazione Emacs rinomina il file +originale in modo da conservarlo. Il nuovo nome è ottenuto +aggiungendo un carattere "~" alla fine del nome originale. Quando il +salvataggio termina, Emacs mostra il nome del file scritto. + +>> Premi C-x C-s TUTORIAL<Invio>. + Questo dovrebbe salvare questa esercitazione in un file chiamato + “TUTORIAL” e mostrare “Wrote ...TUTORIAL nella parte bassa dello + schermo. -Si può aprire un file già esistente per leggerlo o modificarlo. Si può -anche "visitare" un file che ancora non esiste. Questo è un modo per -creare un nuovo file con Emacs: si apre il file che sarà inizialmente -vuoto e quindi si inizia ad inserire il testo. Quando si chiederà di -salvare il file Emacs lo creerà ed esso conterrà tutto il testo che è -stato inserito. Da quel punto in poi si potrà pensare di operare su un -file già esistente. +Si può aprire un file già esistente per leggerlo o modificarlo. Si +può anche “visitare” un file che ancora non esiste. Questo è un modo +per creare un nuovo file con Emacs: si apre il file che sarà +inizialmente vuoto e quindi si inizia ad inserire il testo. Quando si +chiederà di salvare il file Emacs lo creerà ed esso conterrà tutto il +testo che è stato inserito. Da quel punto in poi si potrà pensare di +operare su un file già esistente. * BUFFER -------- -Se si apre un secondo file con C-x C-f il primo rimane aperto all'interno -di Emacs. Si può tornare a visualizzarlo "visitandolo" di nuovo con il -comando C-x C-f. In questo modo si possono aprire quanti file si vogliono -all'interno di Emacs. +Se si apre un secondo file con C-x C-f il primo rimane aperto +all'interno di Emacs. Si può tornare a visualizzarlo “visitandolo” di +nuovo con il comando C-x C-f. In questo modo si possono aprire quanti +file si vogliono all'interno di Emacs. ->> Crea un file chiamato "pippo" usando C-x C-f pippo <Invio>. Inserisci - del testo e poi salva "pippo" con C-x C-s. Poi usa C-x C-f TUTORIAL.it - <Invio> per tornare all'esercitazione. +Emacs conserva il testo di ogni file all'interno di un oggetto +chiamato “buffer”. L'apertura di un file crea un nuovo buffer +all'interno di Emacs. Per guardare una lista dei buffer che esistono +attualmente nella tua sessione di Emacs si usa -Emacs conserva il testo di ogni file all'interno di un oggetto chiamato -"buffer". La "visita" di un file produce un nuovo buffer all'interno di -Emacs. Per guardare una lista dei buffer che esistono attualmente nella -tua sessione di Emacs si usa - - C-x C-b Elenca buffer + C-x C-b Elenca buffer >> Prova C-x C-b adesso. -Si osservi come ogni buffer abbia un nome e come possa avere anche il nome -di un file del quale conserva il contenuto. Alcuni buffer non -corrispondono ad alcun file. Per esempio il buffer che ha nome "*Buffer -List*" non ha un file corrispondente, è quello che contiene la lista che è -stata creata da C-x C-b. OGNI testo che si legge all'interno di Emacs è -sempre parte di un buffer. +Osserva come ogni buffer abbia un nome e come possa avere anche il +nome di un file del quale conserva il contenuto. QUALSIASI testo +mostrato in una finestra di Emacs appartiene a qualche buffer. >> Usa C-x 1 per eliminare la lista dei buffer. -Se si modifica in qualche modo il testo di un file e poi si visita un altro -file questo non comporta un salvataggio del primo. Le modifiche rimangono -solo all'interno di Emacs, nel buffer relativo a quel file. La creazione -o la modifica del buffer del secondo file non ha alcun effetto sul buffer -del primo. Sarebbe fastidioso dover tornare al primo file con C-x C-f per -salvarlo con C-x C-s. Così c'è il comando +Quando ci sono svariati buffer, solo uno di essi è quello “corrente” +in un certo istante. Questo buffer è quello che è soggetto alle tue +modifiche. Se vuoi modificare un altro buffer, devi prima +“selezionarlo”. Se vuoi passare a un buffer che corrisponde a un +file, puoi farlo visitando di nuovo quel file usando C-x C-f. Ma c'è +un modo più semplice: usa il comando C-x b. Questo comando richiede +il nome del buffer. + +>> Crea un file chiamato “pippo” con C-x C-f pippo<Invio>. + Torna poi a questa esercitazione con C-x b TUTORIAL<Invio>. + +La maggior parte delle volte, il nome del buffer corrisponde al nome +del file (senza la parte relativa alla directory). Questo non è +sempre vero. La lista dei buffer che ottieni con C-x C-b mostra sia +il nome del buffer che il nome del file associato. + +Alcuni buffer non corrispondono ad alcun file. Per esempio il buffer +che ha nome “*Buffer List*” non è associato a nessun file. Questo +buffer TUTORIAL inizialmente non era associato a un file, mentre +adesso lo è, dal momento che nella sezione precedente hai usato C-x +C-s per salvarlo in un file. + +Anche il buffer chiamato “*Messages* non è associato ad alcun file. +Quel buffer contiene tutti i messaggi che sono apparsi nella parte +bassa dello schermo durante la sessione di Emacs. + +>> Passa al buffer con i messaggi con C-x b *Messages*<Invio>. + Torna poi a questa esercitazione con C-x b TUTORIAL<Invio>. - C-x s Salva alcuni buffer +Se si modifica in qualche modo il testo di un file e poi si visita un +altro file questo non comporta il salvataggio del primo. Le modifiche +rimangono solo all'interno di Emacs, nel buffer relativo a quel file. +La creazione o la modifica del buffer del secondo file non ha alcun +effetto sul buffer del primo. Questo è comodo, ma è conveniente avere +la possibilità di salvare il buffer del primo file: sarebbe fastidioso +dover prima passare a quel buffer per salvarlo con C-x C-s. Così c'è +il comando -C-x s chiede conferma del salvataggio per ogni buffer che contiene testo -modificato e non ancora salvato. Chiede, per ognuno di quei buffer, se si -voglia salvarne il contenuto nel file corrispondente. + C-x s Salva alcuni buffer ->> Inserisci una riga di testo e poi premi C-x s. Dovrebbe chiederti se - vuoi salvare il buffer chiamato TUTORIAL.it. Rispondi di sì battendo - "y". +C-x s chiede conferma del salvataggio per ogni buffer che contiene +testo modificato e non ancora salvato. Chiede, per ognuno di quei +buffer, se si voglia salvarne il contenuto nel file corrispondente. + +>> Inserisci una riga di testo e poi premi C-x s. + Dovrebbe chiederti se vuoi salvare il file chiamato “...TUTORIAL”. + Rispondi di sì battendo “y”. * ESTENDERE L'INSIEME DEI COMANDI --------------------------------- Emacs ha molti comandi in più rispetto a quelli che potrebbero trovare -posto su tutti i caratteri CONTROL e META. Emacs risolve questo problema -usando il comando "estendi" (eXtend). Ce ne sono di due tipi: - - C-x Comando esteso carattere. Seguito da un carattere. - M-x Comando esteso con nome. Seguito da un nome di comando. - -Si tratta di comandi utili ma meno utilizzati di quelli che già osservati. -Se ne sono visti due: il comando C-x C-f per visitare un file e quello C-x -C-s per salvarlo. Un altro esempio è quello che serve per chiudere la -sessione Emacs - cioè il comando C-x C-c. Non bisogna temere di perdere -le modifiche fatte: C-x C-c propone infatti di salvare ogni file -modificato prima di chiudere Emacs. - -C-z è il comando che serve per uscire da Emacs *temporaneamente* - così da -poter tornare alla stessa sessione di Emacs in un momento successivo. - -Su sistemi che lo permettono C-z "sospende" Emacs, cioè riporta alla shell -che lo aveva invocato senza però porre termine alla sessione attuale. -Nelle shell più comuni si può riaprire la sessione in corso con il comando -"fg" oppure con "%emacs". - -Su sistemi che non prevedono la possibilità di "sospensione", C-z crea una -subshell che funziona all'interno di Emacs per dare la possibilità di -usare altri programmi e poi tornare a Emacs successivamente; in pratica -non fa "uscire" veramente da Emacs. In questo caso il comando di shell -"exit" è il modo comune per tornare ad Emacs dalla subshell. - -Il momento di usare C-x C-c è quando si sta per effettuare il log-out dal -sistema. È anche il comando giusto quando si deve chiudere Emacs che è -stato invocato da un programma che gestisce la posta o da altri programmi -simili, dal momento che essi potrebbero non riuscire a gestire la -sospensione di Emacs. In circostanze normali, invece, se non si è sul -punto di fare un log-out è meglio sospendere l'esecuzione di Emacs -piuttosto che interromperla. - -Ci sono molti comandi che usano C-x. Ecco una lista di quelli già -conosciuti: - - C-x C-f Apri un file. - C-x C-s Salva un file. - C-x C-b Elenca buffer. - C-x C-c Chiudi Emacs. - C-x 1 Elimina tutte le finestre tranne una. - C-x u Annulla. - -I comandi estesi con nome sono usati ancora meno spesso, oppure sono usati -solo in certi "modi" di esecuzione. Un esempio è il comando -replace-string per sostituire in tutto il testo una stringa di caratteri -con un'altra. Quando si usa M-x Emacs visualizza "M-x" nella parte bassa -dello schermo, quindi si deve inserire per esteso il nome del comando; in -questo caso "replace-string". Inserisci solo "repl s<TAB>" ed Emacs -completerà da solo il nome. (<TAB> è il tasto di tabulazione, che si -trova di solito sul lato sinistro della tastiera sopra al tasto Blocca -Maiuscole). Concludi l'inserimento del comando con il tasto <Invio>. - -Il comando replace-string richiede due argomenti: la stringa da sostituire -e quella con cui sostituirla. Bisogna indicare la fine di ogni argomento -con <Invio>. - ->> Muovi il cursore sulla riga bianca qui sotto, quindi batti M-x repl s - <Invio> cambiata <Invio> modificata <Invio>. - -Osserva come questa riga è cambiata: hai sostituito la parola cam-bia-ta -con "modificata" tutte le volte che quella compariva nel testo, a partire -dalla posizione iniziale del cursore. +posto su tutti i caratteri CONTROL e META. Emacs risolve questo +problema usando il comando X (eXtend). Ci sono due varianti: + + C-x Comando esteso carattere. Seguito da un carattere. + M-x Comando esteso con nome. Seguito da un nome di comando. + +Si tratta di comandi utili ma meno utilizzati di quelli che già +osservati. Se ne sono visti alcuni: il comando C-x C-f per visitare +un file e C-x C-s per salvarlo, ad esempio. Un altro esempio è quello +che serve per chiudere la sessione Emacs, cioè il comando C-x C-c. +(Non preoccuparti di perdere le modifiche che hai apportato: C-x C-c +propone infatti di salvare ogni file modificato prima di chiudere +Emacs.) + +Se stai usando un terminale grafico, non devi fare niente di speciale +per passare da Emacs a un'altra applicazione. Puoi farlo con il mouse +oppure utilizzare i comandi del “window manager”. Al contrario, se +stai usando un terminale a caratteri che può mostrare una sola +applicazione alla volta, hai bisogno di un modo per “sospendere” Emacs +e poter quindi usare un'altra applicazione. + +C-z è il comando che serve per uscire da Emacs *temporaneamente*, in +modo tale da poter tornare alla stessa sessione di Emacs in un momento +successivo. Quando si è su un terminale a caratteri, C-z sospende +Emacs, cioè si ritorna alla shell senza distruggere la sessione +corrente. Nelle shell più comuni, puoi ritornare in Emacs con il +comando “fg” oppure con “%emacs”. + +Il momento di usare C-x C-c è quando si sta per effettuare il log-out +dal sistema. È anche il comando giusto quando si deve chiudere Emacs +che è stato invocato da un altro programma, ad esempio da quello che +gestisce la posta. + +Ci sono molti comandi C-x. Ecco una lista di quelli già conosciuti: + + C-x C-f Apri un file. + C-x C-s Salva un file. + C-x s Salva alcuni buffer. + C-x C-b Elenca buffer. + C-x b Passa a un altro buffer. + C-x C-c Chiudi Emacs. + C-x 1 Elimina tutte le finestre tranne una. + C-x u Annulla. + +I comandi estesi con nome sono usati ancora meno spesso, oppure sono +usati solo in certe modalità. Un esempio è il comando replace-string +per sostituire in tutto il testo una stringa di caratteri con +un'altra. Quando si usa M-x Emacs visualizza "M-x" nella parte bassa +dello schermo, quindi si deve inserire per esteso il nome del comando; +in questo caso “replace-string”. Inserisci solo “repl s<TAB>” ed +Emacs completerà da solo il nome. (<TAB> è il tasto di tabulazione, +che si trova di solito sul lato sinistro della tastiera sopra al tasto +Blocca Maiuscole.) Concludi l'inserimento del comando con il tasto +<Invio>. + +Il comando replace-string richiede due argomenti: la stringa da +sostituire e quella con cui sostituirla. Bisogna indicare la fine di +ogni argomento con <Invio>. + +>> Muovi il cursore sulla riga vuota due righe sotto questa. + Inserisci quindi M-x repl s<Invio>cambiata<Invio>modificata<Invio>. + + Osserva come questa riga sia cambiata: hai sostituito la parola + “cambiata” con “modificata” tutte le volte che quella compariva nel + testo, a partire dalla posizione iniziale del cursore. * SALVATAGGIO AUTOMATICO ------------------------ -Quando si apportano delle modifiche ad un file ma non sono ancora state -salvate potrebbero essere perse se per caso il sistema si bloccasse. Per -proteggerti da questa eventualità Emacs scrive periodicamente un file di -"salvataggio automatico" per ogni file che si sta scrivendo. Il nome del -file di salvataggio automatico ha un carattere # all'inizio e alla fine; -per esempio se il file si chiama "ciao.c" il nome del file di salvataggio -automatico sarà "#ciao.c#". Quando si salva il file nel modo consueto -Emacs cancella il file di salvataggio automatico. +Quando si apportano delle modifiche ad un file ma non sono ancora +state salvate potrebbero essere perse se per caso il sistema si +bloccasse. Per proteggerti da questa eventualità Emacs scrive +periodicamente un file di “salvataggio automatico” per ogni file che +si sta modificando. Il nome del file di salvataggio automatico ha un +carattere # all'inizio e alla fine; per esempio se il file si chiama +“ciao.c” il nome del file di salvataggio automatico sarà “#ciao.c#”. +Quando si salva il file nel modo consueto Emacs cancella il file di +salvataggio automatico. -Se il computer si blocca si può recuperare il file salvato automaticamente -aprendo il file in modo normale (il file che si stava scrivendo, non -quello di salvataggio automatico) e usando poi M-x recover file<Invio>. -Quando viene chiesta la conferma si risponda con yes<Invio> per andare -avanti nel recupero dei dati salvati automaticamente. +Se il computer si blocca si può recuperare il file salvato +automaticamente aprendo il file in modo normale (il file che si stava +scrivendo, non quello di salvataggio automatico) e usando poi M-x +recover-file<Invio>. Quando viene chiesta la conferma si risponda +con yes<Invio> per procedere con il recupero dei dati salvati +automaticamente. * AREA DI ECO ------------- Se Emacs si accorge che si inseriscono comandi multicarattere in modo -troppo lento allora mostra la sequenza nella parte bassa dello schermo in -un'area chiamata "area di eco". L'area in questione contiene l'ultima riga -dello schermo. +troppo lento allora mostra la sequenza nella parte bassa dello schermo +in un'area chiamata "area di eco". L'area in questione contiene +l'ultima riga dello schermo. * MODE LINE ----------- -La riga immediatamente sopra all'area di eco è chiamata "mode line" (riga -di modo). La "mode line" si presenta più o meno così: +La riga immediatamente sopra all'area di eco è chiamata "mode line" +(riga di modo). La "mode line" si presenta più o meno così: ---:** TUTORIAL.it (Fundamental)--L720--64%--------------- + -:**- TUTORIAL 62% L759 (Fundamental) -Questa riga fornisce informazioni utili sullo stato di Emacs e sul testo -che si inserisce. +Questa riga fornisce informazioni utili sullo stato di Emacs e sul +testo che si inserisce. -Abbiamo già visto cosa significa il nome del file - è il file che si sta -visitando. --NN%-- (due cifre e il segno %) indica la posizione attuale -nel testo: significa che NN percento del testo si trova sopra al margine -superiore dello schermo. Se si visualizza l'inizio del file ci sarà -scritto --Top-- (inizio) invece che --00%--. Se invece ci si trova alla -fine del file ci sarà scritto --Bot-- (fine). Se si osserva un file -talmente piccolo da essere visualizzato per intero sullo schermo allora la -"mode line" indicherà --All-- (tutto). +Abbiamo già visto cosa significa il nome del file: è il file che si +sta visitando. NN% indica la posizione attuale nel testo: significa +che NN percento del testo si trova sopra al margine superiore dello +schermo. Se si visualizza l'inizio del file ci sarà scritto “Top” +(inizio) invece che “ 0%”. Se invece ci si trova alla fine del file +ci sarà scritto “Bot” (fine). Se si osserva un file talmente piccolo +da essere visualizzato per intero sullo schermo allora la mode line +indicherà “All” (tutto). La lettera L e le cifre indicano il numero di riga (Line) del punto indicato dal cursore in quel momento. I due asterischi vicino all'inizio indicano che sono state fatte delle modifiche al testo. Se il file è stato appena aperto o appena salvato -quella parte della "mode line" non mostra alcun asterisco, solo trattini. - -La parte di "mode line" racchiusa tra parentesi serve ad indicare in quale -modo di scrittura ci si trovi. Il modo standard è "Fundamental" ed è -quello che probabilmente è attivo adesso. È un esempio di "modalità -primaria" (major mode). - -Emacs ha tanti diversi tipi di "modalità primarie". Alcuni di questi -servono per la scrittura di diversi linguaggi di programmazione e/o tipi -di testo, come la modalità Lisp, la modalità Testo, ecc. In un -determinato momento una sola "modalità primaria" alla volta può essere -attiva, e il suo nome è visualizzato sulla "mode line", proprio come -"Fundamental" lo è adesso. - -Ogni "modalità primaria" condiziona il comportamento di alcuni comandi. +quella parte della mode line non mostra alcun asterisco, solo +trattini. + +La parte di mode line racchiusa tra parentesi serve ad indicare in +quale modo di scrittura ci si trovi. Il modo standard è “Fundamental” +ed è quello che probabilmente è attivo adesso. È un esempio di +“modalità primaria” (major mode). + +Emacs ha tanti diversi tipi di modalità primarie. Alcuni di questi +servono per la scrittura di diversi linguaggi di programmazione e/o +tipi di testo, come la modalità Lisp, la modalità Testo, ecc. In +qualsiasi momento c'è una e una sola modalità primaria attiva, e il +suo nome è visualizzato sulla mode line, dove adesso c'è +“Fundamental”. + +Ogni modalità primaria condiziona il comportamento di alcuni comandi. Per esempio ci sono comandi per creare commenti in un programma e, dal momento che ogni linguaggio di programmazione ha un diverso tipo di -commento, ogni "modalità primaria" deve inserire i commenti in modo -diverso. Ogni "modalità primaria" è anche il nome di un comando esteso -con nome che serve per attivare quella "modalità primaria". Per esempio -M-x fundamental-mode è il comando per attivare la modalità primaria -"Fundamental". +commento, ogni modalità primaria deve inserire i commenti in modo +diverso. Ogni modalità primaria corrisponde al nome di un comando +esteso, con cui puoi passare a quella modalità. Per esempio M-x +fundamental-mode è il comando per attivare la modalità primaria +“Fundamental”. -Se si vuole inserire del testo in italiano, come questo file, serve -probabilmente la modalità testo ("text-mode"). +Se si vuole inserire del testo in italiano, come questo file, +probabilmente è più adeguata la modalità testo. ->> Inserisci M-x text mode<Invio>. +>> Inserisci M-x text-mode<Invio>. -Non preoccuparti, nessuno dei comandi che hai imparato verrà modificato in -modo sostanziale. Tuttavia adesso puoi osservare come M-f e M-b -considerino gli apostrofi come parti di parole. Al contrario, nella -modalità "Fundamental", M-f e M-b consideravano gli apostrofi dei -separatori di parole. +Non preoccuparti, nessuno dei comandi che hai imparato verrà +modificato in modo sostanziale. Tuttavia adesso puoi osservare come +M-f e M-b considerino gli apostrofi come parti di parole. In +precedenza, nella modalità “Fundamental”, M-f e M-b consideravano gli +apostrofi dei separatori di parole. -Le "modalità primarie" di solito producono nei comandi piccoli cambiamenti -come questo: la maggior parte di essi "fa lo stesso lavoro" ma in maniera -appena diversa. +Le modalità primarie di solito producono nei comandi piccoli +cambiamenti come quello: la maggior parte di essi “fa lo stesso +lavoro” ma in maniera un po' diversa. -Per leggere la documentazione sulla "modalità primaria" attuale si usa +Per leggere la documentazione sulla modalità primaria attuale, usa C-h m. ->> Usa C-u C-v una o più volte per portare questa riga vicino all'inizio - dello schermo. Usa C-h m per leggere come il "text-mode" (modo testo) - differisce dalla modalità "Fundamental". Premi C-x 1 per eliminare la - finestra contenente la documentazione. - -Le "modalità primarie" sono chiamate così perché ci sono anche delle -"modalità secondarie" (minor modes). Le "modalità secondarie" non sono -alternative alle "modalità primarie" ma solo piccole varianti di esse. -Ogni "modalità secondaria" può essere attivata o disattivata -indipendentemente da tutte le altre "modalità secondarie" e -indipendentemente dalla "modalità primaria" attiva in quel momento. Si -può quindi usare nessuna "modalità secondaria", una soltanto oppure ogni -altra combinazione di modalità secondarie. - -Una "modalità secondaria" molto utile, specialmente per il testo italiano, -è la modalità "Auto Fill". Quando questa modalità è attiva, Emacs -interrompe la riga tra due parole ogni volta che, nel corso -dell'inserimento, essa diventa troppo lunga. - -Si può attivare il modo "Auto Fill" con: M-x auto fill mode<Invio>. -Quando la modalità suddetta è attiva può essere disattivata con M-x auto -fill mode<Invio>. Se la modalità è disattivata questo comando la attiva, -viceversa se è già attiva. Un comando che funziona così si comporta come -un interruttore, attiva o disattiva qualcosa ogni volta che viene premuto. - ->> Usa M-x auto fill mode<Invio> adesso. Inserisci una riga di "asdf" +>> Sposta il cursore sulla riga successiva a questa. +>> Premi C-l C-l per portare questa riga in cima allo schermo. +>> Usa C-h m per leggere come la modalità Testo differisca dalla + Fundamental. +>> Premi C-x 1 per eliminare la finestra contenente la documentazione. + +Le modalità primarie sono chiamate così perché ci sono anche delle +“modalità secondarie” (minor modes). Tali modalità non sono +alternative a quelle primarie, introducono solo piccole varianti. +Ogni modalità secondaria può essere attivata o disattivata, +indipendentemente da tutte le altre modalità secondarie e +indipendentemente dalla modalità primaria attiva in quel momento. Si +può quindi usare nessuna modalità secondaria, una soltanto oppure +qualsiasi combinazione di modalità secondarie. + +Una modalità secondaria molto utile, specialmente per scrivere del +testo, è la modalità “Auto Fill” (riempimento automatico). Quando +questa modalità è attiva, Emacs interrompe la riga tra due parole ogni +volta che, nel corso dell'inserimento, essa diventa troppo lunga. + +Si può attivare il modo “Auto Fill” con M-x auto-fill-mode<Invio>. +Quando la modalità suddetta è attiva può essere disattivata eseguendo +di nuovo M-x auto-fill-mode<Invio>. Se la modalità è disattivata +questo comando la attiva, viceversa se è già attiva. Un comando che +funziona così si comporta come un interruttore, attiva o disattiva +qualcosa ogni volta che viene premuto. + +>> Usa M-x auto fill mode<Invio> adesso. Inserisci una riga di “asdf ” ripetuti fino a quando non la vedi dividersi in due righe. Devi - interporre degli spazi perché la modalità "Auto Fill" spezza le righe + interporre degli spazi perché la modalità Auto Fill spezza le righe solo in corrispondenza di uno spazio. -Il margine di solito è predisposto a 70 caratteri ma può essere spostato -con il comando C-x f. Bisogna fornire al comando l'argomento numerico del -margine che si desidera. +Il margine di solito è predisposto a 70 caratteri ma può essere +spostato con il comando C-x f. Bisogna fornire al comando l'argomento +numerico del margine che si desidera. >> Usa C-x f con un argomento di 20 (C-u 2 0 C-x f), poi inserisci del - testo e osserva come Emacs interrompe le righe a 20 caratteri. Infine - torna di nuovo a un margine di 70 caratteri con C-x f. + testo e osserva come Emacs interrompe le righe a 20 caratteri. + Infine torna di nuovo a un margine di 70 caratteri con C-x f. -Se si modifica il testo all'interno di un paragrafo la modalità -"Auto Fill" non -lo risistema. -Per risistemare i margini di un paragrafo -si usa M-q (META-q) -quando il cursore si trova in quel paragrafo. +Se si modifica il testo all'interno di un paragrafo la modalità "Auto +Fill" non lo risistema. Per risistemare i margini di un paragrafo si +usa M-q (META-q) quando il cursore si trova in quel paragrafo. >> Muovi il cursore sul paragrafo precedente e premi M-q. @@ -821,250 +878,309 @@ quando il cursore si trova in quel paragrafo. * CERCARE DEL TESTO ------------------- -Emacs può effettuare la ricerca di stringhe (che sono gruppi di caratteri -contigui o parole) in posizione sia successiva che precedente nel testo. -Cercare una stringa è un comando che provoca lo spostamento del cursore: -lo porta lì dove la stringa compare. - -Il comando di ricerca di Emacs è diverso da quello di molti altri editor -perché è "incrementale". Ciò significa che la ricerca avviene proprio -mentre si inserisce la stringa da cercare. - -I comandi per iniziare la ricerca sono C-s per quella in avanti e C-r per -quella all'indietro nel testo. ASPETTA! Non provarli ora. - -Quando si preme C-s si vede comparire il messaggio "I-search" nell'"area -di eco", ciò significa che Emacs aspetta che si indichi ciò che deve -cercare. <Invio> serve a concludere la ricerca. - ->> Adesso usa C-s per inziare la ricerca. LENTAMENTE, una lettera alla - volta, inserisci la parola "cursore", facendo una pausa dopo ogni - carattere scritto per vedere cosa succede al cursore. Hai cercato - "cursore" una volta sola. ->> Usa C-s un'altra volta per trovare il punto in cui la parola "cursore" - compare successivamente. ->> Adesso premi <Delete> quattro volte e osserva come si muove il cursore. +Emacs può effettuare la ricerca di stringhe (una “stringa” è un gruppo +di caratteri contigui) in posizione sia successiva che precedente nel +testo. Cercare una stringa è un comando che provoca lo spostamento +del cursore: lo porta lì dove la stringa compare. + +Il comando di ricerca di Emacs è diverso da quello di molti altri +editor perché è “incrementale”. Ciò significa che la ricerca avviene +proprio mentre si inserisce la stringa da cercare. + +I comandi per iniziare la ricerca sono C-s per quella in avanti e C-r +per quella all'indietro nel testo. ASPETTA! Non provarli ora. + +Quando si preme C-s si vede comparire il messaggio “I-search” +nell'area di eco: ciò significa che Emacs aspetta che si indichi ciò +che deve cercare. <Invio> serve a concludere la ricerca. + +>> Adesso usa C-s per iniziare la ricerca. LENTAMENTE, una lettera + alla volta, inserisci la parola “cursore”, facendo una pausa dopo + ogni carattere scritto per vedere cosa succede al cursore. Hai + cercato “cursore”, una volta sola. +>> Usa C-s un'altra volta per trovare la successiva occorrenza della + parola “cursore”. +>> Adesso premi <DEL> quattro volte e osserva come si muove il cursore. >> Premi <Invio> per concludere la ricerca. -Hai visto cos'è successo? Durante una ricerca incrementale Emacs prova ad -andare al punto successivo in cui compare la stringa indicata fino a quel -momento. Per raggiungere il punto successivo in cui compare di nuovo -"cursore" basta solo premere C-s ancora una volta. Se la stringa cercata -non compare in alcun punto successivo Emacs emette un "beep" e informa che -la ricerca non è andata a buon fine ("failing"). C-g è un modo -alternativo per concludere la ricerca. - -NOTA: su alcuni sistemi il comando C-s bloccherà lo schermo e poi non si -vedrà alcun altro messaggio da Emacs. Questo significa che una -caratteristica del sistema operativo chiamata "controllo di flusso" sta -intercettando il carattere C-s e non gli permette di arrivare fino ad -Emacs. Per sbloccare lo schermo si può usare C-q. Poi si legga la -sezione "Spontaneous Entry to Incremental Search" nel manuale di Emacs per -suggerimenti su come gestire questa caratteristica del proprio sistema. - -Se durante una ricerca incrementale si preme il tasto <Delete> ci si -accorgerà che l'ultimo carattere della stringa da cercare scompare e la -ricerca torna all'ultimo risultato trovato prima che fosse stato scritto. -Per esempio, supponiamo di aver battuto una "c" e di aver trovato la prima -"c" che compare nel testo. Se poi aggiungiamo una "u" il cursore si -sposta alla prima stringa "cu" che trova. Ora se si preme <Delete> la "u" -viene cancellata dalla stringa da cercare e il cursore torna sulla "c" che -era stata trovata in precedenza. +Hai visto cos'è successo? Durante una ricerca incrementale Emacs +prova ad andare al punto successivo in cui compare la stringa indicata +fino a quel momento. Per raggiungere il punto successivo in cui +compare di nuovo “cursore” basta solo premere C-s ancora una volta. +Se la stringa cercata non compare in alcun punto successivo Emacs +emette un “beep” e informa che la ricerca non è andata a buon fine +(“failing”). C-g è un modo alternativo per concludere la ricerca. + +Se durante una ricerca incrementale si preme il tasto <DEL> ci si +accorgerà che l'ultimo carattere della stringa da cercare scompare e +la ricerca torna all'ultimo risultato trovato prima che fosse stato +scritto. Per esempio, supponiamo di aver battuto una “c” e di aver +trovato la prima “c” che compare nel testo. Se poi aggiungiamo una +“u” il cursore si sposta alla prima stringa “cu” che trova. Ora se si +preme <DEL> la “u” viene rimossa dalla stringa da cercare e il cursore +torna sulla “c” trovata in precedenza. Se ci si trova nel mezzo di una operazione di ricerca e si usa un -carattere control o meta (con poche eccezioni - i caratteri che hanno -significato particolare durante la ricerca sono C-s e C-r) allora la +carattere control o meta (con poche eccezioni, caratteri che hanno +significato particolare durante la ricerca come C-s e C-r) allora la ricerca viene conclusa. -Il comando C-s inizia la ricerca di ogni presenza della stringa in -posizione SUCCESSIVA a quella attuale del cursore. Se si vuole cercare -qualcosa che nel testo precede il cursore allora bisogna usare il comando -C-r. Tutto quello che abbiamo detto su C-s si applica allo stesso modo -per C-r, invertendo ovviamente la direzione di ricerca. +Il comando C-s inizia la ricerca di ogni occorrenza della stringa in +posizione SUCCESSIVA a quella attuale del cursore. Se si vuole +cercare qualcosa che nel testo precede il cursore allora bisogna usare +il comando C-r. Tutto quello che abbiamo detto su C-s si applica allo +stesso modo per C-r, invertendo ovviamente la direzione di ricerca. * FINESTRE MULTIPLE ------------------- Una delle caratteristiche interessanti di Emacs è che si possono -visualizzare più finestre sullo schermo nello stesso momento. +visualizzare più finestre sullo schermo nello stesso momento. (Nota +che Emacs utilizza il termine “frame”, descritto nella sezione +successiva, per indicare quello che altre applicazioni chiamano +“window”. Il manuale di Emacs contiene un Glossario dei termini usati +da Emacs.) + +>> Muovi il cursore su questa riga e inserisci C-l C-l. ->> Muovi il cursore su questa riga e inserisci C-u 0 C-l (è CONTROL-L, non - CONTROL-1). >> Adesso usa C-x 2 che divide lo schermo in due parti. Entrambe le finestre visualizzano questo tutorial. Il cursore si trova nella finestra superiore. + >> Premi C-M-v per far scorrere la finestra inferiore. (Se non hai un tasto META usa <ESC> C-v.) + >> Usa C-x o per muovere il cursore nella finestra inferiore. >> Usa C-v e M-v nella finestra inferiore per farvi scorrere il testo. Continua a leggere queste indicazioni nella finestra superiore. ->> Premi C-x o di nuovo per muovere il cursore nella finestra superiore. - Il cursore si trova sul punto che occupava in precedenza. -Si può continuare a usare C-x o per andare da una finestra all'altra. Ogni -finestra ha la sua posizione per il cursore ma solo una alla volta lo -visualizza. Tutti i comandi impartiti funzionano sulla finestra in cui si -trova il cursore. Noi la chiamiamo la "finestra selezionata". +>> Premi C-x o di nuovo per muovere il cursore nella finestra + superiore. Il cursore si trova sul punto che occupava in + precedenza. + +Puoi continuare a usare C-x o per andare da una finestra all'altra. +La “finestra selezionata”, dove avvengono le modifiche, è quella con +un cursore che lampeggia quando non stai scrivendo. Le altre finestre +conservano la loro posizione del cursore; se stai usando un terminale +grafico, quei cursori appaiono come dei rettangoli vuoi e non +lampeggianti. Il comando C-M-v è molto utile quando si inserisce del testo in una -finestra mentre si usa l'altra solo come riferimento. Si può tenere il -cursore sempre nella finestra in cui si lavora e portare avanti -sequenzialmente il testo contenuto nell'altra con C-M-v. +finestra mentre si usa l'altra solo come riferimento. Si può tenere +il cursore sempre nella finestra in cui si lavora e far scorrere il +testo contenuto nell'altra con C-M-v. -C-M-v è un esempio di carattere CONTROL-META. Se c'è un vero e proprio -tasto META si può ottenere C-M-v tenendo premuti contemporaneamente -CONTROL e META mentre si batte v. Non importa quale tra CONTROL e META -viene premuto per primo perché essi agiscono assieme modificando i -caratteri inseriti dopo. +C-M-v è un esempio di carattere CONTROL-META. Se c'è un vero e +proprio tasto META si può ottenere C-M-v tenendo premuti +contemporaneamente CONTROL e META mentre si batte v. Non importa +quale tra CONTROL e META viene premuto per primo perché essi agiscono +assieme modificando i caratteri inseriti dopo. Se non c'è un tasto META e si usa il tasto ESC l'ordine diventa -importante: bisogna premere prima <ESC> e poi farlo seguire da CONTROL-v -perché CONTROL-ESC-v non funziona. Questo perché <ESC> è un carattere a -sé stante e non uno che ne modifica altri. +importante: bisogna premere prima <ESC> e poi farlo seguire da +CONTROL-v perché CONTROL-ESC-v non funziona. Questo perché <ESC> è un +carattere a sé stante e non uno che ne modifica altri. >> Usa C-x 1 (nella finestra superiore) per eliminare la finestra inferiore. (Se usi C-x 1 nella finestra inferiore allora viene eliminata quella -superiore. Questo comando conserva una sola finestra, quella in cui si -trova il cursore.) +superiore. Pensa a questo comando come “conserva una sola finestra, +quella attualmente selezionata.”) + +Non devi necessariamente visualizzare il medesimo buffer in entrambe +le finestre. Se usi C-x C-f per visitare un file in una finestra, il +contenuto dell'altra non cambia. Si può visitare in modo indipendente +un file diverso in ogni finestra. -Due finestre aperte contemporaneamente non devono necessariamente -contenere lo stesso buffer. Quando si usa C-x C-f per visitare un file in -una finestra il contenuto dell'altra non cambia. Si può "visitare" in -modo indipendente un file diverso in ogni finestra. +Ecco un altro modo per usare due finestre per visualizzare cose +diverse: -Ecco un altro modo per usare due finestre per visualizzare cose diverse: +>> Inserisci C-x 4 C-f seguito dal nome di uno dei tuoi file e termina + con <Invio>. Osserva come il file viene aperto nella finestra + inferiore e il cursore venga posizionato là. ->> Inserisci C-x 4 C-f seguito dal nome di uno dei tuoi file. Premi - <Invio>. Osserva come il file viene aperto nella finestra inferiore. - Il cursore si posiziona in quella. >> Usa C-x o per tornare alla finestra superiore e C-x 1 per eliminare quella inferiore. +* FRAME MULTIPLI +---------------- + +Emacs può anche creare dei “frame” multipli. Un frame il nome che +diamo a una collezione di finestre, insieme con il suo menu, le barre +di scorrimento, l'area di eco, ecc. Su un terminale grafico, Emacs +chiama “frame” quello che la maggior parte delle altre applicazioni +chiamano “finestra”, ed è possibile mostrarne più di uno +contemporaneamente. Su un terminale testuale, è possibile mostrare un +solo frame alla volta. + +>> Usa M-x make-frame<Invio>. + Un nuovo frame dovrebbe apparire sullo schermo. + +In questo nuovo frame puoi svolgere qualsiasi cosa come nel frame +originale. Non c'è nulla di speciale nel primo frame. + +>> Usa M-x delete-frame<Invio>. + Questo rimuove il frame selezionato. + +Puoi anche eliminare un frame usando i metodi offerti dal sistema +grafico (normalmente cliccando sul pulsante “X” in uno degli angoli +superiori del frame). Se rimuovi in questo modo l'ultimo frame, la +sessione Emacs viene terminata. + + * LIVELLI DI EDITING RICORSIVO ------------------------------ -A volte ci si può trovare in quello che si chiama un "livello di editing -ricorsivo", ciò è indicato dalla presenza di parentesi quadre nella "mode -line", attorno alle parentesi della "modalità primaria" attualmente in -uso. Per esempio si potrebbe leggere [(Fundamental)] invece che -(Fundamental). +A volte ci si può trovare in quello che si chiama un “livello di +editing ricorsivo”: ciò è indicato dalla presenza di parentesi quadre +nella mode line, attorno alle parentesi che delimitano il nome della +modalità primaria. Per esempio si potrebbe leggere [(Fundamental)] +invece che (Fundamental). -Per uscire dal livello di editing ricorsivo si usa <ESC> <ESC> <ESC>. È -un comando di uscita di uso piuttosto generale, si può anche usare per -eliminare finestre in più e per uscire dal "minibuffer". +Per uscire dal livello di editing ricorsivo si usa <ESC> <ESC> <ESC>. +È un comando di uscita di uso piuttosto generale, si può anche usare +per eliminare finestre in più e per uscire dal minibuffer. >> Usa M-x per entrare nel "minibuffer": poi usa <ESC> <ESC> <ESC> per uscirne. -Non è possibile usare C-g per uscire da un livello di editing ricorsivo, -ciò avviene perché C-g è usato per annullare i comandi all'INTERNO del +Non è possibile usare C-g per uscire da un livello di editing +ricorsivo, perché C-g è usato per annullare i comandi all'INTERNO del livello di editing ricorsivo. * COME IMPARARE ALTRO --------------------- -In questo tutorial abbiamo provato a fornire le informazioni sufficienti -per iniziare ad usare Emacs. Ci sono così tante opzioni in Emacs che -sarebbe impossibile spiegarle tutte qui, ma è possibile imparare tutte le -altre caratteristiche di Emacs utili per il proprio lavoro. Ci sono -comandi per leggere la documentazione dei comandi disponibili in Emacs. -Questi comandi di aiuto iniziano tutti con il carattere C-h, che infatti è -chiamato "carattere di aiuto (help)". +In questo tutorial abbiamo provato a fornire le informazioni +sufficienti per iniziare ad usare Emacs. Ci sono così tante opzioni +in Emacs che sarebbe impossibile spiegarle tutte qui. Tuttavia +potresti voler saperne di più su Emacs, che offre molte altre utili +funzionalità. Ci sono comandi per leggere la documentazione dei +comandi disponibili in Emacs. Questi comandi di “aiuto” iniziano +tutti con il carattere C-h, che infatti è chiamato “carattere di aiuto +(help)”. + +Per raggiungere le voci di Aiuto si usa il carattere C-h e poi un +altro carattere che specifica la richiesta. Quando davvero non si sa +cosa fare si può provare con C-h ? ed Emacs indicherà tutti i tipi di +aiuto che può fornire. Se si è attivato l'aiuto con C-h e si decide +che non serve più si può annullare la richiesta con C-g. -Per raggiungere le voci di Aiuto si usa il carattere C-h e poi un altro -carattere che specifica la richiesta. Quando davvero non si sa cosa fare -si può provare con C-h ? ed Emacs indicherà tutti i tipi di aiuto che può -fornire. Se si è attivato l'aiuto con C-h e si decide che non serve più -si può annullare la richiesta con C-g. +(Se C-h non mostra un messaggio relativo all'aiuto nella parte bassa +dello schermo, prova ad usare il tasto F1 oppure con M-x help<Invio>.) -Alcuni sistemi fanno un diverso uso del carattere C-h perché questo viene -indebitamente modificato dall'amministratore di sistema. A parte -rivolgerti allo stesso perché risolva il problema puoi provare ad accedere -alla funzione aiuto di Emacs con il tasto F1 oppure con M-x help<Invio>. +La forma base di aiuto è data da C-h c. Si inserisce C-h, il +carattere c e poi un carattere o una sequenza di caratteri; Emacs +mostrerà una breve descrizione del comando stesso. -La forma base di aiuto è data da C-h c. Si inserisce C-h, il carattere c -e poi un carattere o una sequenza di caratteri; Emacs mostrerà una breve -descrizione del comando stesso. +>> Prova C-h c C-p. ->> Prova C-h c C-p. Dovresti leggere un messaggio del tipo +Dovresti leggere un messaggio del tipo (purtroppo in inglese!): - C-p runs the command previous-line (purtroppo in inglese!) + C-p runs the command previous-line -Questo messaggio indica il "nome della funzione". I nomi di funzione sono -usati principalmente per personalizzare ed estendere Emacs e sono scelti -anche in modo da indicare che cosa il comando fa. Servono quindi anche da -breve descrizione, sufficiente per ricordarsi di comandi già imparati. +Questo messaggio indica il “nome della funzione”. Dal momento che i +nomi di funzione sono scelti per indicare cosa fa il comando, servono +quindi anche come breve descrizione, sufficiente per ricordarsi di +comandi già imparati. -I comandi con più caratteri come ad esempio C-x C-s e (se non c'è il tasto -META o EDIT o ALT) <ESC>v sono permessi allo stesso modo dopo una -richiesta di aiuto fatta con C-h c. +I comandi con più caratteri come ad esempio C-x C-s e (se non c'è il +tasto META o EDIT o ALT) <ESC>v sono permessi allo stesso modo dopo +una richiesta di aiuto fatta con C-h c. -Per avere ulteriori informazioni su un comando si usa C-h k invece che C-h -c. +Per avere ulteriori informazioni su un comando si usa C-h k invece che +C-h c. >> Prova C-h k C-p. -Questo mostrerà la documentazione della funzione, così come il suo nome, -all'interno di una finestra di Emacs. Quando hai finito di leggere usa -C-x 1 per eliminare la finestra con il testo di aiuto. Non sei obbligato -a farlo subito. Puoi anche lavorare sul tuo testo mentre fai riferimento -al testo di aiuto e poi usare un C-x 1. +Questo mostrerà la documentazione della funzione, così come il suo +nome, all'interno di una finestra di Emacs. Quando hai finito di +leggere usa C-x 1 per eliminare la finestra con il testo di aiuto. +Non sei obbligato a farlo subito. Puoi anche lavorare sul tuo testo +mentre fai riferimento al testo di aiuto e poi usare un C-x 1. Ecco altre utili opzioni di C-h: - C-h f Descrive una funzione. Inserisci il nome della funzione. + C-h f Descrive una funzione. Inserisci il nome della funzione. ->> Prova con C-h f previous-line<Invio>. Avrai tutte le informazioni che - Emacs possiede sulla funzione che implementa il comando C-p. +>> Prova con C-h f previous-line<Invio>. + Questo mostrerà tutte le informazioni che Emacs possiede sulla + funzione che implementa il comando C-p. -Un comando simile è C-h v che mostra la documentazione di variabili i cui -valori sono utilizzati per personalizzare il comportamento di Emacs. Devi -inserire il nome della variabile quando Emacs lo richiede. +Un comando simile è C-h v che mostra la documentazione delle +variabili, comprese quelle di cui puoi modificare il valore per +personalizzare il comportamento di Emacs. Devi inserire il nome della +variabile quando Emacs lo richiede. - C-h a "Apropos" comando. Inserisci una parola ed Emacs ti - elencherà tutti i comandi il cui nome contiene quella - parola. Questi comandi possono tutti essere eseguiti con - META-x. Per alcuni comandi ti sarà mostrata anche una - sequenza di uno o due caratteri che serve a far partire il - comando senza doverlo inserire per esteso. + C-h a "Apropos" comando. Inserisci una parola ed Emacs ti + elencherà tutti i comandi il cui nome contiene quella + parola. Questi comandi possono tutti essere eseguiti + con META-x. Per alcuni comandi ti sarà mostrata anche + una sequenza di uno o due caratteri che serve a far + partire il comando senza doverlo inserire per esteso. >> Prova C-h a file<Invio> Questo mostrerà in un'altra finestra una lista di tutti i comandi che -contengono la parola "file" nel nome. Nella lista si vedranno -comandi-carattere, come C-x C-f, assieme ai corrispondenti nomi per esteso -come "find-file". +contengono la parola “file” nel nome. Nella lista si vedranno +comandi-carattere, come C-x C-f, assieme ai corrispondenti nomi per +esteso come find-file. + +>> Usa C-M-v per far scorrere il testo nella finestra di aiuto. + Ripeti per alcune volte. ->> Usa C-M-v per far scorrere il testo nella finestra di aiuto. Ripeti - per alcune volte. >> Usa C-x 1 per eliminare la finestra di aiuto. - C-h i Leggi la documentazione. Questo comando apre un buffer - speciale chiamato "*info*" in cui puoi leggere i manuali - on-line dei pacchetti installati sul tuo sistema. Batti m - emacs <Invio> per leggere il manuale di Emacs. Se non hai - mai usato il sistema Info prima d'ora premi ? ed Emacs ti - guiderà nell'uso delle opzioni del modo Info. Una volta - terminata questa esercitazione il manuale di Emacs contenuto - nel sistema Info dovrebbe diventare la tua principale fonte - di documentazione. + C-h i Leggi la documentazione. Questo comando apre un + buffer speciale chiamato “*info*” in cui puoi leggere + i manuali on-line dei pacchetti installati sul tuo + sistema. Batti m emacs<Invio> per leggere il manuale + di Emacs. Se non hai mai usato il sistema Info prima + d'ora premi ? ed Emacs ti guiderà nell'uso delle + opzioni del modo Info. Una volta terminata questa + esercitazione il manuale di Emacs contenuto nel + sistema Info dovrebbe diventare la tua principale + fonte di documentazione. + + +* ALTRE FUNZIONALITÀ +-------------------- + +Puoi imparare di più su Emacs leggendo il suo manuale, sia nella forma +stampata piuttosto che da dentro Emacs stesso (usa il menu Help oppure +C-h r). Due funzionalità che possono farti comodo sono il +completamento automatico, che consente di ridurre il numero di +caratteri da digitare, e dired, che semplifica la gestione dei file. + +Il completamento è un modo per evitare la pressione di tasti quando +non sia necessario. Ad esempio, quando vuoi passare al buffer +*Messages*, puoi inserire C-x b *M<Tab> e Emacs cercherà di completare +il nome del buffer usando la parte che hai già inserito. Questa +funzione può essere usata anche sui nomi dei comandi oppure su quelli +dei file, ed è descritta nel manuale Emacs nel nodo chiamato +“Completion”. + +Dired ti consente di elencare i file in una directory (e opzionalmente +nelle directory sottostanti), muoverti tra quei file, visitarli, +rinominarli, cancellarli e in generale eseguire qualche operazione su +quei file. Dired è descritta nel manuale Emacs nel nodo chiamato +“Dired”. + +Il manuale descrive molte altre funzionalità di Emacs. * CONCLUSIONI ------------- -Ricorda che per chiudere una sessione di Emacs si usa C-x C-c. Per -tornare temporaneamente alla shell, così da poter rientrare in Emacs -successivamente, si usa C-z. +Per chiudere una sessione di Emacs si usa C-x C-c. -Questo documento è stato creato per essere utile a tutti i nuovi utenti, -se qualcosa per te è stato poco chiaro non dare la colpa a te stesso - -lamentati! +Questo documento è stato creato per essere utile a tutti i nuovi +utenti, se qualcosa per te è stato poco chiaro non dare la colpa a te +stesso: lamentati! * COPIA @@ -1072,8 +1188,8 @@ lamentati! La versione inglese di questo testo (disponibile nel file "TUTORIAL") deriva da una lunga serie di tutorial di Emacs che iniziò con quello -scritto da Stuart Cracraft per il primo Emacs. La versione italiana è a -cura di Alfredo Finelli (alfredofnl@tiscali.it). +scritto da Stuart Cracraft per il primo Emacs. La versione italiana è +a cura di Alfredo Finelli (alfredofnl@tiscali.it). Questo documento, come GNU Emacs, è coperto da copyright e viene distribuito con il permesso di farne copie a determinate condizioni: @@ -1082,22 +1198,23 @@ distribuito con il permesso di farne copie a determinate condizioni: secondo i quali è possibile la copia e la distribuzione di questo documento è quella originale in lingua inglese contenuta nel file "TUTORIAL". Qui di seguito se ne riporta una traduzione a scopo - indicativo, restando comunque inteso il fatto che è quella originale a - fare fede. + indicativo, restando comunque inteso il fatto che è quella + originale a fare fede. Copyright (C) 2003-2015 Free Software Foundation, Inc. - È permesso a chiunque copiare e distribuire attraverso ogni mezzo copie - fedeli di questo documento così come viene ricevuto, a condizione che - le informazioni sul copyright e sui permessi garantiti siano conservate - intatte e che il distributore riconosca a colui che riceve la copia il - diritto ad un'ulteriore distribuzione, che deve avvenire così come - definito in questa clausola. - - È permesso distribuire versioni modificate di questo documento, o di - ogni sua parte, alle condizioni indicate precedentemente, purché esse - portino chiaramente indicato il nome di colui che le ha modificate per - ultimo. + È permesso a chiunque copiare e distribuire attraverso ogni mezzo + copie fedeli di questo documento così come viene ricevuto, a + condizione che le informazioni sul copyright e sui permessi + garantiti siano conservate intatte e che il distributore riconosca + a colui che riceve la copia il diritto ad un'ulteriore + distribuzione, che deve avvenire così come definito in questa + clausola. + + È permesso distribuire versioni modificate di questo documento, o + di ogni sua parte, alle condizioni indicate precedentemente, purché + esse portino chiaramente indicato il nome di colui che le ha + modificate per ultimo. Le condizioni per copiare Emacs sono più complesse ma definite con lo stesso spirito. Per favore, leggete il file COPYING e poi distribuite diff --git a/etc/tutorials/TUTORIAL.pt_BR b/etc/tutorials/TUTORIAL.pt_BR index 619f4fc13e..5fd05170f7 100644 --- a/etc/tutorials/TUTORIAL.pt_BR +++ b/etc/tutorials/TUTORIAL.pt_BR @@ -847,7 +847,7 @@ saída do Emacs. Isso indica que um "recurso" do sistema operacional chamado "controle de fluxo" (flow control) esta interceptando o C-s e não deixando que passe pelo Emacs. Para destravar a tela, digite C-q. Então, leia na seção "Spontaneous Entry to Incremental Search" no -manual do Emacs para uma dica de como lhe dar com esse "recurso". +manual do Emacs para uma dica de como lidar com esse "recurso". Se você estiver no meio de uma pesquisa incremental e digitar <Delete>, você perceberá que o último caractere da pesquisa será apagado e a diff --git a/lib-src/etags.c b/lib-src/etags.c index 5f985b027b..3cb39689b8 100644 --- a/lib-src/etags.c +++ b/lib-src/etags.c @@ -364,6 +364,7 @@ static void PHP_functions (FILE *); static void PS_functions (FILE *); static void Prolog_functions (FILE *); static void Python_functions (FILE *); +static void Ruby_functions (FILE *); static void Scheme_functions (FILE *); static void TeX_commands (FILE *); static void Texinfo_nodes (FILE *); @@ -722,6 +723,12 @@ static const char Python_help [] = "In Python code, 'def' or 'class' at the beginning of a line\n\ generate a tag."; +static const char *Ruby_suffixes [] = + { "rb", "ruby", NULL }; +static const char Ruby_help [] = + "In Ruby code, 'def' or 'class' or 'module' at the beginning of\n\ +a line generate a tag."; + /* Can't do the `SCM' or `scm' prefix with a version number. */ static const char *Scheme_suffixes [] = { "oak", "sch", "scheme", "SCM", "scm", "SM", "sm", "ss", "t", NULL }; @@ -800,6 +807,7 @@ static language lang_names [] = { "proc", no_lang_help, plain_C_entries, plain_C_suffixes }, { "prolog", Prolog_help, Prolog_functions, Prolog_suffixes }, { "python", Python_help, Python_functions, Python_suffixes }, + { "ruby", Ruby_help, Ruby_functions, Ruby_suffixes }, { "scheme", Scheme_help, Scheme_functions, Scheme_suffixes }, { "tex", TeX_help, TeX_commands, TeX_suffixes }, { "texinfo", Texinfo_help, Texinfo_nodes, Texinfo_suffixes }, @@ -4532,6 +4540,35 @@ Python_functions (FILE *inf) } } +/* + * Ruby support + * Original code by Xi Lu <lx@shellcodes.org> (2015) + */ +static void +Ruby_functions (FILE *inf) +{ + char *cp = NULL; + + LOOP_ON_INPUT_LINES (inf, lb, cp) + { + cp = skip_spaces (cp); + if (LOOKING_AT (cp, "def") + || LOOKING_AT (cp, "class") + || LOOKING_AT (cp, "module")) + { + char *name = cp; + + /* Ruby method names can end in a '='. Also, operator overloading can + define operators whose names include '='. */ + while (!notinname (*cp) || *cp == '=') + cp++; + + make_tag (name, cp - name, true, + lb.buffer, cp - lb.buffer + 1, lineno, linecharno); + } + } +} + /* * PHP support @@ -4948,6 +4985,7 @@ Lua_functions (FILE *inf) LOOP_ON_INPUT_LINES (inf, lb, bp) { + bp = skip_spaces (bp); if (bp[0] != 'f' && bp[0] != 'l') continue; diff --git a/lib-src/pop.c b/lib-src/pop.c index c6deaf73a2..42d302026f 100644 --- a/lib-src/pop.c +++ b/lib-src/pop.c @@ -42,10 +42,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ #endif #include <pop.h> -#ifdef sun -#include <malloc.h> -#endif /* sun */ - #ifdef HESIOD #include <hesiod.h> /* diff --git a/lib/gnulib.mk b/lib/gnulib.mk index 67c7e18401..17a01af0ad 100644 --- a/lib/gnulib.mk +++ b/lib/gnulib.mk @@ -21,7 +21,7 @@ # the same distribution terms as the rest of that program. # # Generated by gnulib-tool. -# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=close --avoid=dup --avoid=fchdir --avoid=flexmember --avoid=fstat --avoid=malloc-posix --avoid=msvc-inval --avoid=msvc-nothrow --avoid=open --avoid=openat-die --avoid=opendir --avoid=raise --avoid=save-cwd --avoid=select --avoid=setenv --avoid=sigprocmask --avoid=stdarg --avoid=stdbool --avoid=threadlib --avoid=unsetenv --makefile-name=gnulib.mk --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt binary-io byteswap c-ctype c-strcase careadlinkat close-stream count-one-bits count-trailing-zeros crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr dtotimespec dup2 environ execinfo faccessat fcntl fcntl-h fdatasync fdopendir filemode fstatat fsync getloadavg getopt-gnu gettime gettimeofday gitlog-to-changelog intprops largefile lstat manywarnings memrchr mkostemp mktime pipe2 pselect pthread_sigmask putenv qcopy-acl readlink readlinkat sig2str socklen stat-time stdalign stddef stdio stpcpy strftime strtoimax strtoumax symlink sys_stat sys_time time time_r time_rz timegm timer-time timespec-add timespec-sub unsetenv update-copyright utimens vla warnings +# Reproduce by: gnulib-tool --import --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=close --avoid=dup --avoid=fchdir --avoid=flexmember --avoid=fstat --avoid=malloc-posix --avoid=msvc-inval --avoid=msvc-nothrow --avoid=open --avoid=openat-die --avoid=opendir --avoid=raise --avoid=save-cwd --avoid=select --avoid=setenv --avoid=sigprocmask --avoid=stdarg --avoid=stdbool --avoid=threadlib --avoid=unsetenv --makefile-name=gnulib.mk --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt binary-io byteswap c-ctype c-strcase careadlinkat close-stream count-one-bits count-trailing-zeros crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr dtotimespec dup2 environ execinfo faccessat fcntl fcntl-h fdatasync fdopendir filemode fstatat fsync getloadavg getopt-gnu gettime gettimeofday gitlog-to-changelog intprops largefile lstat manywarnings memrchr mkostemp mktime pipe2 pselect pthread_sigmask putenv qcopy-acl readlink readlinkat sig2str socklen stat-time stdalign stddef stdio stpcpy strftime strtoimax strtoumax symlink sys_stat sys_time time time_r time_rz timegm timer-time timespec-add timespec-sub unsetenv update-copyright utimens vla warnings MOSTLYCLEANFILES += core *.stackdump diff --git a/lib/intprops.h b/lib/intprops.h index 8fff86d437..ecafaf70e1 100644 --- a/lib/intprops.h +++ b/lib/intprops.h @@ -272,9 +272,10 @@ Example usage, assuming A and B are long int: - long int result = INT_MULTIPLY_WRAPV (a, b); - printf ("result is %ld (%s)\n", result, - INT_MULTIPLY_OVERFLOW (a, b) ? "after overflow" : "no overflow"); + if (INT_MULTIPLY_OVERFLOW (a, b)) + printf ("result would overflow\n"); + else + printf ("result is %ld (no overflow)\n", a * b); Example usage with WRAPV flavor: diff --git a/lisp/calendar/cal-html.el b/lisp/calendar/cal-html.el index 4bddc38489..8c46e3ade7 100644 --- a/lisp/calendar/cal-html.el +++ b/lisp/calendar/cal-html.el @@ -32,6 +32,7 @@ ;;; Code: (require 'calendar) +(require 'diary-lib) (defgroup calendar-html nil @@ -358,12 +359,12 @@ of holidays, rather than diary entries." ;; Monthly calendar ;;------------------------------------------------------------ -(autoload 'diary-list-entries "diary-lib") - (defun cal-html-list-diary-entries (d1 d2) "Generate a list of all diary-entries from absolute date D1 to D2." - (diary-list-entries (calendar-gregorian-from-absolute d1) - (1+ (- d2 d1)) t)) + (if (with-demoted-errors "Not adding diary entries: %S" + (diary-check-diary-file)) + (diary-list-entries (calendar-gregorian-from-absolute d1) + (1+ (- d2 d1)) t))) (defun cal-html-insert-agenda-days (month year diary-list holiday-list) "Insert HTML commands for a range of days in monthly calendars. diff --git a/lisp/calendar/diary-lib.el b/lisp/calendar/diary-lib.el index 93891bf2f1..0720d8266a 100644 --- a/lisp/calendar/diary-lib.el +++ b/lisp/calendar/diary-lib.el @@ -909,13 +909,15 @@ This is recursive; that is, included files may include other files." (append diary-entries-list (diary-list-entries original-date number t))))) (display-warning - :error + 'diary (format-message "Can't read included diary file %s\n" - diary-file))) + diary-file) + :error)) (display-warning - :error + 'diary (format-message "Can't find included diary file %s\n" - diary-file))))) + diary-file) + :error)))) (goto-char (point-min))) (defun diary-include-other-diary-files () @@ -1410,11 +1412,12 @@ marks. This is intended to deal with deleted diary entries." (eval (car (read-from-string sexp))) (error (display-warning - :error + 'diary (format "Bad diary sexp at line %d in %s:\n%s\n\ Error: %s\n" (count-lines (point-min) (point)) - diary-file sexp err)) + diary-file sexp err) + :error) nil)))))) (cond ((stringp result) result) ((and (consp result) diff --git a/lisp/calendar/holidays.el b/lisp/calendar/holidays.el index 307ab4deb8..3e7289bb03 100644 --- a/lisp/calendar/holidays.el +++ b/lisp/calendar/holidays.el @@ -346,9 +346,10 @@ The holidays are those in the list `calendar-holidays'." (eval p) (error (display-warning - :error + 'holidays (format "Bad holiday list item: %s\nError: %s\n" - p err)) + p err) + :error) nil)))) (setq res (append h res)))) 'calendar-date-compare))) diff --git a/lisp/calendar/icalendar.el b/lisp/calendar/icalendar.el index 0c7a0636b0..ca6669d0c4 100644 --- a/lisp/calendar/icalendar.el +++ b/lisp/calendar/icalendar.el @@ -321,18 +321,29 @@ other sexp entries are enumerated in any case." "Return a new buffer containing the unfolded contents of a buffer. Folding is the iCalendar way of wrapping long lines. In the created buffer all occurrences of CR LF BLANK are replaced by the -empty string. Argument FOLDED-ICAL-BUFFER is the unfolded input +empty string. Argument FOLDED-ICAL-BUFFER is the folded input buffer." (let ((unfolded-buffer (get-buffer-create " *icalendar-work*"))) (save-current-buffer (set-buffer unfolded-buffer) (erase-buffer) (insert-buffer-substring folded-ical-buffer) + (icalendar--clean-up-line-endings) (goto-char (point-min)) (while (re-search-forward "\r?\n[ \t]" nil t) (replace-match "" nil nil))) unfolded-buffer)) +(defun icalendar--clean-up-line-endings () + "Replace DOS- and MAC-like line endings with unix line endings. +All occurrences of (CR LF) and (LF CF) are replaced with LF in +the current buffer. This is necessary in buffers which contain a +mix of different line endings." + (save-excursion + (goto-char (point-min)) + (while (re-search-forward "\r\n\\|\n\r" nil t) + (replace-match "\n" nil nil)))) + (defsubst icalendar--rris (regexp rep string &optional fixedcase literal) "Replace regular expression in string. Pass arguments REGEXP REP STRING FIXEDCASE LITERAL to diff --git a/lisp/emacs-lisp/ert.el b/lisp/emacs-lisp/ert.el index d572d544e1..02ae41b9c6 100644 --- a/lisp/emacs-lisp/ert.el +++ b/lisp/emacs-lisp/ert.el @@ -374,9 +374,9 @@ Returns nil." Determines whether CONDITION matches TYPE and EXCLUDE-SUBTYPES, and aborts the current test as failed if it doesn't." (let ((signaled-conditions (get (car condition) 'error-conditions)) - (handled-conditions (cl-etypecase type - (list type) - (symbol (list type))))) + (handled-conditions (pcase-exhaustive type + ((pred listp) type) + ((pred symbolp) (list type))))) (cl-assert signaled-conditions) (unless (cl-intersection signaled-conditions handled-conditions) (ert-fail (append @@ -466,18 +466,18 @@ Errors during evaluation are caught and handled like nil." (defun ert--explain-format-atom (x) "Format the atom X for `ert--explain-equal'." - (cl-typecase x - (character (list x (format "#x%x" x) (format "?%c" x))) - (fixnum (list x (format "#x%x" x))) - (t x))) + (pcase x + ((pred characterp) (list x (format "#x%x" x) (format "?%c" x))) + ((pred integerp) (list x (format "#x%x" x))) + (_ x))) (defun ert--explain-equal-rec (a b) "Return a programmer-readable explanation of why A and B are not `equal'. Returns nil if they are." (if (not (equal (type-of a) (type-of b))) `(different-types ,a ,b) - (cl-etypecase a - (cons + (pcase-exhaustive a + ((pred consp) (let ((a-proper-p (ert--proper-list-p a)) (b-proper-p (ert--proper-list-p b))) (if (not (eql (not a-proper-p) (not b-proper-p))) @@ -502,24 +502,26 @@ Returns nil if they are." `(cdr ,cdr-x) (cl-assert (equal a b) t) nil)))))))) - (array (if (not (equal (length a) (length b))) - `(arrays-of-different-length ,(length a) ,(length b) - ,a ,b - ,@(unless (char-table-p a) - `(first-mismatch-at - ,(cl-mismatch a b :test 'equal)))) - (cl-loop for i from 0 - for ai across a - for bi across b - for xi = (ert--explain-equal-rec ai bi) - do (when xi (cl-return `(array-elt ,i ,xi))) - finally (cl-assert (equal a b) t)))) - (atom (if (not (equal a b)) - (if (and (symbolp a) (symbolp b) (string= a b)) - `(different-symbols-with-the-same-name ,a ,b) - `(different-atoms ,(ert--explain-format-atom a) - ,(ert--explain-format-atom b))) - nil))))) + ((pred arrayp) + (if (not (equal (length a) (length b))) + `(arrays-of-different-length ,(length a) ,(length b) + ,a ,b + ,@(unless (char-table-p a) + `(first-mismatch-at + ,(cl-mismatch a b :test 'equal)))) + (cl-loop for i from 0 + for ai across a + for bi across b + for xi = (ert--explain-equal-rec ai bi) + do (when xi (cl-return `(array-elt ,i ,xi))) + finally (cl-assert (equal a b) t)))) + ((pred atom) + (if (not (equal a b)) + (if (and (symbolp a) (symbolp b) (string= a b)) + `(different-symbols-with-the-same-name ,a ,b) + `(different-atoms ,(ert--explain-format-atom a) + ,(ert--explain-format-atom b))) + nil))))) (defun ert--explain-equal (a b) "Explainer function for `equal'." @@ -694,23 +696,20 @@ and is displayed in front of the value of MESSAGE-FORM." (print-level 8) (print-length 50)) (dolist (frame backtrace) - (cl-ecase (car frame) - ((nil) + (pcase-exhaustive frame + (`(nil ,special-operator . ,arg-forms) ;; Special operator. - (cl-destructuring-bind (special-operator &rest arg-forms) - (cdr frame) - (insert - (format " %S\n" (cons special-operator arg-forms))))) - ((t) + (insert + (format " %S\n" (cons special-operator arg-forms)))) + (`(t ,fn . ,args) ;; Function call. - (cl-destructuring-bind (fn &rest args) (cdr frame) - (insert (format " %S(" fn)) - (cl-loop for firstp = t then nil - for arg in args do - (unless firstp - (insert " ")) - (insert (format "%S" arg))) - (insert ")\n"))))))) + (insert (format " %S(" fn)) + (cl-loop for firstp = t then nil + for arg in args do + (unless firstp + (insert " ")) + (insert (format "%S" arg))) + (insert ")\n")))))) ;; A container for the state of the execution of a single test and ;; environment data needed during its execution. @@ -894,33 +893,32 @@ t -- Always matches. RESULT." ;; It would be easy to add `member' and `eql' types etc., but I ;; haven't bothered yet. - (cl-etypecase result-type - ((member nil) nil) - ((member t) t) - ((member :failed) (ert-test-failed-p result)) - ((member :passed) (ert-test-passed-p result)) - ((member :skipped) (ert-test-skipped-p result)) - (cons - (cl-destructuring-bind (operator &rest operands) result-type - (cl-ecase operator - (and - (cl-case (length operands) - (0 t) - (t - (and (ert-test-result-type-p result (car operands)) - (ert-test-result-type-p result `(and ,@(cdr operands))))))) - (or - (cl-case (length operands) - (0 nil) - (t - (or (ert-test-result-type-p result (car operands)) - (ert-test-result-type-p result `(or ,@(cdr operands))))))) - (not - (cl-assert (eql (length operands) 1)) - (not (ert-test-result-type-p result (car operands)))) - (satisfies - (cl-assert (eql (length operands) 1)) - (funcall (car operands) result))))))) + (pcase-exhaustive result-type + ('nil nil) + ('t t) + (:failed (ert-test-failed-p result)) + (:passed (ert-test-passed-p result)) + (:skipped (ert-test-skipped-p result)) + (`(,operator . ,operands) + (cl-ecase operator + (and + (cl-case (length operands) + (0 t) + (t + (and (ert-test-result-type-p result (car operands)) + (ert-test-result-type-p result `(and ,@(cdr operands))))))) + (or + (cl-case (length operands) + (0 nil) + (t + (or (ert-test-result-type-p result (car operands)) + (ert-test-result-type-p result `(or ,@(cdr operands))))))) + (not + (cl-assert (eql (length operands) 1)) + (not (ert-test-result-type-p result (car operands)))) + (satisfies + (cl-assert (eql (length operands) 1)) + (funcall (car operands) result)))))) (defun ert-test-result-expected-p (test result) "Return non-nil if TEST's expected result type matches RESULT." @@ -961,95 +959,96 @@ as (satisfies ...), strings, :new, etc. make use of UNIVERSE. Selectors that do not, such as (member ...), just return the set implied by them without checking whether it is really contained in UNIVERSE." - ;; This code needs to match the etypecase in + ;; This code needs to match the cases in ;; `ert-insert-human-readable-selector'. - (cl-etypecase selector - ((member nil) nil) - ((member t) (cl-etypecase universe - (list universe) - ((member t) (ert-select-tests "" universe)))) - ((member :new) (ert-select-tests - `(satisfies ,(lambda (test) - (null (ert-test-most-recent-result test)))) - universe)) - ((member :failed) (ert-select-tests - `(satisfies ,(lambda (test) - (ert-test-result-type-p - (ert-test-most-recent-result test) - ':failed))) - universe)) - ((member :passed) (ert-select-tests - `(satisfies ,(lambda (test) - (ert-test-result-type-p - (ert-test-most-recent-result test) - ':passed))) - universe)) - ((member :expected) (ert-select-tests - `(satisfies - ,(lambda (test) - (ert-test-result-expected-p - test - (ert-test-most-recent-result test)))) - universe)) - ((member :unexpected) (ert-select-tests `(not :expected) universe)) - (string - (cl-etypecase universe - ((member t) (mapcar #'ert-get-test - (apropos-internal selector #'ert-test-boundp))) - (list (cl-remove-if-not (lambda (test) - (and (ert-test-name test) - (string-match selector - (symbol-name - (ert-test-name test))))) - universe)))) - (ert-test (list selector)) - (symbol + (pcase-exhaustive selector + ('nil nil) + ('t (pcase-exhaustive universe + ((pred listp) universe) + (`t (ert-select-tests "" universe)))) + (:new (ert-select-tests + `(satisfies ,(lambda (test) + (null (ert-test-most-recent-result test)))) + universe)) + (:failed (ert-select-tests + `(satisfies ,(lambda (test) + (ert-test-result-type-p + (ert-test-most-recent-result test) + ':failed))) + universe)) + (:passed (ert-select-tests + `(satisfies ,(lambda (test) + (ert-test-result-type-p + (ert-test-most-recent-result test) + ':passed))) + universe)) + (:expected (ert-select-tests + `(satisfies + ,(lambda (test) + (ert-test-result-expected-p + test + (ert-test-most-recent-result test)))) + universe)) + (:unexpected (ert-select-tests `(not :expected) universe)) + ((pred stringp) + (pcase-exhaustive universe + (`t (mapcar #'ert-get-test + (apropos-internal selector #'ert-test-boundp))) + ((pred listp) + (cl-remove-if-not (lambda (test) + (and (ert-test-name test) + (string-match selector + (symbol-name + (ert-test-name test))))) + universe)))) + ((pred ert-test-p) (list selector)) + ((pred symbolp) (cl-assert (ert-test-boundp selector)) (list (ert-get-test selector))) - (cons - (cl-destructuring-bind (operator &rest operands) selector - (cl-ecase operator - (member - (mapcar (lambda (purported-test) - (cl-etypecase purported-test - (symbol (cl-assert (ert-test-boundp purported-test)) - (ert-get-test purported-test)) - (ert-test purported-test))) - operands)) - (eql - (cl-assert (eql (length operands) 1)) - (ert-select-tests `(member ,@operands) universe)) - (and - ;; Do these definitions of AND, NOT and OR satisfy de - ;; Morgan's laws? Should they? - (cl-case (length operands) - (0 (ert-select-tests 't universe)) - (t (ert-select-tests `(and ,@(cdr operands)) - (ert-select-tests (car operands) - universe))))) - (not - (cl-assert (eql (length operands) 1)) - (let ((all-tests (ert-select-tests 't universe))) - (cl-set-difference all-tests - (ert-select-tests (car operands) - all-tests)))) - (or - (cl-case (length operands) - (0 (ert-select-tests 'nil universe)) - (t (cl-union (ert-select-tests (car operands) universe) - (ert-select-tests `(or ,@(cdr operands)) - universe))))) - (tag - (cl-assert (eql (length operands) 1)) - (let ((tag (car operands))) - (ert-select-tests `(satisfies - ,(lambda (test) - (member tag (ert-test-tags test)))) - universe))) - (satisfies - (cl-assert (eql (length operands) 1)) - (cl-remove-if-not (car operands) - (ert-select-tests 't universe)))))))) + (`(,operator . ,operands) + (cl-ecase operator + (member + (mapcar (lambda (purported-test) + (pcase-exhaustive purported-test + ((pred symbolp) + (cl-assert (ert-test-boundp purported-test)) + (ert-get-test purported-test)) + ((pred ert-test-p) purported-test))) + operands)) + (eql + (cl-assert (eql (length operands) 1)) + (ert-select-tests `(member ,@operands) universe)) + (and + ;; Do these definitions of AND, NOT and OR satisfy de + ;; Morgan's laws? Should they? + (cl-case (length operands) + (0 (ert-select-tests 't universe)) + (t (ert-select-tests `(and ,@(cdr operands)) + (ert-select-tests (car operands) + universe))))) + (not + (cl-assert (eql (length operands) 1)) + (let ((all-tests (ert-select-tests 't universe))) + (cl-set-difference all-tests + (ert-select-tests (car operands) + all-tests)))) + (or + (cl-case (length operands) + (0 (ert-select-tests 'nil universe)) + (t (cl-union (ert-select-tests (car operands) universe) + (ert-select-tests `(or ,@(cdr operands)) + universe))))) + (tag + (cl-assert (eql (length operands) 1)) + (let ((tag (car operands))) + (ert-select-tests `(satisfies + ,(lambda (test) + (member tag (ert-test-tags test)))) + universe))) + (satisfies + (cl-assert (eql (length operands) 1)) + (cl-remove-if-not (car operands) + (ert-select-tests 't universe))))))) (defun ert--insert-human-readable-selector (selector) "Insert a human-readable presentation of SELECTOR into the current buffer." @@ -1058,26 +1057,24 @@ contained in UNIVERSE." ;; `most-recent-result' slots of test case objects in (eql ...) or ;; (member ...) selectors. (cl-labels ((rec (selector) - ;; This code needs to match the etypecase in + ;; This code needs to match the cases in ;; `ert-select-tests'. - (cl-etypecase selector - ((or (member nil t - :new :failed :passed - :expected :unexpected) - string - symbol) + (pcase-exhaustive selector + ((or + ;; 'nil 't :new :failed :passed :expected :unexpected + (pred stringp) + (pred symbolp)) selector) - (ert-test + ((pred ert-test-p) (if (ert-test-name selector) (make-symbol (format "<%S>" (ert-test-name selector))) (make-symbol "<unnamed test>"))) - (cons - (cl-destructuring-bind (operator &rest operands) selector - (cl-ecase operator - ((member eql and not or) - `(,operator ,@(mapcar #'rec operands))) - ((member tag satisfies) - selector))))))) + (`(,operator . ,operands) + (pcase operator + ((or 'member 'eql 'and 'not 'or) + `(,operator ,@(mapcar #'rec operands))) + ((or 'tag 'satisfies) + selector)))))) (insert (format "%S" (rec selector))))) diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index 6b5a202495..f60bff4a47 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el @@ -216,7 +216,7 @@ of it available such that: This variable has three possible values: nil: no packages are hidden; - `archive': only criteria (a) is used; + `archive': only criterion (a) is used; t: both criteria are used. This variable has no effect if `package-menu--hide-packages' is @@ -234,7 +234,7 @@ Each element has the form (ARCHIVE-ID . PRIORITY). When installing packages, the package with the highest version number from the archive with the highest priority is -selected. When higher versions are available from archives with +selected. When higher versions are available from archives with lower priorities, the user has to select those manually. Archives not in this list have the priority 0. @@ -829,7 +829,10 @@ untar into a directory named DIR; otherwise, signal an error." (package--make-autoloads-and-stuff pkg-desc pkg-dir) ;; Update package-alist. (let ((new-desc (package-load-descriptor pkg-dir))) - ;; FIXME: Check that `new-desc' matches `desc'! + (unless (equal (package-desc-full-name new-desc) + (package-desc-full-name pkg-desc)) + (error "The retrieved package (`%s') doesn't match what the archive offered (`%s')" + (package-desc-full-name new-desc) (package-desc-full-name pkg-desc))) ;; Activation has to be done before compilation, so that if we're ;; upgrading and macros have changed we load the new definitions ;; before compiling. @@ -923,11 +926,12 @@ untar into a directory named DIR; otherwise, signal an error." ;;;; Compilation (defvar warning-minimum-level) (defun package--compile (pkg-desc) - "Byte-compile installed package PKG-DESC." + "Byte-compile installed package PKG-DESC. +This assumes that `pkg-desc' has already been activated with +`package-activate-1'." (let ((warning-minimum-level :error) (save-silently inhibit-message) (load-path load-path)) - (package--activate-autoloads-and-load-path pkg-desc) (byte-recompile-directory (package-desc-dir pkg-desc) 0 t))) ;;;; Inferring package from current buffer @@ -1133,48 +1137,50 @@ Point is after the headers when BODY runs. FILE, if provided, is added to URL. URL can be a local file name, which must be absolute. ASYNC, if non-nil, runs the request asynchronously. -ERROR-FORM is run only if an error occurs. If NOERROR is -non-nil, don't propagate errors caused by the connection or by -BODY (does not apply to errors signaled by ERROR-FORM). +ERROR-FORM is run only if a connection error occurs. If NOERROR +is non-nil, don't propagate connection errors (does not apply to +errors signaled by ERROR-FORM or by BODY). \(fn URL &key ASYNC FILE ERROR-FORM NOERROR &rest BODY)" (declare (indent defun) (debug t)) (while (keywordp (car body)) (setq body (cdr (cdr body)))) - (macroexp-let2* nil ((url-1 url)) - `(cl-macrolet ((wrap-errors (&rest bodyforms) - (let ((err (make-symbol "err"))) - `(condition-case ,err - ,(macroexp-progn bodyforms) - ,(list 'error ',error-form - (list 'unless ',noerror - `(signal (car ,err) (cdr ,err)))))))) + (macroexp-let2* nil ((url-1 url) + (noerror-1 noerror)) + `(cl-macrolet ((unless-error (body-2 &rest before-body) + (let ((err (make-symbol "err"))) + `(with-temp-buffer + (when (condition-case ,err + (progn ,@before-body t) + ,(list 'error ',error-form + (list 'unless ',noerror-1 + `(signal (car ,err) (cdr ,err))))) + ,@body-2))))) (if (string-match-p "\\`https?:" ,url-1) (let* ((url (concat ,url-1 ,file)) (callback (lambda (status) (let ((b (current-buffer))) (require 'url-handlers) - (unwind-protect (wrap-errors - (when-let ((er (plist-get status :error))) - (error "Error retrieving: %s %S" url er)) - (goto-char (point-min)) - (unless (search-forward-regexp "^\r?\n\r?" nil 'noerror) - (error "Error retrieving: %s %S" url "incomprehensible buffer")) - (with-temp-buffer - (url-insert-buffer-contents b url) - (kill-buffer b) - (goto-char (point-min)) - ,@body))))))) + (unless-error ,body + (when-let ((er (plist-get status :error))) + (error "Error retrieving: %s %S" url er)) + (with-current-buffer b + (goto-char (point-min)) + (unless (search-forward-regexp "^\r?\n\r?" nil 'noerror) + (error "Error retrieving: %s %S" url "incomprehensible buffer"))) + (url-insert-buffer-contents b url) + (kill-buffer b) + (goto-char (point-min))))))) (if ,async - (wrap-errors (url-retrieve url callback nil 'silent)) - (with-current-buffer (wrap-errors (url-retrieve-synchronously url 'silent)) - (funcall callback nil)))) - (wrap-errors (with-temp-buffer - (let ((url (expand-file-name ,file ,url-1))) - (unless (file-name-absolute-p url) - (error "Location %s is not a url nor an absolute file name" url)) - (insert-file-contents url)) - ,@body)))))) + (unless-error nil (url-retrieve url callback nil 'silent)) + (unless-error ,body (url-insert-file-contents url)))) + (unless-error ,body + (let ((url (expand-file-name ,file ,url-1))) + (unless (file-name-absolute-p url) + (error "Location %s is not a url nor an absolute file name" url)) + (insert-file-contents url))))))) + +(define-error 'bad-signature "Failed to verify signature") (defun package--check-signature-content (content string &optional sig-file) "Check signature CONTENT against STRING. @@ -1186,7 +1192,7 @@ errors." (condition-case error (epg-verify-string context content string) (error (package--display-verify-error context sig-file) - (signal (car error) (cdr error)))) + (signal 'bad-signature error))) (let (good-signatures had-fatal-error) ;; The .sig file may contain multiple signatures. Success if one ;; of the signatures is good. @@ -1202,10 +1208,10 @@ errors." (setq had-fatal-error t)))) (when (and (null good-signatures) had-fatal-error) (package--display-verify-error context sig-file) - (error "Failed to verify signature %s" sig-file)) + (signal 'bad-signature (list sig-file))) good-signatures))) -(defun package--check-signature (location file &optional string async callback) +(defun package--check-signature (location file &optional string async callback unwind) "Check signature of the current buffer. Download the signature file from LOCATION by appending \".sig\" to FILE. @@ -1214,18 +1220,35 @@ STRING is the string to verify, it defaults to `buffer-string'. If ASYNC is non-nil, the download of the signature file is done asynchronously. -If the signature is verified and CALLBACK was provided, CALLBACK -is `funcall'ed with the list of good signatures as argument (the -list can be empty). If the signatures file is not found, -CALLBACK is called with no arguments." +If the signature does not verify, signal an error. +If the signature is verified and CALLBACK was provided, `funcall' +CALLBACK with the list of good signatures as argument (the list +can be empty). +If no signatures file is found, and `package-check-signature' is +`allow-unsigned', call CALLBACK with a nil argument. +Otherwise, an error is signaled. + +UNWIND, if provided, is a function to be called after everything +else, even if an error is signaled." (let ((sig-file (concat file ".sig")) (string (or string (buffer-string)))) (package--with-response-buffer location :file sig-file :async async :noerror t - :error-form (when callback (funcall callback nil)) - (let ((sig (package--check-signature-content (buffer-substring (point) (point-max)) string sig-file))) - (when callback (funcall callback sig)) - sig)))) + ;; Connection error is assumed to mean "no sig-file". + :error-form (let ((allow-unsigned (eq package-check-signature 'allow-unsigned))) + (when (and callback allow-unsigned) + (funcall callback nil)) + (when unwind (funcall unwind)) + (unless allow-unsigned + (error "Unsigned file `%s' at %s" file location))) + ;; OTOH, an error here means "bad signature", which we never + ;; suppress. (Bug#22089) + (unwind-protect + (let ((sig (package--check-signature-content (buffer-substring (point) (point-max)) + string sig-file))) + (when callback (funcall callback sig)) + sig) + (when unwind (funcall unwind)))))) ;;; Packages on Archives ;; The following variables store information about packages available @@ -1488,19 +1511,12 @@ similar to an entry in `package-alist'. Save the cached copy to location file content async ;; This function will be called after signature checking. (lambda (&optional good-sigs) - (unless (or good-sigs (eq package-check-signature 'allow-unsigned)) - ;; Even if the sig fails, this download is done, so - ;; remove it from the in-progress list. - (package--update-downloads-in-progress archive) - (error "Unsigned archive `%s'" name)) - ;; Either everything worked or we don't mind not signing. - ;; Write out the archives file. (write-region content nil local-file nil 'silent) ;; Write out good signatures into archive-contents.signed file. (when good-sigs (write-region (mapconcat #'epg-signature-to-string good-sigs "\n") - nil (concat local-file ".signed") nil 'silent)) - (package--update-downloads-in-progress archive)))))))) + nil (concat local-file ".signed") nil 'silent))) + (lambda () (package--update-downloads-in-progress archive)))))))) (defun package--download-and-read-archives (&optional async) "Download descriptions of all `package-archives' and read them. @@ -1782,11 +1798,6 @@ if all the in-between dependencies are also in PACKAGE-LIST." location file content nil ;; This function will be called after signature checking. (lambda (&optional good-sigs) - (unless (or good-sigs (eq package-check-signature 'allow-unsigned)) - ;; Even if the sig fails, this download is done, so - ;; remove it from the in-progress list. - (error "Unsigned package: `%s'" - (package-desc-name pkg-desc))) ;; Signature checked, unpack now. (with-temp-buffer (insert content) (let ((save-silently t)) diff --git a/lisp/files.el b/lisp/files.el index d20bb1401f..ea09c2a9fa 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -1023,6 +1023,7 @@ Return nil if COMMAND is not found anywhere in `exec-path'." (defun load-library (library) "Load the Emacs Lisp library named LIBRARY. +LIBRARY should be a string. This is an interface to the function `load'. LIBRARY is searched for in `load-path', both with and without `load-suffixes' (as well as `load-file-rep-suffixes'). @@ -1430,8 +1431,10 @@ return value, which may be passed as the REQUIRE-MATCH arg to (defmacro minibuffer-with-setup-hook (fun &rest body) "Temporarily add FUN to `minibuffer-setup-hook' while executing BODY. -FUN can also be (:append FUN1), in which case FUN1 is appended to -`minibuffer-setup-hook'. + +By default, FUN is prepended to `minibuffer-setup-hook'. But if FUN is of +the form `(:append FUN1)', FUN1 will be appended to `minibuffer-setup-hook' +instead of prepending it. BODY should use the minibuffer at most once. Recursive uses of the minibuffer are unaffected (FUN is not @@ -3419,7 +3422,7 @@ local variables, but directory-local variables may still be applied." (unless hack-local-variables--warned-lexical (setq hack-local-variables--warned-lexical t) (display-warning - :warning + 'files (format-message "%s: `lexical-binding' at end of file unreliable" (file-name-nondirectory @@ -3883,7 +3886,7 @@ This does nothing if either `enable-local-variables' or (if (eq (car elt) 'coding) (unless hack-dir-local-variables--warned-coding (setq hack-dir-local-variables--warned-coding t) - (display-warning :warning + (display-warning 'files "Coding cannot be specified by dir-locals")) (unless (memq (car elt) '(eval mode)) (setq dir-local-variables-alist diff --git a/lisp/finder.el b/lisp/finder.el index 715dd9499f..c40e04a914 100644 --- a/lisp/finder.el +++ b/lisp/finder.el @@ -238,7 +238,7 @@ from; the default is `load-path'." ;; The idea here is that eg calc.el gets to define ;; the description of the calc package. ;; This does not work for eg nxml-mode.el. - ((eq base-name package) + ((or (eq base-name package) version) (setq desc (cdr entry)) (aset desc 0 version) (aset desc 2 summary))) diff --git a/lisp/font-lock.el b/lisp/font-lock.el index 762720d5ba..93d677c67e 100644 --- a/lisp/font-lock.el +++ b/lisp/font-lock.el @@ -1065,7 +1065,8 @@ Called with two arguments BEG and END.") (defun font-lock-flush (&optional beg end) "Declare the region BEG...END's fontification as out-of-date. -If the region is not specified, it defaults to the whole buffer." +If the region is not specified, it defaults to the entire +accessible portion of the current buffer." (and font-lock-mode font-lock-fontified (funcall font-lock-flush-function @@ -1079,7 +1080,8 @@ Called with two arguments BEG and END.") (defun font-lock-ensure (&optional beg end) "Make sure the region BEG...END has been fontified. -If the region is not specified, it defaults to the whole buffer." +If the region is not specified, it defaults to the entire accessible +portion of the buffer." (font-lock-set-defaults) (funcall font-lock-ensure-function (or beg (point-min)) (or end (point-max)))) diff --git a/lisp/gnus/auth-source.el b/lisp/gnus/auth-source.el index 9d842c04f6..10d32d4507 100644 --- a/lisp/gnus/auth-source.el +++ b/lisp/gnus/auth-source.el @@ -919,13 +919,15 @@ while \(:host t) would find all host entries." prompt) (defun auth-source-ensure-strings (values) - (unless (listp values) - (setq values (list values))) - (mapcar (lambda (value) - (if (numberp value) - (format "%s" value) - value)) - values)) + (if (eq values t) + values + (unless (listp values) + (setq values (list values))) + (mapcar (lambda (value) + (if (numberp value) + (format "%s" value) + value)) + values))) ;;; Backend specific parsing: netrc/authinfo backend diff --git a/lisp/help.el b/lisp/help.el index c558b652b7..d6cfae4418 100644 --- a/lisp/help.el +++ b/lisp/help.el @@ -1069,7 +1069,7 @@ is currently activated with completion." ;;; Automatic resizing of temporary buffers. (defcustom temp-buffer-max-height (lambda (buffer) - (if (eq (selected-window) (frame-root-window)) + (if (and (display-graphic-p) (eq (selected-window) (frame-root-window))) (/ (x-display-pixel-height) (frame-char-height) 2) (/ (- (frame-height) 2) 2))) "Maximum height of a window displaying a temporary buffer. @@ -1086,7 +1086,7 @@ function is called, the window to be resized is selected." (defcustom temp-buffer-max-width (lambda (buffer) - (if (eq (selected-window) (frame-root-window)) + (if (and (display-graphic-p) (eq (selected-window) (frame-root-window))) (/ (x-display-pixel-width) (frame-char-width) 2) (/ (- (frame-width) 2) 2))) "Maximum width of a window displaying a temporary buffer. diff --git a/lisp/ibuffer.el b/lisp/ibuffer.el index 5819f63c67..bfb247ca84 100644 --- a/lisp/ibuffer.el +++ b/lisp/ibuffer.el @@ -1354,23 +1354,36 @@ group." (message "%s buffers marked" count)) (ibuffer-redisplay t)) -(defun ibuffer-mark-forward (arg) - "Mark the buffer on this line, and move forward ARG lines. +(defsubst ibuffer-get-region-and-prefix () + (let ((arg (prefix-numeric-value current-prefix-arg))) + (if (use-region-p) (list (region-beginning) (region-end) arg) + (list nil nil arg)))) + +(defun ibuffer-mark-forward (start end arg) + "Mark the buffers in the region, or ARG buffers. If point is on a group name, this function operates on that group." - (interactive "p") - (ibuffer-mark-interactive arg ibuffer-marked-char)) + (interactive (ibuffer-get-region-and-prefix)) + (ibuffer-mark-region-or-n-with-char start end arg ibuffer-marked-char)) -(defun ibuffer-unmark-forward (arg) - "Unmark the buffer on this line, and move forward ARG lines. +(defun ibuffer-unmark-forward (start end arg) + "Unmark the buffers in the region, or ARG buffers. If point is on a group name, this function operates on that group." - (interactive "p") - (ibuffer-mark-interactive arg ?\s)) + (interactive (ibuffer-get-region-and-prefix)) + (ibuffer-mark-region-or-n-with-char start end arg ?\s)) (defun ibuffer-unmark-backward (arg) - "Unmark the buffer on this line, and move backward ARG lines. + "Unmark the ARG previous buffers. If point is on a group name, this function operates on that group." (interactive "p") - (ibuffer-unmark-forward (- arg))) + (ibuffer-unmark-forward nil nil (- arg))) + +(defun ibuffer-mark-region-or-n-with-char (start end arg mark-char) + (if (use-region-p) + (let ((cur (point)) (line-count (count-lines start end))) + (goto-char start) + (ibuffer-mark-interactive line-count mark-char) + (goto-char cur)) + (ibuffer-mark-interactive arg mark-char))) (defun ibuffer-mark-interactive (arg mark &optional movement) (ibuffer-assert-ibuffer-mode) @@ -1409,16 +1422,16 @@ If point is on a group name, this function operates on that group." (list (ibuffer-current-buffer) mark)))) -(defun ibuffer-mark-for-delete (arg) - "Mark the buffers on ARG lines forward for deletion. +(defun ibuffer-mark-for-delete (start end arg) + "Mark for deletion the buffers in the region, or ARG buffers. If point is on a group name, this function operates on that group." - (interactive "P") - (ibuffer-mark-interactive arg ibuffer-deletion-char 1)) + (interactive (ibuffer-get-region-and-prefix)) + (ibuffer-mark-region-or-n-with-char start end arg ibuffer-deletion-char)) (defun ibuffer-mark-for-delete-backwards (arg) - "Mark the buffers on ARG lines backward for deletion. + "Mark for deletion the ARG previous buffers. If point is on a group name, this function operates on that group." - (interactive "P") + (interactive "p") (ibuffer-mark-interactive arg ibuffer-deletion-char -1)) (defun ibuffer-current-buffer (&optional must-be-live) diff --git a/lisp/ido.el b/lisp/ido.el index a254b4fefc..1415b27a3a 100644 --- a/lisp/ido.el +++ b/lisp/ido.el @@ -3559,7 +3559,9 @@ it is put to the start of the list." (let* ((len (1- (length dir))) (non-essential t) (compl - (or (file-name-all-completions "" dir) + (or ;; We do not want to be disturbed by "File does not + ;; exist" errors. + (ignore-errors (file-name-all-completions "" dir)) ;; work around bug in ange-ftp. ;; /ftp:user@host: => nil ;; /ftp:user@host:./ => ok diff --git a/lisp/mail/rmailout.el b/lisp/mail/rmailout.el index 1e770e6fea..587d75f09b 100644 --- a/lisp/mail/rmailout.el +++ b/lisp/mail/rmailout.el @@ -84,13 +84,14 @@ This uses `rmail-output-file-alist'." (eval (cdar tail)) (error (display-warning - :error + 'rmail-output (format-message "\ Error evaluating `rmail-output-file-alist' element: regexp: %s action: %s error: %S\n" - (caar tail) (cdar tail) err)) + (caar tail) (cdar tail) err) + :error) nil)))) (setq tail (cdr tail))) answer)))))) diff --git a/lisp/net/eudc-vars.el b/lisp/net/eudc-vars.el index a08d175fd6..de7e25a66a 100644 --- a/lisp/net/eudc-vars.el +++ b/lisp/net/eudc-vars.el @@ -50,7 +50,7 @@ instead." ;; Known protocols (used in completion) ;; Not to be mistaken with `eudc-supported-protocols' -(defvar eudc-known-protocols '(bbdb ph ldap)) +(defvar eudc-known-protocols '(bbdb ldap)) (defcustom eudc-server-hotlist nil "Directory servers to query. @@ -357,6 +357,10 @@ BBDB fields. SPECs are sexps which are evaluated: (symbol :tag "BBDB Field") (sexp :tag "Conversion Spec")))) +(make-obsolete-variable 'eudc-ph-bbdb-conversion-alist + "the EUDC PH/QI backend is obsolete." + "25.1") + ;;}}} ;;{{{ LDAP Custom Group diff --git a/lisp/net/net-utils.el b/lisp/net/net-utils.el index c6d40b6241..643d312fc2 100644 --- a/lisp/net/net-utils.el +++ b/lisp/net/net-utils.el @@ -35,15 +35,19 @@ ;; * Support connections to HOST/PORT, generally for debugging and the like. ;; In other words, for doing much the same thing as "telnet HOST PORT", and ;; then typing commands. -;; -;; PATHS -;; -;; On some systems, some of these programs are not in normal user path, -;; but rather in /sbin, /usr/sbin, and so on. - ;;; Code: +;; On some systems, programs like ifconfig are not in normal user +;; path, but rather in /sbin, /usr/sbin, etc (but non-root users can +;; still use them for queries). Actually the trend these +;; days is for /sbin to be a symlink to /usr/sbin, but we still need to +;; search both for older systems. +(defun net-utils--executable-find-sbin (command) + "Return absolute name of COMMAND if found in an sbin directory." + (let ((exec-path '("/sbin" "/usr/sbin" "/usr/local/sbin"))) + (executable-find command))) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Customization Variables ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -85,10 +89,13 @@ These options can be used to limit how many ICMP packets are emitted." (define-obsolete-variable-alias 'ipconfig-program 'ifconfig-program "22.2") (defcustom ifconfig-program - (if (eq system-type 'windows-nt) - "ipconfig" - "ifconfig") + (cond ((eq system-type 'windows-nt) "ipconfig") + ((executable-find "ifconfig") "ifconfig") + ((net-utils--executable-find-sbin "ifconfig")) + ((net-utils--executable-find-sbin "ip")) + (t "ip")) "Program to print network configuration information." + :version "25.1" ; add ip :group 'net-utils :type 'string) @@ -96,10 +103,12 @@ These options can be used to limit how many ICMP packets are emitted." 'ifconfig-program-options "22.2") (defcustom ifconfig-program-options - (list - (if (eq system-type 'windows-nt) - "/all" "-a")) + (cond ((string-match "ipconfig\\'" ifconfig-program) '("/all")) + ((string-match "ifconfig\\'" ifconfig-program) '("-a")) + ((string-match "ip\\'" ifconfig-program) '("addr"))) "Options for the ifconfig program." + :version "25.1" + :set-after '(ifconfig-program) :group 'net-utils :type '(repeat string)) @@ -126,7 +135,7 @@ These options can be used to limit how many ICMP packets are emitted." :group 'net-utils :type '(repeat string)) -(defcustom arp-program "arp" +(defcustom arp-program (or (net-utils--executable-find-sbin "arp") "arp") "Program to print IP to address translation tables." :group 'net-utils :type 'string) diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index a2153415f4..aebfe42216 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -486,6 +486,7 @@ The string is used in `tramp-methods'.") ;; Solaris: /usr/xpg4/bin:/usr/ccs/bin:/usr/bin:/opt/SUNWspro/bin ;; GNU/Linux (Debian, Suse): /bin:/usr/bin ;; FreeBSD: /usr/bin:/bin:/usr/sbin:/sbin: - beware trailing ":"! +;; Darwin: /usr/bin:/bin:/usr/sbin:/sbin ;; IRIX64: /usr/bin ;;;###tramp-autoload (defcustom tramp-remote-path @@ -597,9 +598,14 @@ we have this shell function.") use File::Spec; use Cwd \"realpath\"; +sub myrealpath { + my ($file) = @_; + return realpath($file) if -e $file; +} + sub recursive { my ($volume, @dirs) = @_; - my $real = realpath(File::Spec->catpath( + my $real = myrealpath(File::Spec->catpath( $volume, File::Spec->catdir(@dirs), \"\")); if ($real) { my ($vol, $dir) = File::Spec->splitpath($real, 1); @@ -613,7 +619,7 @@ sub recursive { } } -$result = realpath($ARGV[0]); +$result = myrealpath($ARGV[0]); if (!$result) { my ($vol, $dir) = File::Spec->splitpath($ARGV[0], 1); ($vol, @dirs) = recursive($vol, File::Spec->splitdir($dir)); @@ -621,10 +627,7 @@ if (!$result) { $result = File::Spec->catpath($vol, File::Spec->catdir(@dirs), \"\"); } -if ($ARGV[0] =~ /\\/$/) { - $result = $result . \"/\"; -} - +$result =~ s/\"/\\\\\"/g; print \"\\\"$result\\\"\\n\"; ' \"$1\" 2>/dev/null" "Perl script to produce output suitable for use with `file-truename' @@ -1143,20 +1146,17 @@ target of the symlink differ." ;; Do it yourself. We bind `directory-sep-char' here for ;; XEmacs on Windows, which would otherwise use backslash. - (t (let* ((directory-sep-char ?/) - (steps (tramp-compat-split-string localname "/")) - (localnamedir (tramp-run-real-handler - 'file-name-as-directory (list localname))) - (is-dir (string= localname localnamedir)) - (thisstep nil) - (numchase 0) - ;; Don't make the following value larger than - ;; necessary. People expect an error message in - ;; a timely fashion when something is wrong; - ;; otherwise they might think that Emacs is hung. - ;; Of course, correctness has to come first. - (numchase-limit 20) - symlink-target) + (t (let ((directory-sep-char ?/) + (steps (tramp-compat-split-string localname "/")) + (thisstep nil) + (numchase 0) + ;; Don't make the following value larger than + ;; necessary. People expect an error message in a + ;; timely fashion when something is wrong; + ;; otherwise they might think that Emacs is hung. + ;; Of course, correctness has to come first. + (numchase-limit 20) + symlink-target) (while (and steps (< numchase numchase-limit)) (setq thisstep (pop steps)) (tramp-message @@ -1212,10 +1212,8 @@ target of the symlink differ." (if result (mapconcat 'identity (cons "" result) "/") "/")) - (when (and is-dir - (or (string= "" result) - (not (string= (substring result -1) "/")))) - (setq result (concat result "/")))))) + (when (string= "" result) + (setq result "/"))))) (tramp-message v 4 "True name of `%s' is `%s'" localname result) result)))) @@ -1276,11 +1274,15 @@ target of the symlink differ." (tramp-get-test-command vec) (tramp-shell-quote-argument localname) (tramp-get-ls-command vec) + (if (eq id-format 'integer) "-ildn" "-ild") ;; On systems which have no quoting style, file names ;; with special characters could fail. - (if (tramp-get-ls-command-with-quoting-style vec) - "--quoting-style=c" "") - (if (eq id-format 'integer) "-ildn" "-ild") + (cond + ((tramp-get-ls-command-with-quoting-style vec) + "--quoting-style=c") + ((tramp-get-ls-command-with-w-option vec) + "-w") + (t "")) (tramp-shell-quote-argument localname))) ;; Parse `ls -l' output ... (with-current-buffer (tramp-get-buffer vec) @@ -1837,10 +1839,14 @@ be non-negative integers." "-- 2>/dev/null | sed -e 's/\"/\\\\\"/g' -e 's/%s/\"/g'); echo \")\"") (tramp-shell-quote-argument localname) (tramp-get-ls-command vec) - ;; On systems which have no quoting style, file names with - ;; special characters could fail. - (if (tramp-get-ls-command-with-quoting-style vec) - "--quoting-style=shell" "") + ;; On systems which have no quoting style, file names with special + ;; characters could fail. + (cond + ((tramp-get-ls-command-with-quoting-style vec) + "--quoting-style=shell") + ((tramp-get-ls-command-with-w-option vec) + "-w") + (t "")) (tramp-get-remote-stat vec) tramp-stat-marker tramp-stat-marker tramp-stat-marker tramp-stat-marker @@ -4149,7 +4155,8 @@ seconds. If not, it produces an error message with the given ERROR-ARGS." "Set up an interactive shell. Mainly sets the prompt and the echo correctly. PROC is the shell process to set up. VEC specifies the connection." - (let ((tramp-end-of-output tramp-initial-end-of-output)) + (let ((tramp-end-of-output tramp-initial-end-of-output) + (case-fold-search t)) (tramp-open-shell vec (tramp-get-method-parameter vec 'tramp-remote-shell)) ;; Disable tab and echo expansion. @@ -4174,6 +4181,25 @@ process to set up. VEC specifies the connection." vec (format "PS1=%s PS2='' PS3='' PROMPT_COMMAND=''" (tramp-shell-quote-argument tramp-end-of-output)) t) + ;; Check whether the output of "uname -sr" has been changed. If + ;; yes, this is a strong indication that we must expire all + ;; connection properties. We start again with + ;; `tramp-maybe-open-connection', it will be caught there. + (tramp-message vec 5 "Checking system information") + (let ((old-uname (tramp-get-connection-property vec "uname" nil)) + (new-uname + (tramp-set-connection-property + vec "uname" + (tramp-send-command-and-read vec "echo \\\"`uname -sr`\\\"")))) + (when (and (stringp old-uname) (not (string-equal old-uname new-uname))) + (tramp-message + vec 3 + "Connection reset, because remote host changed from `%s' to `%s'" + old-uname new-uname) + ;; We want to keep the password. + (tramp-cleanup-connection vec t t) + (throw 'uname-changed (tramp-maybe-open-connection vec)))) + ;; Try to set up the coding system correctly. ;; CCC this can't be the right way to do it. Hm. (tramp-message vec 5 "Determining coding system") @@ -4182,7 +4208,7 @@ process to set up. VEC specifies the connection." ;; Use MULE to select the right EOL convention for communicating ;; with the process. (let ((cs (or (and (memq 'utf-8 (coding-system-list)) - (string-match "utf8" (tramp-get-remote-locale vec)) + (string-match "utf-?8" (tramp-get-remote-locale vec)) (cons 'utf-8 'utf-8)) (tramp-compat-funcall 'process-coding-system proc) (cons 'undecided 'undecided))) @@ -4192,8 +4218,12 @@ process to set up. VEC specifies the connection." (setq cs-encode (cdr cs)) (unless cs-decode (setq cs-decode 'undecided)) (unless cs-encode (setq cs-encode 'undecided)) - (setq cs-encode (tramp-compat-coding-system-change-eol-conversion - cs-encode 'unix)) + (setq cs-encode + (tramp-compat-coding-system-change-eol-conversion + cs-encode + (if (string-match + "^Darwin" (tramp-get-connection-property vec "uname" "")) + 'mac 'unix))) (tramp-send-command vec "echo foo ; echo bar" t) (goto-char (point-min)) (when (search-forward "\r" nil t) @@ -4212,25 +4242,6 @@ process to set up. VEC specifies the connection." (tramp-send-command vec "set +o vi +o emacs" t) - ;; Check whether the output of "uname -sr" has been changed. If - ;; yes, this is a strong indication that we must expire all - ;; connection properties. We start again with - ;; `tramp-maybe-open-connection', it will be caught there. - (tramp-message vec 5 "Checking system information") - (let ((old-uname (tramp-get-connection-property vec "uname" nil)) - (new-uname - (tramp-set-connection-property - vec "uname" - (tramp-send-command-and-read vec "echo \\\"`uname -sr`\\\"")))) - (when (and (stringp old-uname) (not (string-equal old-uname new-uname))) - (tramp-message - vec 3 - "Connection reset, because remote host changed from `%s' to `%s'" - old-uname new-uname) - ;; We want to keep the password. - (tramp-cleanup-connection vec t t) - (throw 'uname-changed (tramp-maybe-open-connection vec)))) - ;; Check whether the remote host suffers from buggy ;; `send-process-string'. This is known for FreeBSD (see comment in ;; `send_process', file process.c). I've tested sending 624 bytes @@ -4277,6 +4288,10 @@ process to set up. VEC specifies the connection." (tramp-get-connection-property vec "uname" "")) (tramp-send-command vec "stty -oxtabs" t)) + ;; Set utf8 encoding. Needed for Mac OS X, for example. This is + ;; non-POSIX, so we must expect errors on some systems. + (tramp-send-command vec "stty iutf8 2>/dev/null" t) + ;; Set `remote-tty' process property. (let ((tty (tramp-send-command-and-read vec "echo \\\"`tty`\\\"" 'noerror))) (unless (zerop (length tty)) @@ -5358,7 +5373,7 @@ Return ATTR." (defun tramp-get-remote-locale (vec) (with-tramp-connection-property vec "locale" (tramp-send-command vec "locale -a") - (let ((candidates '("en_US.utf8" "C.utf8")) + (let ((candidates '("en_US.utf8" "C.utf8" "en_US.UTF-8")) locale) (with-current-buffer (tramp-get-connection-buffer vec) (while candidates @@ -5417,6 +5432,14 @@ Return ATTR." vec (format "%s --quoting-style=shell -al /dev/null" (tramp-get-ls-command vec)))))) +(defun tramp-get-ls-command-with-w-option (vec) + (save-match-data + (with-tramp-connection-property vec "ls-w-option" + (tramp-message vec 5 "Checking, whether `ls -w' works") + ;; Option "-w" is available on BSD systems. + (tramp-send-command-and-check + vec (format "%s -alw" (tramp-get-ls-command vec)))))) + (defun tramp-get-test-command (vec) (with-tramp-connection-property vec "test" (tramp-message vec 5 "Finding a suitable `test' command") diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 40c3f368a9..b7f53095a8 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -1291,8 +1291,8 @@ This is HOST, if non-nil. Otherwise, it is `tramp-default-host'." (defun tramp-dissect-file-name (name &optional nodefault) "Return a `tramp-file-name' structure. -The structure consists of remote method, remote user, remote host -and localname (file name on remote host). If NODEFAULT is +The structure consists of remote method, remote user, remote host, +localname (file name on remote host) and hop. If NODEFAULT is non-nil, the file name parts are not expanded to their default values." (save-match-data diff --git a/lisp/net/trampver.el b/lisp/net/trampver.el index 04046c5ee7..77ee8aebd6 100644 --- a/lisp/net/trampver.el +++ b/lisp/net/trampver.el @@ -6,6 +6,7 @@ ;; Author: Kai Großjohann <kai.grossjohann@gmx.net> ;; Keywords: comm, processes ;; Package: tramp +;; Version: 2.2.13.25.1 ;; This file is part of GNU Emacs. @@ -31,7 +32,7 @@ ;; should be changed only there. ;;;###tramp-autoload -(defconst tramp-version "2.2.13-25.1" +(defconst tramp-version "2.2.13.25.1" "This version of Tramp.") ;;;###tramp-autoload diff --git a/lisp/net/eudcb-ph.el b/lisp/obsolete/eudcb-ph.el index f144bf695f..c847c2a167 100644 --- a/lisp/net/eudcb-ph.el +++ b/lisp/obsolete/eudcb-ph.el @@ -7,6 +7,7 @@ ;; Maintainer: Thomas Fitzsimmons <fitzsim@fitzsim.org> ;; Keywords: comm ;; Package: eudc +;; Obsolete-since: 25.1 ;; This file is part of GNU Emacs. diff --git a/lisp/paren.el b/lisp/paren.el index 30314c2f9c..5825d6a4f7 100644 --- a/lisp/paren.el +++ b/lisp/paren.el @@ -87,7 +87,10 @@ whitespace there." 'show-paren-mismatch "22.1") (defcustom show-paren-highlight-openparen t - "Non-nil turns on openparen highlighting when matching forward." + "Non-nil turns on openparen highlighting when matching forward. +When nil, and point stands just before an open paren, the paren +is not highlighted, the cursor being regarded as adequate to mark +its position." :type 'boolean) (defvar show-paren--idle-timer nil) diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el index 16f82ccb47..bde030e3f2 100644 --- a/lisp/progmodes/gdb-mi.el +++ b/lisp/progmodes/gdb-mi.el @@ -1766,7 +1766,8 @@ static char *magick[] = { (defvar gdb-control-commands-regexp (concat "^\\(" - "commands\\|if\\|while\\|define\\|document\\|python\\|" + "commands\\|if\\|while\\|define\\|document\\|" + "python\\|python-interactive\\|pi\\|guile\\|guile-repl\\|gr\\|" "while-stepping\\|stepping\\|ws\\|actions" "\\)\\([[:blank:]]+.*\\)?$") "Regexp matching GDB commands that enter a recursive reading loop. @@ -1782,21 +1783,27 @@ commands to be prefixed by \"-interpreter-exec console\".") (let ((inhibit-read-only t)) (remove-text-properties (point-min) (point-max) '(face)))) ;; mimic <RET> key to repeat previous command in GDB - (if (not (string= "" string)) - (if gdb-continuation - (setq gdb-last-command (concat gdb-continuation - (gdb-strip-string-backslash string) - " ")) - (setq gdb-last-command (gdb-strip-string-backslash string))) - (if gdb-last-command (setq string gdb-last-command)) - (setq gdb-continuation nil)) - (if (and (not gdb-continuation) (or (string-match "^-" string) - (> gdb-control-level 0))) + (when (= gdb-control-level 0) + (if (not (string= "" string)) + (if gdb-continuation + (setq gdb-last-command (concat gdb-continuation + (gdb-strip-string-backslash string) + " ")) + (setq gdb-last-command (gdb-strip-string-backslash string))) + (if gdb-last-command (setq string gdb-last-command)) + (setq gdb-continuation nil))) + (if (and (not gdb-continuation) + (or (string-match "^-" string) + (> gdb-control-level 0))) ;; Either MI command or we are feeding GDB's recursive reading loop. (progn (setq gdb-first-done-or-error t) (process-send-string proc (concat string "\n")) - (if (and (string-match "^end$" string) + (if (and (string-match + (concat "^\\(" + (if (eq system-type 'windows-nt) "\026" "\004") + "\\|,q\\|,quit\\|end\\)$") + string) (> gdb-control-level 0)) (setq gdb-control-level (1- gdb-control-level)))) ;; CLI command @@ -1812,7 +1819,11 @@ commands to be prefixed by \"-interpreter-exec console\".") (if gdb-enable-debug (push (cons 'mi-send to-send) gdb-debug-log)) (process-send-string proc to-send)) - (if (and (string-match "^end$" string) + (if (and (string-match + (concat "^\\(" + (if (eq system-type 'windows-nt) "\026" "\004") + "\\|,q\\|,quit\\|end\\)$") + string) (> gdb-control-level 0)) (setq gdb-control-level (1- gdb-control-level))) (setq gdb-continuation nil))) diff --git a/lisp/progmodes/prog-mode.el b/lisp/progmodes/prog-mode.el index b459cbfd28..9702880771 100644 --- a/lisp/progmodes/prog-mode.el +++ b/lisp/progmodes/prog-mode.el @@ -50,49 +50,51 @@ "Keymap used for programming modes.") (defvar prog-indentation-context nil - "Non-nil while indenting embedded code chunks. + "When non-nil, provides context for indenting embedded code chunks. + There are languages where part of the code is actually written in a sub language, e.g., a Yacc/Bison or ANTLR grammar also consists of plain C code. This variable enables the major mode of the -main language to use the indentation engine of the sub mode for -lines in code chunks written in the sub language. +main language to use the indentation engine of the sub-mode for +lines in code chunks written in the sub-mode's language. When a major mode of such a main language decides to delegate the indentation of a line/region to the indentation engine of the sub -mode, it is supposed to bind this variable to non-nil around the call. +mode, it should bind this variable to non-nil around the call. + +The non-nil value should be a list of the form: -The non-nil value looks as follows (FIRST-COLUMN (START . END) PREVIOUS-CHUNKS) -FIRST-COLUMN is the column the indentation engine of the sub mode -should usually choose for top-level language constructs inside -the code chunk (instead of 0). +FIRST-COLUMN is the column the indentation engine of the sub-mode +should use for top-level language constructs inside the code +chunk (instead of 0). -START to END is the region of the code chunk. See function -`prog-widen' for additional info. +START and END specify the region of the code chunk. END can be +nil, which stands for the value of `point-max'. The function +`prog-widen' uses this to restore restrictions imposed by the +sub-mode's indentation engine. PREVIOUS-CHUNKS, if non-nil, provides the indentation engine of -the sub mode with the virtual context of the code chunk. Valid +the sub-mode with the virtual context of the code chunk. Valid values are: - - A string containing code which the indentation engine can + - A string containing text which the indentation engine can consider as standing in front of the code chunk. To cache the string's calculated syntactic information for repeated calls - with the same string, it is valid and expected for the inner - mode to add text-properties to the string. + with the same string, the sub-mode can add text-properties to + the string. A typical use case is for grammars with code chunks which are - to be indented like function bodies - the string would contain - a corresponding function header. + to be indented like function bodies -- the string would contain + the corresponding function preamble. - - A function called with the start position of the current - chunk. It will return either the region of the previous chunk - as (PREV-START . PREV-END) or nil if there is no further - previous chunk. + - A function, to be called with the start position of the current + chunk. It should return either the region of the previous chunk + as (PREV-START . PREV-END), or nil if there is no previous chunk. - A typical use case are literate programming sources - the - function would successively return the code chunks of the - previous macro definitions for the same name.") + A typical use case are literate programming sources -- the + function would successively return the previous code chunks.") (defun prog-indent-sexp (&optional defun) "Indent the expression after point. @@ -113,8 +115,8 @@ instead." (defun prog-widen () "Remove restrictions (narrowing) from current code chunk or buffer. -This function can be used instead of `widen' in any function used -by the indentation engine to make it respect the value +This function should be used instead of `widen' in any function used +by the indentation engine to make it respect the value of `prog-indentation-context'. This function (like `widen') is useful inside a @@ -122,8 +124,8 @@ This function (like `widen') is useful inside a narrowing is in effect." (let ((chunk (cadr prog-indentation-context))) (if chunk - ;; no widen necessary here, as narrow-to-region changes (not - ;; just narrows) existing restrictions + ;; No call to `widen' is necessary here, as narrow-to-region + ;; changes (not just narrows) the existing restrictions (narrow-to-region (car chunk) (or (cdr chunk) (point-max))) (widen)))) @@ -134,15 +136,15 @@ Each element looks like (SYMBOL . CHARACTER), where the symbol matching SYMBOL (a string, not a regexp) will be shown as CHARACTER instead. -CHARACTER can be a character or it can be a list or vector, in +CHARACTER can be a character, or it can be a list or vector, in which case it will be used to compose the new symbol as per the third argument of `compose-region'.") (defun prettify-symbols-default-compose-p (start end _match) "Return true iff the symbol MATCH should be composed. The symbol starts at position START and ends at position END. -This is default `prettify-symbols-compose-predicate' which is -suitable for most programming languages such as C or Lisp." +This is the default for `prettify-symbols-compose-predicate' +which is suitable for most programming languages such as C or Lisp." ;; Check that the chars should really be composed into a symbol. (let* ((syntaxes-beg (if (memq (char-syntax (char-after start)) '(?w ?_)) '(?w ?_) '(?. ?\\))) @@ -154,14 +156,14 @@ suitable for most programming languages such as C or Lisp." (defvar-local prettify-symbols-compose-predicate #'prettify-symbols-default-compose-p - "A predicate deciding if the currently matched symbol is to be composed. + "A predicate for deciding if the currently matched symbol is to be composed. The matched symbol is the car of one entry in `prettify-symbols-alist'. -The predicate receives the match's start and end position as well +The predicate receives the match's start and end positions as well as the match-string as arguments.") (defun prettify-symbols--compose-symbol (alist) "Compose a sequence of characters into a symbol. -Regexp match data 0 points to the chars." +Regexp match data 0 specifies the characters to be composed." ;; Check that the chars should really be composed into a symbol. (let ((start (match-beginning 0)) (end (match-end 0)) diff --git a/lisp/simple.el b/lisp/simple.el index 2ccb016aca..2abab5c597 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -974,7 +974,8 @@ If DELETE is `delete-only', then only delete the region and the return value is undefined. If DELETE is nil, just return the content as a string. If DELETE is `bounds', then don't delete, but just return the boundaries of the region as a list of (START . END) positions. -If anything else, delete the region and return its content as a string.") +If anything else, delete the region and return its content as a string, +after filtering it with `filter-buffer-substring'.") (defvar region-insert-function (lambda (lines) @@ -999,6 +1000,10 @@ Optional second arg KILLFLAG, if non-nil, means to kill (save in kill ring) instead of delete. Interactively, N is the prefix arg, and KILLFLAG is set if N is explicitly specified. +When killing, the killed text is filtered by +`filter-buffer-substring' before it is saved in the kill ring, so +the actual saved text might be different from what was killed. + In Overwrite mode, single character backward deletion may replace tabs with spaces so as to back over columns, unless point is at the end of the line." @@ -1034,7 +1039,11 @@ To disable this, set variable `delete-active-region' to nil. Optional second arg KILLFLAG non-nil means to kill (save in kill ring) instead of delete. Interactively, N is the prefix arg, and -KILLFLAG is set if N was explicitly specified." +KILLFLAG is set if N was explicitly specified. + +When killing, the killed text is filtered by +`filter-buffer-substring' before it is saved in the kill ring, so +the actual saved text might be different from what was killed." (declare (interactive-only delete-char)) (interactive "p\nP") (unless (integerp n) @@ -3351,13 +3360,12 @@ the use of a shell (with its need to quote arguments)." (shell-command-on-region (point) (point) command output-buffer nil error-buffer))))))) -(defun display-message-or-buffer (message - &optional buffer-name not-this-window frame) +(defun display-message-or-buffer (message &optional buffer-name action frame) "Display MESSAGE in the echo area if possible, otherwise in a pop-up buffer. MESSAGE may be either a string or a buffer. -A buffer is displayed using `display-buffer' if MESSAGE is too long for -the maximum height of the echo area, as defined by `max-mini-window-height' +A pop-up buffer is displayed using `display-buffer' if MESSAGE is too long +for maximum height of the echo area, as defined by `max-mini-window-height' if `resize-mini-windows' is non-nil. Returns either the string shown in the echo area, or when a pop-up @@ -3369,8 +3377,8 @@ is used, defaulting to `*Message*'. In the case where MESSAGE is a string and it is displayed in the echo area, it is not specified whether the contents are inserted into the buffer anyway. -Optional arguments NOT-THIS-WINDOW and FRAME are as for `display-buffer', -and only used if a buffer is displayed." +Optional arguments ACTION and FRAME are as for `display-buffer', +and are only used if a pop-up buffer is displayed." (cond ((and (stringp message) (not (string-match "\n" message))) ;; Trivial case where we can use the echo area (message "%s" message)) @@ -3809,7 +3817,9 @@ see other processes running on the system, use `list-system-processes'." (setq prefix-command--last-echo nil) (defun internal-echo-keystrokes-prefix () - ;; BEWARE: Called directly from the C code. + ;; BEWARE: Called directly from C code. + ;; If the return value is non-nil, it means we are in the middle of + ;; a command with prefix, such as a command invoked with prefix-arg. (if (not prefix-command--needs-update) prefix-command--last-echo (setq prefix-command--last-echo @@ -4249,21 +4259,25 @@ The command \\[yank] can retrieve it from there. If you want to append the killed region to the last killed text, use \\[append-next-kill] before \\[kill-region]. +Any command that calls this function is a \"kill command\". +If the previous command was also a kill command, +the text killed this time appends to the text killed last time +to make one entry in the kill ring. + +The killed text is filtered by `filter-buffer-substring' before it is +saved in the kill ring, so the actual saved text might be different +from what was killed. + If the buffer is read-only, Emacs will beep and refrain from deleting the text, but put the text in the kill ring anyway. This means that you can use the killing commands to copy text from a read-only buffer. Lisp programs should use this function for killing text. (To delete text, use `delete-region'.) -Supply two arguments, character positions indicating the stretch of text - to be killed. -Any command that calls this function is a \"kill command\". -If the previous command was also a kill command, -the text killed this time appends to the text killed last time -to make one entry in the kill ring. - -The optional argument REGION if non-nil, indicates that we're not just killing -some text between BEG and END, but we're killing the region." +Supply two arguments, character positions BEG and END indicating the + stretch of text to be killed. If the optional argument REGION is + non-nil, the function ignores BEG and END, and kills the current + region instead." ;; Pass mark first, then point, because the order matters when ;; calling `kill-append'. (interactive (list (mark) (point) 'region)) @@ -4308,8 +4322,14 @@ In Transient Mark mode, deactivate the mark. If `interprogram-cut-function' is non-nil, also save the text for a window system cut and paste. -The optional argument REGION if non-nil, indicates that we're not just copying -some text between BEG and END, but we're copying the region. +The copied text is filtered by `filter-buffer-substring' before it is +saved in the kill ring, so the actual saved text might be different +from what was in the buffer. + +When called from Lisp, save in the kill ring the stretch of text +between BEG and END, unless the optional argument REGION is +non-nil, in which case ignore BEG and END, and save the current +region instead. This command's old key binding has been given to `kill-ring-save'." ;; Pass mark first, then point, because the order matters when @@ -4334,8 +4354,14 @@ system cut and paste. If you want to append the killed line to the last killed text, use \\[append-next-kill] before \\[kill-ring-save]. -The optional argument REGION if non-nil, indicates that we're not just copying -some text between BEG and END, but we're copying the region. +The copied text is filtered by `filter-buffer-substring' before it is +saved in the kill ring, so the actual saved text might be different +from what was in the buffer. + +When called from Lisp, save in the kill ring the stretch of text +between BEG and END, unless the optional argument REGION is +non-nil, in which case ignore BEG and END, and save the current +region instead. This command is similar to `copy-region-as-kill', except that it gives visual feedback indicating the extent of the region being copied." diff --git a/lisp/subr.el b/lisp/subr.el index 420b212d54..860c14c446 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -4686,14 +4686,14 @@ Usually the separator is \".\", but it can be any other string.") (defconst version-regexp-alist - '(("^[-_+ ]?snapshot$" . -4) + '(("^[-._+ ]?snapshot$" . -4) ;; treat "1.2.3-20050920" and "1.2-3" as snapshot releases - ("^[-_+]$" . -4) + ("^[-._+]$" . -4) ;; treat "1.2.3-CVS" as snapshot release - ("^[-_+ ]?\\(cvs\\|git\\|bzr\\|svn\\|hg\\|darcs\\)$" . -4) - ("^[-_+ ]?alpha$" . -3) - ("^[-_+ ]?beta$" . -2) - ("^[-_+ ]?\\(pre\\|rc\\)$" . -1)) + ("^[-._+ ]?\\(cvs\\|git\\|bzr\\|svn\\|hg\\|darcs\\)$" . -4) + ("^[-._+ ]?alpha$" . -3) + ("^[-._+ ]?beta$" . -2) + ("^[-._+ ]?\\(pre\\|rc\\)$" . -1)) "Specify association between non-numeric version and its priority. This association is used to handle version string like \"1.0pre2\", @@ -4703,6 +4703,7 @@ non-numeric part of a version string to an integer. For example: String Version Integer List Version \"0.9snapshot\" (0 9 -4) \"1.0-git\" (1 0 -4) + \"1.0.cvs\" (1 0 -4) \"1.0pre2\" (1 0 -1 2) \"1.0PRE2\" (1 0 -1 2) \"22.8beta3\" (22 8 -2 3) @@ -4742,41 +4743,47 @@ in `version-regexp-alist'. Examples of valid version syntax: - 1.0pre2 1.0.7.5 22.8beta3 0.9alpha1 6.9.30Beta + 1.0pre2 1.0.7.5 22.8beta3 0.9alpha1 6.9.30Beta 2.4.snapshot .5 Examples of invalid version syntax: - 1.0prepre2 1.0..7.5 22.8X3 alpha3.2 .5 + 1.0prepre2 1.0..7.5 22.8X3 alpha3.2 Examples of version conversion: Version String Version as a List of Integers - \"1.0.7.5\" (1 0 7 5) - \"1.0pre2\" (1 0 -1 2) - \"1.0PRE2\" (1 0 -1 2) - \"22.8beta3\" (22 8 -2 3) - \"22.8Beta3\" (22 8 -2 3) - \"0.9alpha1\" (0 9 -3 1) + \".5\" (0 5) + \"0.9 alpha\" (0 9 -3) \"0.9AlphA1\" (0 9 -3 1) - \"0.9alpha\" (0 9 -3) \"0.9snapshot\" (0 9 -4) \"1.0-git\" (1 0 -4) + \"1.0.7.5\" (1 0 7 5) + \"1.0.cvs\" (1 0 -4) + \"1.0PRE2\" (1 0 -1 2) + \"1.0pre2\" (1 0 -1 2) + \"22.8 Beta3\" (22 8 -2 3) + \"22.8beta3\" (22 8 -2 3) See documentation for `version-separator' and `version-regexp-alist'." - (or (and (stringp ver) (> (length ver) 0)) - (error "Invalid version string: `%s'" ver)) + (unless (stringp ver) + (error "Version must be a string")) ;; Change .x.y to 0.x.y (if (and (>= (length ver) (length version-separator)) (string-equal (substring ver 0 (length version-separator)) version-separator)) (setq ver (concat "0" ver))) + (unless (string-match-p "^[0-9]" ver) + (error "Invalid version syntax: `%s' (must start with a number)" ver)) + (save-match-data (let ((i 0) (case-fold-search t) ; ignore case in matching lst s al) + ;; Parse the version-string up to a separator until there are none left (while (and (setq s (string-match "[0-9]+" ver i)) (= s i)) - ;; handle numeric part + ;; Add the numeric part to the beginning of the version list; + ;; lst gets reversed at the end (setq lst (cons (string-to-number (substring ver i (match-end 0))) lst) i (match-end 0)) @@ -4792,15 +4799,15 @@ See documentation for `version-separator' and `version-regexp-alist'." (setq al (cdr al))) (cond (al (push (cdar al) lst)) - ;; Convert 22.3a to 22.3.1, 22.3b to 22.3.2, etc. - ((string-match "^[-_+ ]?\\([a-zA-Z]\\)$" s) + ;; Convert 22.3a to 22.3.1, 22.3b to 22.3.2, etc., but only if + ;; the letter is the end of the version-string, to avoid + ;; 22.8X3 being valid + ((and (string-match "^[-._+ ]?\\([a-zA-Z]\\)$" s) + (= i (length ver))) (push (- (aref (downcase (match-string 1 s)) 0) ?a -1) lst)) (t (error "Invalid version syntax: `%s'" ver)))))) - (if (null lst) - (error "Invalid version syntax: `%s'" ver) - (nreverse lst))))) - + (nreverse lst)))) (defun version-list-< (l1 l2) "Return t if L1, a list specification of a version, is lower than L2. diff --git a/lisp/term.el b/lisp/term.el index bb718cf909..5dd965d2d3 100644 --- a/lisp/term.el +++ b/lisp/term.el @@ -1432,7 +1432,7 @@ Using \"emacs\" loses, because bash disables editing if $TERM == emacs.") :UP=\\E[%%dA:DO=\\E[%%dB:LE=\\E[%%dD:RI=\\E[%%dC\ :kl=\\EOD:kd=\\EOB:kr=\\EOC:ku=\\EOA:kN=\\E[6~:kP=\\E[5~:@7=\\E[4~:kh=\\E[1~\ :mk=\\E[8m:cb=\\E[1K:op=\\E[39;49m:Co#8:pa#64:AB=\\E[4%%dm:AF=\\E[3%%dm:cr=^M\ -:bl=^G:do=^J:le=^H:ta=^I:se=\\E[27m:ue=\\E24m\ +:bl=^G:do=^J:le=^H:ta=^I:se=\\E[27m:ue=\\E[24m\ :kb=^?:kD=^[[3~:sc=\\E7:rc=\\E8:r1=\\Ec:" ;; : -undefine ic ;; don't define :te=\\E[2J\\E[?47l\\E8:ti=\\E7\\E[?47h\ diff --git a/lisp/textmodes/ispell.el b/lisp/textmodes/ispell.el index 3327028894..05a5da57b6 100644 --- a/lisp/textmodes/ispell.el +++ b/lisp/textmodes/ispell.el @@ -2861,7 +2861,7 @@ The variable `ispell-highlight-face' selects the face to use for highlighting." (regexp-quote (buffer-substring-no-properties start end)) "\\b")) (isearch-regexp t) - (isearch-regexp-function nil) + (isearch-regexp-function nil) (isearch-case-fold-search nil) (isearch-forward t) (isearch-other-end start) diff --git a/lisp/textmodes/reftex-auc.el b/lisp/textmodes/reftex-auc.el index bbad065c4b..151be59236 100644 --- a/lisp/textmodes/reftex-auc.el +++ b/lisp/textmodes/reftex-auc.el @@ -137,7 +137,7 @@ argument identify one of multiple indices." ((stringp tag) tag) ((integerp tag) (save-excursion - (goto-char (match-end 1)) + (goto-char (match-end 0)) (or (reftex-nth-arg tag (nth 6 entry)) "idx"))) (t "idx"))))) diff --git a/lisp/textmodes/reftex-vars.el b/lisp/textmodes/reftex-vars.el index 3f7a6f34dc..fcab1367f7 100644 --- a/lisp/textmodes/reftex-vars.el +++ b/lisp/textmodes/reftex-vars.el @@ -877,7 +877,7 @@ DOWNCASE t: Downcase words before using them." "\\\\label{\\(?1:[^}]*\\)}" ;; keyvals [..., label = {foo}, ...] forms used by ctable, ;; listings, minted, ... - "\\[[^[]]*\\<label[[:space:]]*=[[:space:]]*{?\\(?1:[^],}]+\\)}?") + "\\[[^][]\\{0,2000\\}\\<label[[:space:]]*=[[:space:]]*{?\\(?1:[^],}]+\\)}?") "List of regexps matching \\label definitions. The default value matches usual \\label{...} definitions and keyval style [..., label = {...}, ...] label definitions. It is diff --git a/lisp/textmodes/reftex.el b/lisp/textmodes/reftex.el index 84efa7a5b2..4ee3658492 100644 --- a/lisp/textmodes/reftex.el +++ b/lisp/textmodes/reftex.el @@ -2397,7 +2397,7 @@ Your bug report will be posted to the AUCTeX bug reporting list. ;;; Start of automatically extracted autoloads. -;;;### (autoloads nil "reftex-auc" "reftex-auc.el" "cf606f7918831321cb46f254436dc66e") +;;;### (autoloads nil "reftex-auc" "reftex-auc.el" "7c0e0b46919f4ceefe1026e31e73ebcd") ;;; Generated autoloads from reftex-auc.el (autoload 'reftex-arg-label "reftex-auc" "\ diff --git a/lisp/url/url-handlers.el b/lisp/url/url-handlers.el index bafe3e5272..0b9d43f70c 100644 --- a/lisp/url/url-handlers.el +++ b/lisp/url/url-handlers.el @@ -340,8 +340,15 @@ if it had been inserted from a file named URL." ;; XXX: This is HTTP/S specific and should be moved to url-http ;; instead. See http://debbugs.gnu.org/17549. (when (bound-and-true-p url-http-response-status) - (unless (and (>= url-http-response-status 200) - (< url-http-response-status 300)) + ;; Don't signal an error if VISIT is non-nil, because + ;; 'insert-file-contents' doesn't. This is required to + ;; support, e.g., 'browse-url-emacs', which is a fancy way of + ;; visiting the HTML source of a URL: in that case, we want to + ;; display a file buffer even if the URL does not exist and + ;; 'url-retrieve-synchronously' returns 404 or whatever. + (unless (or visit + (and (>= url-http-response-status 200) + (< url-http-response-status 300))) (let ((desc (nth 2 (assq url-http-response-status url-http-codes)))) (kill-buffer buffer) ;; Signal file-error per http://debbugs.gnu.org/16733. diff --git a/lisp/vc/vc-hg.el b/lisp/vc/vc-hg.el index dd897adc59..62fbfde5f8 100644 --- a/lisp/vc/vc-hg.el +++ b/lisp/vc/vc-hg.el @@ -430,9 +430,13 @@ Optional arg REVISION is a revision to annotate from." ;;; Miscellaneous (defun vc-hg-previous-revision (_file rev) - (let ((newrev (1- (string-to-number rev)))) - (when (>= newrev 0) - (number-to-string newrev)))) + ;; We can't simply decrement by 1, because that revision might be + ;; e.g. on a different branch (bug#22032). + (with-temp-buffer + (and (eq 0 + (vc-hg-command t nil nil "id" "-n" "-r" (concat rev "^"))) + ;; Trim the trailing newline. + (buffer-substring (point-min) (1- (point-max)))))) (defun vc-hg-next-revision (_file rev) (let ((newrev (1+ (string-to-number rev))) diff --git a/lisp/vc/vc-hooks.el b/lisp/vc/vc-hooks.el index dbe09d247b..93d2dc0ee8 100644 --- a/lisp/vc/vc-hooks.el +++ b/lisp/vc/vc-hooks.el @@ -791,7 +791,11 @@ current, and kill the buffer that visits the link." nil) (defun vc-refresh-state () - "Activate or deactivate VC mode as appropriate." + "Refresh the VC state of the current buffer's file. + +This command is more thorough than `vc-state-refresh', in that it +also supports switching a back-end or removing the file from VC. +In the latter case, VC mode is deactivated for this buffer." (interactive) ;; Recompute whether file is version controlled, ;; if user has killed the buffer and revisited. diff --git a/lisp/vc/vc-svn.el b/lisp/vc/vc-svn.el index 62689a3842..a50befa9e4 100644 --- a/lisp/vc/vc-svn.el +++ b/lisp/vc/vc-svn.el @@ -147,7 +147,8 @@ switches." (defun vc-svn-registered (file) "Check if FILE is SVN registered." (setq file (expand-file-name file)) - (when (vc-svn-root file) + (when (and (vc-svn-root file) + (file-accessible-directory-p (file-name-directory file))) (with-temp-buffer (cd (file-name-directory file)) (let* (process-file-side-effects @@ -309,11 +310,13 @@ to the SVN command." (defalias 'vc-svn-responsible-p 'vc-svn-root) +(declare-function log-edit-extract-headers "log-edit" (headers string)) + (defun vc-svn-checkin (files comment &optional _extra-args-ignored) "SVN-specific version of `vc-backend-checkin'." (let ((status (apply 'vc-svn-command nil 1 files "ci" - (nconc (cons "-m" (log-edit-extract-headers comment)) + (nconc (cons "-m" (log-edit-extract-headers nil comment)) (vc-switches 'SVN 'checkin))))) (set-buffer "*vc*") (goto-char (point-min)) @@ -401,6 +404,8 @@ FILE is a file wildcard, relative to the root directory of DIRECTORY." (unless contents-done (vc-svn-command nil 0 file "revert"))) +(autoload 'vc-read-revision "vc") + (defun vc-svn-merge-file (file) "Accept a file merge request, prompting for revisions." (let* ((first-revision diff --git a/lwlib/xlwmenu.c b/lwlib/xlwmenu.c index 61f175b3c2..7e766bb730 100644 --- a/lwlib/xlwmenu.c +++ b/lwlib/xlwmenu.c @@ -28,13 +28,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ #include <stdio.h> #include <sys/types.h> -#if (defined __sun) && !(defined SUNOS41) -#define SUNOS41 #include <X11/Xos.h> -#undef SUNOS41 -#else -#include <X11/Xos.h> -#endif #include <X11/IntrinsicP.h> #include <X11/ObjectP.h> #include <X11/StringDefs.h> diff --git a/modules/mod-test/test.el b/modules/mod-test/test.el index ad4cc49c69..69bf933c7f 100644 --- a/modules/mod-test/test.el +++ b/modules/mod-test/test.el @@ -34,11 +34,9 @@ (should (stringp (nth 1 descr))) (should (eq 0 (string-match - (if (eq system-type 'windows-nt) - "#<module function at \\(0x\\)?[0-9a-fA-F]+ from .*>" - (if (eq system-type 'cygwin) - "#<module function at \\(0x\\)?[0-9a-fA-F]+>" - "#<module function Fmod_test_sum from .*>")) + (concat "#<module function " + "\\(at \\(0x\\)?[0-9a-fA-F]+\\( from .*\\)?" + "\\|Fmod_test_sum from .*\\)>") (nth 1 descr)))) (should (= (nth 2 descr) 3))) (should-error (mod-test-sum "1" 2) :type 'wrong-type-argument) @@ -48,10 +46,15 @@ (1- most-positive-fixnum))) (should (= (mod-test-sum 1 most-negative-fixnum) (1+ most-negative-fixnum))) - (should (= (mod-test-sum 1 #x1fffffff) - (1+ #x1fffffff))) - (should (= (mod-test-sum -1 #x20000000) - #x1fffffff))) + (when (< #x1fffffff most-positive-fixnum) + (should (= (mod-test-sum 1 #x1fffffff) + (1+ #x1fffffff))) + (should (= (mod-test-sum -1 #x20000000) + #x1fffffff))) + (should-error (mod-test-sum 1 most-positive-fixnum) + :type 'overflow-error) + (should-error (mod-test-sum -1 most-negative-fixnum) + :type 'overflow-error)) (ert-deftest mod-test-sum-docstring () (should (string= (documentation 'mod-test-sum) "Return A + B"))) diff --git a/src/alloc.c b/src/alloc.c index e83b3836aa..23ddd83d7d 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -406,24 +406,37 @@ ALIGN (void *ptr, int alignment) If A is a symbol, extract the hidden pointer's offset from lispsym, converted to void *. */ -static void * -XPNTR_OR_SYMBOL_OFFSET (Lisp_Object a) -{ - intptr_t i = USE_LSB_TAG ? XLI (a) - XTYPE (a) : XLI (a) & VALMASK; - return (void *) i; -} +#define macro_XPNTR_OR_SYMBOL_OFFSET(a) \ + ((void *) (intptr_t) (USE_LSB_TAG ? XLI (a) - XTYPE (a) : XLI (a) & VALMASK)) /* Extract the pointer hidden within A. */ -static void * +#define macro_XPNTR(a) \ + ((void *) ((intptr_t) XPNTR_OR_SYMBOL_OFFSET (a) \ + + (SYMBOLP (a) ? (char *) lispsym : NULL))) + +/* For pointer access, define XPNTR and XPNTR_OR_SYMBOL_OFFSET as + functions, as functions are cleaner and can be used in debuggers. + Also, define them as macros if being compiled with GCC without + optimization, for performance in that case. The macro_* names are + private to this section of code. */ + +static ATTRIBUTE_UNUSED void * +XPNTR_OR_SYMBOL_OFFSET (Lisp_Object a) +{ + return macro_XPNTR_OR_SYMBOL_OFFSET (a); +} +static ATTRIBUTE_UNUSED void * XPNTR (Lisp_Object a) { - void *p = XPNTR_OR_SYMBOL_OFFSET (a); - if (SYMBOLP (a)) - p = (intptr_t) p + (char *) lispsym; - return p; + return macro_XPNTR (a); } +#if DEFINE_KEY_OPS_AS_MACROS +# define XPNTR_OR_SYMBOL_OFFSET(a) macro_XPNTR_OR_SYMBOL_OFFSET (a) +# define XPNTR(a) macro_XPNTR (a) +#endif + static void XFLOAT_INIT (Lisp_Object f, double n) { @@ -5567,10 +5580,6 @@ garbage_collect_1 (void *end) mark_fringe_data (); #endif -#ifdef HAVE_MODULES - mark_modules (); -#endif - /* Everything is now marked, except for the data in font caches, undo lists, and finalizers. The first two are compacted by removing an items which aren't reachable otherwise. */ diff --git a/src/conf_post.h b/src/conf_post.h index 2c3eee59b7..b629e8d3df 100644 --- a/src/conf_post.h +++ b/src/conf_post.h @@ -245,6 +245,7 @@ extern int emacs_setenv_TZ (char const *); #endif #define ATTRIBUTE_CONST _GL_ATTRIBUTE_CONST +#define ATTRIBUTE_UNUSED _GL_UNUSED #if 3 <= __GNUC__ # define ATTRIBUTE_MALLOC __attribute__ ((__malloc__)) diff --git a/src/emacs-module.c b/src/emacs-module.c index 22fee7e486..ee97644098 100644 --- a/src/emacs-module.c +++ b/src/emacs-module.c @@ -44,10 +44,7 @@ enum { module_has_cleanup = false }; /* Handle to the main thread. Used to verify that modules call us in the right thread. */ -#ifdef HAVE_THREADS_H -# include <threads.h> -static thrd_t main_thread; -#elif defined HAVE_PTHREAD +#ifdef HAVE_PTHREAD # include <pthread.h> static pthread_t main_thread; #elif defined WINDOWSNT @@ -56,6 +53,18 @@ static pthread_t main_thread; static DWORD main_thread; #endif +/* True if Lisp_Object and emacs_value have the same representation. + This is typically true unless WIDE_EMACS_INT. In practice, having + the same sizes and alignments and maximums should be a good enough + proxy for equality of representation. */ +enum + { + plain_values + = (sizeof (Lisp_Object) == sizeof (emacs_value) + && alignof (Lisp_Object) == alignof (emacs_value) + && INTPTR_MAX == EMACS_INT_MAX) + }; + /* Private runtime and environment members. */ @@ -103,8 +112,11 @@ static void module_reset_handlerlist (const int *); static void module_wrong_type (emacs_env *, Lisp_Object, Lisp_Object); /* We used to return NULL when emacs_value was a different type from - Lisp_Object, but nowadays we just use Qnil instead. */ -static emacs_value module_nil; + Lisp_Object, but nowadays we just use Qnil instead. Although they + happen to be the same thing in the current implementation, module + code should not assume this. */ +verify (NIL_IS_ZERO); +static emacs_value const module_nil = 0; /* Convenience macros for non-local exit handling. */ @@ -559,7 +571,7 @@ module_get_user_ptr (emacs_env *env, emacs_value uptr) static void module_set_user_ptr (emacs_env *env, emacs_value uptr, void *ptr) { - // FIXME: This function should return bool because it can fail. + /* FIXME: This function should return bool because it can fail. */ MODULE_FUNCTION_BEGIN (); check_main_thread (); if (module_non_local_exit_check (env) != emacs_funcall_exit_return) @@ -587,7 +599,7 @@ static void module_set_user_finalizer (emacs_env *env, emacs_value uptr, emacs_finalizer_function fin) { - // FIXME: This function should return bool because it can fail. + /* FIXME: This function should return bool because it can fail. */ MODULE_FUNCTION_BEGIN (); Lisp_Object lisp = value_to_lisp (uptr); if (! USER_PTRP (lisp)) @@ -598,7 +610,7 @@ module_set_user_finalizer (emacs_env *env, emacs_value uptr, static void module_vec_set (emacs_env *env, emacs_value vec, ptrdiff_t i, emacs_value val) { - // FIXME: This function should return bool because it can fail. + /* FIXME: This function should return bool because it can fail. */ MODULE_FUNCTION_BEGIN (); Lisp_Object lvec = value_to_lisp (vec); if (! VECTORP (lvec)) @@ -641,7 +653,7 @@ module_vec_get (emacs_env *env, emacs_value vec, ptrdiff_t i) static ptrdiff_t module_vec_size (emacs_env *env, emacs_value vec) { - // FIXME: Return a sentinel value (e.g., -1) on error. + /* FIXME: Return a sentinel value (e.g., -1) on error. */ MODULE_FUNCTION_BEGIN (0); Lisp_Object lvec = value_to_lisp (vec); if (! VECTORP (lvec)) @@ -729,19 +741,18 @@ usage: (module-call ENVOBJ &rest ARGLIST) */) initialize_environment (&pub, &priv); USE_SAFE_ALLOCA; -#ifdef WIDE_EMACS_INT - emacs_value *args = SAFE_ALLOCA (len * sizeof *args); - - for (ptrdiff_t i = 0; i < len; i++) - args[i] = lisp_to_value (arglist[i + 1]); -#else - /* BEWARE! Here, we assume that Lisp_Object and - * emacs_value have the exact same representation. */ - emacs_value *args = (emacs_value*) arglist + 1; -#endif + emacs_value *args; + if (plain_values) + args = (emacs_value *) arglist + 1; + else + { + args = SAFE_ALLOCA (len * sizeof *args); + for (ptrdiff_t i = 0; i < len; i++) + args[i] = lisp_to_value (arglist[i + 1]); + } emacs_value ret = envptr->subr (&pub, len, args, envptr->data); - SAFE_FREE(); + SAFE_FREE (); eassert (&priv == pub.private_members); @@ -775,9 +786,7 @@ usage: (module-call ENVOBJ &rest ARGLIST) */) static void check_main_thread (void) { -#ifdef HAVE_THREADS_H - eassert (thrd_equal (thdr_current (), main_thread)); -#elif defined HAVE_PTHREAD +#ifdef HAVE_PTHREAD eassert (pthread_equal (pthread_self (), main_thread)); #elif defined WINDOWSNT eassert (GetCurrentThreadId () == main_thread); @@ -838,106 +847,107 @@ module_args_out_of_range (emacs_env *env, Lisp_Object a1, Lisp_Object a2) /* Value conversion. */ -#ifdef WIDE_EMACS_INT /* Unique Lisp_Object used to mark those emacs_values which are really - just containers holding a Lisp_Object that's too large for emacs_value. */ + just containers holding a Lisp_Object that does not fit as an emacs_value, + either because it is an integer out of range, or is not properly aligned. + Used only if !plain_values. */ static Lisp_Object ltv_mark; -#endif -/* Convert an `emacs_value' to the corresponding internal object. - Never fails. */ +/* Convert V to the corresponding internal object O, such that + V == lisp_to_value_bits (O). Never fails. */ static Lisp_Object -value_to_lisp (emacs_value v) +value_to_lisp_bits (emacs_value v) { -#ifdef WIDE_EMACS_INT - uintptr_t tmp = (uintptr_t)v; - unsigned tag = tmp & ((1 << GCTYPEBITS) - 1); - Lisp_Object o; + intptr_t i = (intptr_t) v; + if (plain_values || USE_LSB_TAG) + return XIL (i); + + /* With wide EMACS_INT and when tag bits are the most significant, + reassembling integers differs from reassembling pointers in two + ways. First, save and restore the least-significant bits of the + integer, not the most-significant bits. Second, sign-extend the + integer when restoring, but zero-extend pointers because that + makes TAG_PTR faster. */ + + EMACS_UINT tag = i & (GCALIGNMENT - 1); + EMACS_UINT untagged = i - tag; switch (tag) { case_Lisp_Int: - o = make_lisp_ptr ((void *)((tmp - tag) >> GCTYPEBITS), tag); break; - default: - o = make_lisp_ptr ((void *)(tmp - tag), tag); + { + bool negative = tag & 1; + EMACS_UINT sign_extension + = negative ? VALMASK & ~(INTPTR_MAX >> INTTYPEBITS): 0; + uintptr_t u = i; + intptr_t all_but_sign = u >> GCTYPEBITS; + untagged = sign_extension + all_but_sign; + break; + } } - /* eassert (lisp_to_value (o) == v); */ - if (CONSP (o) && EQ (XCDR (o), ltv_mark)) - return XCAR (o); - else - return o; -#else - Lisp_Object o = XIL ((EMACS_INT) v); - /* Check the assumption made elsewhere that Lisp_Object and emacs_value - share the same underlying bit representation. */ - eassert (EQ (o, *(Lisp_Object*)&v)); - /* eassert (lisp_to_value (o) == v); */ + + return XIL ((tag << VALBITS) + untagged); +} + +/* If V was computed from lisp_to_value (O), then return O. + Never fails. */ +static Lisp_Object +value_to_lisp (emacs_value v) +{ + Lisp_Object o = value_to_lisp_bits (v); + if (! plain_values && CONSP (o) && EQ (XCDR (o), ltv_mark)) + o = XCAR (o); return o; -#endif } -/* Convert an internal object to an `emacs_value'. Allocate storage - from the environment; return NULL if allocation fails. */ +/* Attempt to convert O to an emacs_value. Do not do any checking or + or allocate any storage; the caller should prevent or detect + any resulting bit pattern that is not a valid emacs_value. */ static emacs_value -lisp_to_value (Lisp_Object o) +lisp_to_value_bits (Lisp_Object o) { -#ifdef WIDE_EMACS_INT - /* We need to compress the EMACS_INT into the space of a pointer. - For most objects, this is just a question of shuffling the tags around. - But in some cases (e.g. large integers) this can't be done, so we - should allocate a special object to hold the extra data. */ - Lisp_Object orig = o; - int tag = XTYPE (o); - switch (tag) - { - case_Lisp_Int: - { - EMACS_UINT ui = (EMACS_UINT) XINT (o); - if (ui <= (SIZE_MAX >> GCTYPEBITS)) - { - uintptr_t uv = (uintptr_t) ui; - emacs_value v = (emacs_value) ((uv << GCTYPEBITS) | tag); - eassert (EQ (value_to_lisp (v), o)); - return v; - } - else - { - o = Fcons (o, ltv_mark); - tag = Lisp_Cons; - } - } /* FALLTHROUGH */ - default: - { - void *ptr = XUNTAG (o, tag); - if (((uintptr_t)ptr) & ((1 << GCTYPEBITS) - 1)) - { /* Pointer is not properly aligned! */ - eassert (!CONSP (o)); /* Cons cells have to always be aligned! */ - o = Fcons (o, ltv_mark); - ptr = XUNTAG (o, tag); - } - emacs_value v = (emacs_value) (((uintptr_t) ptr) | tag); - eassert (EQ (value_to_lisp (v), orig)); - return v; - } - } -#else - emacs_value v = (emacs_value) XLI (o); + EMACS_UINT u = XLI (o); - /* Check the assumption made elsewhere that Lisp_Object and emacs_value - share the same underlying bit representation. */ - eassert (v == *(emacs_value*)&o); - eassert (EQ (value_to_lisp (v), o)); - return v; -#endif + /* Compress U into the space of a pointer, possibly losing information. */ + uintptr_t p = (plain_values || USE_LSB_TAG + ? u + : (INTEGERP (o) ? u << VALBITS : u & VALMASK) + XTYPE (o)); + return (emacs_value) p; } - -/* Memory management. */ +#ifndef HAVE_STRUCT_ATTRIBUTE_ALIGNED +enum { HAVE_STRUCT_ATTRIBUTE_ALIGNED = 0 }; +#endif -/* Mark all objects allocated from local environments so that they - don't get garbage-collected. */ -void -mark_modules (void) +/* Convert O to an emacs_value. Allocate storage if needed; this can + signal if memory is exhausted. */ +static emacs_value +lisp_to_value (Lisp_Object o) { + emacs_value v = lisp_to_value_bits (o); + + if (! EQ (o, value_to_lisp_bits (v))) + { + /* Package the incompressible object pointer inside a pair + that is compressible. */ + Lisp_Object pair = Fcons (o, ltv_mark); + + if (! HAVE_STRUCT_ATTRIBUTE_ALIGNED) + { + /* Keep calling Fcons until it returns a compressible pair. + This shouldn't take long. */ + while ((intptr_t) XCONS (pair) & (GCALIGNMENT - 1)) + pair = Fcons (o, pair); + + /* Plant the mark. The garbage collector will eventually + reclaim any just-allocated incompressible pairs. */ + XSETCDR (pair, ltv_mark); + } + + v = (emacs_value) ((intptr_t) XCONS (pair) + Lisp_Cons); + } + + eassert (EQ (o, value_to_lisp (v))); + return v; } @@ -1048,10 +1058,9 @@ module_format_fun_env (const struct module_fun_env *env) void syms_of_module (void) { - module_nil = lisp_to_value (Qnil); -#ifdef WIDE_EMACS_INT - ltv_mark = Fcons (Qnil, Qnil); -#endif + if (!plain_values) + ltv_mark = Fcons (Qnil, Qnil); + eassert (NILP (value_to_lisp (module_nil))); DEFSYM (Qmodule_refs_hash, "module-refs-hash"); DEFVAR_LISP ("module-refs-hash", Vmodule_refs_hash, @@ -1111,9 +1120,7 @@ module_init (void) { /* It is not guaranteed that dynamic initializers run in the main thread, therefore detect the main thread here. */ -#ifdef HAVE_THREADS_H - main_thread = thrd_current (); -#elif defined HAVE_PTHREAD +#ifdef HAVE_PTHREAD main_thread = pthread_self (); #elif defined WINDOWSNT /* The 'main' function already recorded the main thread's thread ID, diff --git a/src/fileio.c b/src/fileio.c index 6cda1e39ee..e18ddb1a7a 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -4263,9 +4263,14 @@ by calling `format-decode', which see. */) if (CODING_FOR_UNIBYTE (&coding) /* Can't do this if part of the buffer might be preserved. */ && NILP (replace)) - /* Visiting a file with these coding system makes the buffer - unibyte. */ - bset_enable_multibyte_characters (current_buffer, Qnil); + { + /* Visiting a file with these coding system makes the buffer + unibyte. */ + if (inserted > 0) + bset_enable_multibyte_characters (current_buffer, Qnil); + else + Fset_buffer_multibyte (Qnil); + } } coding.dst_multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters)); diff --git a/src/frame.c b/src/frame.c index c388986e35..4897052e1f 100644 --- a/src/frame.c +++ b/src/frame.c @@ -2641,13 +2641,16 @@ If FRAME is nil, describe the currently selected frame. */) DEFUN ("modify-frame-parameters", Fmodify_frame_parameters, Smodify_frame_parameters, 2, 2, 0, - doc: /* Modify the parameters of frame FRAME according to ALIST. + doc: /* Modify FRAME according to new values of its parameters in ALIST. If FRAME is nil, it defaults to the selected frame. ALIST is an alist of parameters to change and their new values. Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol. -The meaningful PARMs depend on the kind of frame. -Undefined PARMs are ignored, but stored in the frame's parameter list -so that `frame-parameters' will return them. +Which PARMs are meaningful depends on the kind of frame. +The meaningful parameters are acted upon, i.e. the frame is changed +according to their new values, and are also stored in the frame's +parameter list so that `frame-parameters' will return them. +PARMs that are not meaningful are still stored in the frame's parameter +list, but are otherwise ignored. The value of frame parameter FOO can also be accessed as a frame-local binding for the variable FOO, if you have diff --git a/src/indent.c b/src/indent.c index 04837f8f51..33bf424b34 100644 --- a/src/indent.c +++ b/src/indent.c @@ -2080,11 +2080,7 @@ whether or not it is currently displayed in some window. */) } else it_overshoot_count = - (!(it.method == GET_FROM_IMAGE - || it.method == GET_FROM_STRETCH) - /* We will overshoot if lines are truncated and PT lies - beyond the right margin of the window. */ - || it.line_wrap == TRUNCATE); + !(it.method == GET_FROM_IMAGE || it.method == GET_FROM_STRETCH); if (start_x_given) { @@ -2142,6 +2138,11 @@ whether or not it is currently displayed in some window. */) screen lines we need to backtrack. */ it_overshoot_count = it.vpos; } + /* We will overshoot if lines are truncated and point lies + beyond the right margin of the window. */ + if (it.line_wrap == TRUNCATE && it.current_x >= it.last_visible_x + && it_overshoot_count == 0) + it_overshoot_count = 1; if (it_overshoot_count > 0) move_it_by_lines (&it, -it_overshoot_count); diff --git a/src/lisp.h b/src/lisp.h index 4bf7f38af8..995760a501 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -357,7 +357,7 @@ error !; # define lisp_h_XINT(a) (XLI (a) >> INTTYPEBITS) # define lisp_h_XSYMBOL(a) \ (eassert (SYMBOLP (a)), \ - (struct Lisp_Symbol *) ((uintptr_t) XLI (a) - Lisp_Symbol \ + (struct Lisp_Symbol *) ((intptr_t) XLI (a) - Lisp_Symbol \ + (char *) lispsym)) # define lisp_h_XTYPE(a) ((enum Lisp_Type) (XLI (a) & ~VALMASK)) # define lisp_h_XUNTAG(a, type) ((void *) (intptr_t) (XLI (a) - (type))) @@ -369,6 +369,12 @@ error !; #if (defined __NO_INLINE__ \ && ! defined __OPTIMIZE__ && ! defined __OPTIMIZE_SIZE__ \ && ! (defined INLINING && ! INLINING)) +# define DEFINE_KEY_OPS_AS_MACROS true +#else +# define DEFINE_KEY_OPS_AS_MACROS false +#endif + +#if DEFINE_KEY_OPS_AS_MACROS # define XLI(o) lisp_h_XLI (o) # define XIL(i) lisp_h_XIL (i) # define CHECK_LIST_CONS(x, y) lisp_h_CHECK_LIST_CONS (x, y) @@ -713,9 +719,15 @@ struct Lisp_Symbol #define DEFUN_ARGS_8 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \ Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object) -/* Yield an integer that contains TAG along with PTR. */ +/* Yield a signed integer that contains TAG along with PTR. + + Sign-extend pointers when USE_LSB_TAG (this simplifies emacs-module.c), + and zero-extend otherwise (that’s a bit faster here). + Sign extension matters only when EMACS_INT is wider than a pointer. */ #define TAG_PTR(tag, ptr) \ - ((USE_LSB_TAG ? (tag) : (EMACS_UINT) (tag) << VALBITS) + (uintptr_t) (ptr)) + (USE_LSB_TAG \ + ? (intptr_t) (ptr) + (tag) \ + : (EMACS_INT) (((EMACS_UINT) (tag) << VALBITS) + (uintptr_t) (ptr))) /* Yield an integer that contains a symbol tag along with OFFSET. OFFSET should be the offset in bytes from 'lispsym' to the symbol. */ @@ -934,7 +946,7 @@ INLINE struct Lisp_Symbol * XSYMBOL (Lisp_Object a) { eassert (SYMBOLP (a)); - uintptr_t i = (uintptr_t) XUNTAG (a, Lisp_Symbol); + intptr_t i = (intptr_t) XUNTAG (a, Lisp_Symbol); void *p = (char *) lispsym + i; return p; } @@ -3919,7 +3931,6 @@ extern Lisp_Object make_user_ptr (void (*finalizer) (void*), void *p); /* Defined in emacs-module.c. */ extern void module_init (void); -extern void mark_modules (void); extern void syms_of_module (void); #endif diff --git a/src/lread.c b/src/lread.c index 0da5819d34..74a5fdfe67 100644 --- a/src/lread.c +++ b/src/lread.c @@ -4353,7 +4353,7 @@ init_lread (void) load_path_check (default_lpath); /* Add the site-lisp directories to the front of the default. */ - if (!no_site_lisp) + if (!no_site_lisp && PATH_SITELOADSEARCH[0] != '\0') { Lisp_Object sitelisp; sitelisp = decode_env_path (0, PATH_SITELOADSEARCH, 0); @@ -4384,7 +4384,7 @@ init_lread (void) load_path_check (Vload_path); /* Add the site-lisp directories at the front. */ - if (initialized && !no_site_lisp) + if (initialized && !no_site_lisp && PATH_SITELOADSEARCH[0] != '\0') { Lisp_Object sitelisp; sitelisp = decode_env_path (0, PATH_SITELOADSEARCH, 0); diff --git a/src/macfont.m b/src/macfont.m index fae284fad8..3023fbea78 100644 --- a/src/macfont.m +++ b/src/macfont.m @@ -771,7 +771,7 @@ mac_font_descriptor_get_adjusted_weight (CTFontDescriptorRef desc, CGFloat val) { long percent_val = lround (val * 100); - if (percent_val == -40 || percent_val == 56) + if (percent_val == -40) { CTFontRef font = NULL; CFStringRef name = @@ -786,19 +786,10 @@ mac_font_descriptor_get_adjusted_weight (CTFontDescriptorRef desc, CGFloat val) { CFIndex weight = mac_font_get_weight (font); - if (percent_val == -40) - { - /* Workaround for crash when displaying Oriya characters - with Arial Unicode MS on OS X 10.11. */ - if (weight == 5) - val = 0; - } - else /* percent_val == 56 */ - { - if (weight == 9) - /* Adjustment for HiraginoSans-W7 on OS X 10.11. */ - val = 0.4; - } + /* Workaround for crash when displaying Oriya characters + with Arial Unicode MS on OS X 10.11. */ + if (weight == 5) + val = 0; CFRelease (font); } } diff --git a/src/puresize.h b/src/puresize.h index f07562429d..96ddcde24a 100644 --- a/src/puresize.h +++ b/src/puresize.h @@ -81,21 +81,35 @@ extern _Noreturn void pure_write_error (Lisp_Object); extern EMACS_INT pure[]; +/* The puresize_h_* macros are private to this include file. */ + /* True if PTR is pure. */ + +#define puresize_h_PURE_P(ptr) \ + ((uintptr_t) (ptr) - (uintptr_t) pure <= PURESIZE) + INLINE bool PURE_P (void *ptr) { - return (uintptr_t) (ptr) - (uintptr_t) pure <= PURESIZE; + return puresize_h_PURE_P (ptr); } /* Signal an error if OBJ is pure. PTR is OBJ untagged. */ + +#define puresize_h_CHECK_IMPURE(obj, ptr) \ + (PURE_P (ptr) ? pure_write_error (obj) : (void) 0) + INLINE void CHECK_IMPURE (Lisp_Object obj, void *ptr) { - if (PURE_P (ptr)) - pure_write_error (obj); + puresize_h_CHECK_IMPURE (obj, ptr); } +#if DEFINE_KEY_OPS_AS_MACROS +# define PURE_P(ptr) puresize_h_PURE_P (ptr) +# define CHECK_IMPURE(obj, ptr) puresize_h_CHECK_IMPURE (obj, ptr) +#endif + INLINE_HEADER_END #endif /* EMACS_PURESIZE_H */ diff --git a/src/w32fns.c b/src/w32fns.c index 208c9805e9..4be322182c 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -1666,10 +1666,7 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) FRAME_MENU_BAR_LINES (f) = 0; FRAME_MENU_BAR_HEIGHT (f) = 0; if (nlines) - { - FRAME_EXTERNAL_MENU_BAR (f) = 1; - windows_or_buffers_changed = 23; - } + FRAME_EXTERNAL_MENU_BAR (f) = 1; else { if (FRAME_EXTERNAL_MENU_BAR (f) == 1) @@ -4620,8 +4617,7 @@ my_create_tip_window (struct frame *f) rect.right = FRAME_PIXEL_WIDTH (f); rect.bottom = FRAME_PIXEL_HEIGHT (f); - AdjustWindowRect (&rect, f->output_data.w32->dwStyle, - FRAME_EXTERNAL_MENU_BAR (f)); + AdjustWindowRect (&rect, f->output_data.w32->dwStyle, false); tip_window = FRAME_W32_WINDOW (f) = CreateWindow (EMACS_CLASS, @@ -6381,7 +6377,7 @@ compute_tip_xy (struct frame *f, if (INTEGERP (left)) *root_x = XINT (left); else if (INTEGERP (right)) - *root_y = XINT (right) - width; + *root_x = XINT (right) - width; else if (*root_x + XINT (dx) <= min_x) *root_x = 0; /* Can happen for negative dx */ else if (*root_x + XINT (dx) + width <= max_x) @@ -6681,8 +6677,7 @@ Text larger than the specified size is clipped. */) rect.left = rect.top = 0; rect.right = width; rect.bottom = height; - AdjustWindowRect (&rect, f->output_data.w32->dwStyle, - FRAME_EXTERNAL_MENU_BAR (f)); + AdjustWindowRect (&rect, f->output_data.w32->dwStyle, false); /* Position and size tooltip, and put it in the topmost group. The add-on of FRAME_COLUMN_WIDTH to the 5th argument is a diff --git a/src/w32menu.c b/src/w32menu.c index 6af69f482d..964b965fac 100644 --- a/src/w32menu.c +++ b/src/w32menu.c @@ -494,7 +494,10 @@ set_frame_menubar (struct frame *f, bool first_time, bool deep_p) /* Force the window size to be recomputed so that the frame's text area remains the same, if menubar has just been created. */ if (old_widget == NULL) - adjust_frame_size (f, -1, -1, 2, false, Qmenu_bar_lines); + { + windows_or_buffers_changed = 23; + adjust_frame_size (f, -1, -1, 2, false, Qmenu_bar_lines); + } } unblock_input (); diff --git a/src/w32term.c b/src/w32term.c index f48e72553a..0b8bef239f 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -6115,9 +6115,22 @@ x_set_window_size (struct frame *f, bool change_gravity, int pixelwidth, pixelheight; Lisp_Object fullscreen = get_frame_param (f, Qfullscreen); RECT rect; + MENUBARINFO info; + int menu_bar_height; block_input (); + /* Get the height of the menu bar here. It's used below to detect + whether the menu bar is wrapped. It's also used to specify the + third argument for AdjustWindowRect. FRAME_EXTERNAL_MENU_BAR which + has been used before for that reason is unreliable because it only + specifies whether we _want_ a menu bar for this frame and not + whether this frame _has_ a menu bar. See bug#22105. */ + info.cbSize = sizeof (info); + info.rcBar.top = info.rcBar.bottom = 0; + GetMenuBarInfo (FRAME_W32_WINDOW (f), 0xFFFFFFFD, 0, &info); + menu_bar_height = info.rcBar.bottom - info.rcBar.top; + if (pixelwise) { pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width); @@ -6135,17 +6148,11 @@ x_set_window_size (struct frame *f, bool change_gravity, height of the frame then the wrapped menu bar lines are not accounted for (Bug#15174 and Bug#18720). Here we add these extra lines to the frame height. */ - MENUBARINFO info; int default_menu_bar_height; - int menu_bar_height; /* Why is (apparently) SM_CYMENUSIZE needed here instead of SM_CYMENU ?? */ default_menu_bar_height = GetSystemMetrics (SM_CYMENUSIZE); - info.cbSize = sizeof (info); - info.rcBar.top = info.rcBar.bottom = 0; - GetMenuBarInfo (FRAME_W32_WINDOW (f), 0xFFFFFFFD, 0, &info); - menu_bar_height = info.rcBar.bottom - info.rcBar.top; if ((default_menu_bar_height > 0) && (menu_bar_height > default_menu_bar_height) @@ -6160,8 +6167,7 @@ x_set_window_size (struct frame *f, bool change_gravity, rect.right = pixelwidth; rect.bottom = pixelheight; - AdjustWindowRect (&rect, f->output_data.w32->dwStyle, - FRAME_EXTERNAL_MENU_BAR (f)); + AdjustWindowRect (&rect, f->output_data.w32->dwStyle, menu_bar_height > 0); if (!(f->after_make_frame) && !(f->want_fullscreen & FULLSCREEN_WAIT) diff --git a/src/xdisp.c b/src/xdisp.c index d1a10ca3c3..37dc6047e5 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -16301,9 +16301,33 @@ redisplay_window (Lisp_Object window, bool just_this_one_p) if (w->cursor.vpos < 0) { /* If point does not appear, try to move point so it does - appear. The desired matrix has been built above, so we - can use it here. */ - new_vpos = window_box_height (w) / 2; + appear. The desired matrix has been built above, so we + can use it here. First see if point is in invisible + text, and if so, move it to the first visible buffer + position past that. */ + struct glyph_row *r = NULL; + Lisp_Object invprop = + get_char_property_and_overlay (make_number (PT), Qinvisible, + Qnil, NULL); + + if (TEXT_PROP_MEANS_INVISIBLE (invprop) != 0) + { + ptrdiff_t alt_pt; + Lisp_Object invprop_end = + Fnext_single_char_property_change (make_number (PT), Qinvisible, + Qnil, Qnil); + + if (NATNUMP (invprop_end)) + alt_pt = XFASTINT (invprop_end); + else + alt_pt = ZV; + r = row_containing_pos (w, alt_pt, w->desired_matrix->rows, + NULL, 0); + } + if (r) + new_vpos = MATRIX_ROW_BOTTOM_Y (r); + else /* Give up and just move to the middle of the window. */ + new_vpos = window_box_height (w) / 2; } if (!cursor_row_fully_visible_p (w, false, false)) @@ -16720,6 +16744,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p) startp = run_window_scroll_functions (window, it.current.pos); /* Redisplay the window. */ + bool use_desired_matrix = false; if (!current_matrix_up_to_date_p || windows_or_buffers_changed || f->cursor_type_changed @@ -16730,7 +16755,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p) || MINI_WINDOW_P (w) || !(used_current_matrix_p = try_window_reusing_current_matrix (w))) - try_window (window, startp, 0); + use_desired_matrix = (try_window (window, startp, 0) == 1); /* If new fonts have been loaded (due to fontsets), give up. We have to start a new redisplay since we need to re-adjust glyph @@ -16770,9 +16795,15 @@ redisplay_window (Lisp_Object window, bool just_this_one_p) and similar ones. */ if (w->cursor.vpos < 0) { + /* Prefer the desired matrix to the current matrix, if possible, + in the fallback calculations below. This is because using + the current matrix might completely goof, e.g. if its first + row is after point. */ + struct glyph_matrix *matrix = + use_desired_matrix ? w->desired_matrix : w->current_matrix; /* First, try locating the proper glyph row for PT. */ struct glyph_row *row = - row_containing_pos (w, PT, w->current_matrix->rows, NULL, 0); + row_containing_pos (w, PT, matrix->rows, NULL, 0); /* Sometimes point is at the beginning of invisible text that is before the 1st character displayed in the row. In that case, @@ -16797,8 +16828,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p) alt_pos = XFASTINT (invis_end); else alt_pos = ZV; - row = row_containing_pos (w, alt_pos, w->current_matrix->rows, - NULL, 0); + row = row_containing_pos (w, alt_pos, matrix->rows, NULL, 0); } } /* Finally, fall back on the first row of the window after the @@ -16806,11 +16836,11 @@ redisplay_window (Lisp_Object window, bool just_this_one_p) displaying the cursor at all. */ if (!row) { - row = w->current_matrix->rows; + row = matrix->rows; if (row->mode_line_p) ++row; } - set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0); + set_cursor_from_row (w, row, matrix, 0, 0, 0, 0); } if (!cursor_row_fully_visible_p (w, false, false)) @@ -17795,7 +17825,7 @@ row_containing_pos (struct window *w, ptrdiff_t charpos, while (true) { /* Give up if we have gone too far. */ - if (end && row >= end) + if ((end && row >= end) || !row->enabled_p) return NULL; /* This formerly returned if they were equal. I think that both quantities are of a "last plus one" type; diff --git a/src/xfns.c b/src/xfns.c index 313ac52f12..ab6b92256b 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -5719,7 +5719,7 @@ compute_tip_xy (struct frame *f, Lisp_Object parms, Lisp_Object dx, Lisp_Object if (INTEGERP (left)) *root_x = XINT (left); else if (INTEGERP (right)) - *root_y = XINT (right) - width; + *root_x = XINT (right) - width; else if (*root_x + XINT (dx) <= 0) *root_x = 0; /* Can happen for negative dx */ else if (*root_x + XINT (dx) + width diff --git a/test/automated/auth-source-tests.el b/test/automated/auth-source-tests.el index 0b49b9013f..dd70d546d5 100644 --- a/test/automated/auth-source-tests.el +++ b/test/automated/auth-source-tests.el @@ -174,5 +174,50 @@ (:search-function . auth-source-secrets-search) (:create-function . auth-source-secrets-create))))) +(defun auth-source--test-netrc-parse-entry (entry host user port) + "Parse a netrc entry from buffer." + (auth-source-forget-all-cached) + (setq port (auth-source-ensure-strings port)) + (with-temp-buffer + (insert entry) + (goto-char (point-min)) + (let* ((check (lambda(alist) + (and alist + (auth-source-search-collection + host + (or + (auth-source--aget alist "machine") + (auth-source--aget alist "host") + t)) + (auth-source-search-collection + user + (or + (auth-source--aget alist "login") + (auth-source--aget alist "account") + (auth-source--aget alist "user") + t)) + (auth-source-search-collection + port + (or + (auth-source--aget alist "port") + (auth-source--aget alist "protocol") + t))))) + (entries (auth-source-netrc-parse-entries check 1))) + entries))) + +(ert-deftest auth-source-test-netrc-parse-entry () + (should (equal (auth-source--test-netrc-parse-entry + "machine mymachine1 login user1 password pass1\n" t t t) + '((("password" . "pass1") + ("login" . "user1") + ("machine" . "mymachine1"))))) + (should (equal (auth-source--test-netrc-parse-entry + "machine mymachine1 login user1 password pass1 port 100\n" + t t t) + '((("port" . "100") + ("password" . "pass1") + ("login" . "user1") + ("machine" . "mymachine1")))))) + (provide 'auth-source-tests) ;;; auth-source-tests.el ends here diff --git a/test/automated/auto-revert-tests.el b/test/automated/auto-revert-tests.el index 2745f10608..e03ed8cb68 100644 --- a/test/automated/auto-revert-tests.el +++ b/test/automated/auto-revert-tests.el @@ -39,7 +39,9 @@ (null (string-match (format-message "Reverting buffer `%s'." (buffer-name buffer)) (buffer-string))) - (read-event nil nil 0.1))))) + (if (with-current-buffer buffer auto-revert-use-notify) + (read-event nil nil 0.1) + (sleep-for 0.1)))))) (ert-deftest auto-revert-test00-auto-revert-mode () "Check autorevert for a file." diff --git a/test/automated/character-fold-tests.el b/test/automated/character-fold-tests.el index 4e8761e6f7..c056862564 100644 --- a/test/automated/character-fold-tests.el +++ b/test/automated/character-fold-tests.el @@ -113,7 +113,7 @@ ;; Our initial implementation of case-folding in char-folding ;; created a lot of redundant paths in the regexp. Because of ;; that, if a really long string "almost" matches, the regexp - ;; engine took a long time to realise that it doesn't match. + ;; engine took a long time to realize that it doesn't match. (should-not (character-fold-search-forward (concat string "c") nil 'noerror)) ;; Ensure it took less than a second. (should (< (- (time-to-seconds (current-time)) diff --git a/test/automated/data/package/macro-problem-package-1.0/macro-aux.el b/test/automated/data/package/macro-problem-package-1.0/macro-aux.el index 9d14a21163..f43232224a 100644 --- a/test/automated/data/package/macro-problem-package-1.0/macro-aux.el +++ b/test/automated/data/package/macro-problem-package-1.0/macro-aux.el @@ -1,26 +1,7 @@ ;;; macro-aux.el --- laksd -*- lexical-binding: t; -*- -;; Copyright (C) 2015 Artur Malabarba - ;; Author: Artur Malabarba <emacs@endlessparentheses.com> -;; This program is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation, either version 3 of the License, or -;; (at your option) any later version. - -;; This program is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with this program. If not, see <http://www.gnu.org/licenses/>. - -;;; Commentary: - -;; - ;;; Code: (defun macro-aux-1 ( &rest forms) diff --git a/test/automated/data/package/macro-problem-package-1.0/macro-problem.el b/test/automated/data/package/macro-problem-package-1.0/macro-problem.el index a44074c4f8..0533b1bd9c 100644 --- a/test/automated/data/package/macro-problem-package-1.0/macro-problem.el +++ b/test/automated/data/package/macro-problem-package-1.0/macro-problem.el @@ -1,28 +1,9 @@ ;;; macro-problem.el --- laksd -*- lexical-binding: t; -*- -;; Copyright (C) 2015 Artur Malabarba - ;; Author: Artur Malabarba <emacs@endlessparentheses.com> ;; Keywords: tools ;; Version: 1.0 -;; This program is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation, either version 3 of the License, or -;; (at your option) any later version. - -;; This program is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with this program. If not, see <http://www.gnu.org/licenses/>. - -;;; Commentary: - -;; - ;;; Code: (require 'macro-aux) diff --git a/test/automated/data/package/macro-problem-package-2.0/macro-aux.el b/test/automated/data/package/macro-problem-package-2.0/macro-aux.el index 4785cd7803..6a55a40e3b 100644 --- a/test/automated/data/package/macro-problem-package-2.0/macro-aux.el +++ b/test/automated/data/package/macro-problem-package-2.0/macro-aux.el @@ -1,26 +1,7 @@ ;;; macro-aux.el --- laksd -*- lexical-binding: t; -*- -;; Copyright (C) 2015 Artur Malabarba - ;; Author: Artur Malabarba <emacs@endlessparentheses.com> -;; This program is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation, either version 3 of the License, or -;; (at your option) any later version. - -;; This program is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with this program. If not, see <http://www.gnu.org/licenses/>. - -;;; Commentary: - -;; - ;;; Code: (defmacro macro-aux-1 ( &rest forms) diff --git a/test/automated/data/package/macro-problem-package-2.0/macro-problem.el b/test/automated/data/package/macro-problem-package-2.0/macro-problem.el index ead3d29dc3..cad4ed93f1 100644 --- a/test/automated/data/package/macro-problem-package-2.0/macro-problem.el +++ b/test/automated/data/package/macro-problem-package-2.0/macro-problem.el @@ -1,28 +1,9 @@ ;;; macro-problem.el --- laksd -*- lexical-binding: t; -*- -;; Copyright (C) 2015 Artur Malabarba - ;; Author: Artur Malabarba <emacs@endlessparentheses.com> ;; Keywords: tools ;; Version: 2.0 -;; This program is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation, either version 3 of the License, or -;; (at your option) any later version. - -;; This program is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with this program. If not, see <http://www.gnu.org/licenses/>. - -;;; Commentary: - -;; - ;;; Code: (require 'macro-aux) diff --git a/test/automated/icalendar-tests.el b/test/automated/icalendar-tests.el index 7e05d49883..829cbf2d76 100644 --- a/test/automated/icalendar-tests.el +++ b/test/automated/icalendar-tests.el @@ -2231,7 +2231,63 @@ END:VCALENDAR" Class: PUBLIC UID: 040000008200E00074C5B7101A82E0080000000020FFAED0CFEFCC01000000000000000010000000575268034ECDB649A15349B1BF240F15 " nil) + + ;; 2015-12-05, mixed line endings and empty lines, see Bug#22092. + (icalendar-tests--test-import + "BEGIN:VCALENDAR\r +PRODID:-//www.norwegian.no//iCalendar MIMEDIR//EN\r +VERSION:2.0\r +METHOD:REQUEST\r +BEGIN:VEVENT\r +UID:RFCALITEM1\r +SEQUENCE:1512040950\r +DTSTAMP:20141204T095043Z\r +ORGANIZER:noreply@norwegian.no\r +DTSTART:20141208T173000Z\r + +DTEND:20141208T215500Z\r + +LOCATION:Stavanger-Sola\r + +DESCRIPTION:Fly med Norwegian, reservasjon. Fra Stavanger til Tromsø 8. des 2014 18:30, DY545Fly med Norwegian, reservasjon . Fra Stavanger til Tromsø 8. des 2014 21:00, DY390\r + +X-ALT-DESC;FMTTYPE=text/html:<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\"><html><head><META NAME=\"Generator\" CONTENT=\"MS Exchange Server version 08.00.0681.000\"><title></title></head><body><b><font face=\"Calibri\" size=\"3\">Reisereferanse</p></body></html> +SUMMARY:Norwegian til Tromsoe-Langnes -\r + +CATEGORIES:Appointment\r + + +PRIORITY:5\r + +CLASS:PUBLIC\r + +TRANSP:OPAQUE\r +END:VEVENT\r +END:VCALENDAR +" +"&2014/12/8 18:30-22:55 Norwegian til Tromsoe-Langnes - + Desc: Fly med Norwegian, reservasjon. Fra Stavanger til Tromsø 8. des 2014 18:30, DY545Fly med Norwegian, reservasjon . Fra Stavanger til Tromsø 8. des 2014 21:00, DY390 + Location: Stavanger-Sola + Organizer: noreply@norwegian.no + Class: PUBLIC + UID: RFCALITEM1 +" +"&8/12/2014 18:30-22:55 Norwegian til Tromsoe-Langnes - + Desc: Fly med Norwegian, reservasjon. Fra Stavanger til Tromsø 8. des 2014 18:30, DY545Fly med Norwegian, reservasjon . Fra Stavanger til Tromsø 8. des 2014 21:00, DY390 + Location: Stavanger-Sola + Organizer: noreply@norwegian.no + Class: PUBLIC + UID: RFCALITEM1 +" +"&12/8/2014 18:30-22:55 Norwegian til Tromsoe-Langnes - + Desc: Fly med Norwegian, reservasjon. Fra Stavanger til Tromsø 8. des 2014 18:30, DY545Fly med Norwegian, reservasjon . Fra Stavanger til Tromsø 8. des 2014 21:00, DY390 + Location: Stavanger-Sola + Organizer: noreply@norwegian.no + Class: PUBLIC + UID: RFCALITEM1 +" ) + ) (provide 'icalendar-tests) ;;; icalendar-tests.el ends here diff --git a/test/automated/simple-test.el b/test/automated/simple-test.el index c758d7cc8e..771241ad7e 100644 --- a/test/automated/simple-test.el +++ b/test/automated/simple-test.el @@ -226,9 +226,9 @@ ;;; auto-boundary tests -(ert-deftest undo-auto--boundary-timer () +(ert-deftest undo-auto-boundary-timer () (should - undo-auto--current-boundary-timer)) + undo-auto-current-boundary-timer)) (ert-deftest undo-auto--boundaries-added () ;; The change in the buffer should have caused addition diff --git a/test/automated/subr-tests.el b/test/automated/subr-tests.el index ee8db593b4..3fcb7d346a 100644 --- a/test/automated/subr-tests.el +++ b/test/automated/subr-tests.el @@ -103,5 +103,117 @@ (should (equal (macroexpand-all '(when a b c d)) '(if a (progn b c d))))) +(ert-deftest subr-test-version-parsing () + (should (equal (version-to-list ".5") '(0 5))) + (should (equal (version-to-list "0.9 alpha1") '(0 9 -3 1))) + (should (equal (version-to-list "0.9 snapshot") '(0 9 -4))) + (should (equal (version-to-list "0.9-alpha1") '(0 9 -3 1))) + (should (equal (version-to-list "0.9-snapshot") '(0 9 -4))) + (should (equal (version-to-list "0.9.snapshot") '(0 9 -4))) + (should (equal (version-to-list "0.9_snapshot") '(0 9 -4))) + (should (equal (version-to-list "0.9alpha1") '(0 9 -3 1))) + (should (equal (version-to-list "0.9snapshot") '(0 9 -4))) + (should (equal (version-to-list "1.0 git") '(1 0 -4))) + (should (equal (version-to-list "1.0 pre2") '(1 0 -1 2))) + (should (equal (version-to-list "1.0-git") '(1 0 -4))) + (should (equal (version-to-list "1.0-pre2") '(1 0 -1 2))) + (should (equal (version-to-list "1.0.1-a") '(1 0 1 1))) + (should (equal (version-to-list "1.0.1-f") '(1 0 1 6))) + (should (equal (version-to-list "1.0.1.a") '(1 0 1 1))) + (should (equal (version-to-list "1.0.1.f") '(1 0 1 6))) + (should (equal (version-to-list "1.0.1_a") '(1 0 1 1))) + (should (equal (version-to-list "1.0.1_f") '(1 0 1 6))) + (should (equal (version-to-list "1.0.1a") '(1 0 1 1))) + (should (equal (version-to-list "1.0.1f") '(1 0 1 6))) + (should (equal (version-to-list "1.0.7.5") '(1 0 7 5))) + (should (equal (version-to-list "1.0.git") '(1 0 -4))) + (should (equal (version-to-list "1.0.pre2") '(1 0 -1 2))) + (should (equal (version-to-list "1.0_git") '(1 0 -4))) + (should (equal (version-to-list "1.0_pre2") '(1 0 -1 2))) + (should (equal (version-to-list "1.0git") '(1 0 -4))) + (should (equal (version-to-list "1.0pre2") '(1 0 -1 2))) + (should (equal (version-to-list "22.8 beta3") '(22 8 -2 3))) + (should (equal (version-to-list "22.8-beta3") '(22 8 -2 3))) + (should (equal (version-to-list "22.8.beta3") '(22 8 -2 3))) + (should (equal (version-to-list "22.8_beta3") '(22 8 -2 3))) + (should (equal (version-to-list "22.8beta3") '(22 8 -2 3))) + (should (equal (version-to-list "6.9.30 Beta") '(6 9 30 -2))) + (should (equal (version-to-list "6.9.30-Beta") '(6 9 30 -2))) + (should (equal (version-to-list "6.9.30.Beta") '(6 9 30 -2))) + (should (equal (version-to-list "6.9.30Beta") '(6 9 30 -2))) + (should (equal (version-to-list "6.9.30_Beta") '(6 9 30 -2))) + + (should (equal + (error-message-string (should-error (version-to-list "OTP-18.1.5"))) + "Invalid version syntax: `OTP-18.1.5' (must start with a number)")) + (should (equal + (error-message-string (should-error (version-to-list ""))) + "Invalid version syntax: `' (must start with a number)")) + (should (equal + (error-message-string (should-error (version-to-list "1.0..7.5"))) + "Invalid version syntax: `1.0..7.5'")) + (should (equal + (error-message-string (should-error (version-to-list "1.0prepre2"))) + "Invalid version syntax: `1.0prepre2'")) + (should (equal + (error-message-string (should-error (version-to-list "22.8X3"))) + "Invalid version syntax: `22.8X3'")) + (should (equal + (error-message-string (should-error (version-to-list "beta22.8alpha3"))) + "Invalid version syntax: `beta22.8alpha3' (must start with a number)")) + (should (equal + (error-message-string (should-error (version-to-list "honk"))) + "Invalid version syntax: `honk' (must start with a number)")) + (should (equal + (error-message-string (should-error (version-to-list 9))) + "Version must be a string")) + + (let ((version-separator "_")) + (should (equal (version-to-list "_5") '(0 5))) + (should (equal (version-to-list "0_9 alpha1") '(0 9 -3 1))) + (should (equal (version-to-list "0_9 snapshot") '(0 9 -4))) + (should (equal (version-to-list "0_9-alpha1") '(0 9 -3 1))) + (should (equal (version-to-list "0_9-snapshot") '(0 9 -4))) + (should (equal (version-to-list "0_9.alpha1") '(0 9 -3 1))) + (should (equal (version-to-list "0_9.snapshot") '(0 9 -4))) + (should (equal (version-to-list "0_9alpha1") '(0 9 -3 1))) + (should (equal (version-to-list "0_9snapshot") '(0 9 -4))) + (should (equal (version-to-list "1_0 git") '(1 0 -4))) + (should (equal (version-to-list "1_0 pre2") '(1 0 -1 2))) + (should (equal (version-to-list "1_0-git") '(1 0 -4))) + (should (equal (version-to-list "1_0.pre2") '(1 0 -1 2))) + (should (equal (version-to-list "1_0_1-a") '(1 0 1 1))) + (should (equal (version-to-list "1_0_1-f") '(1 0 1 6))) + (should (equal (version-to-list "1_0_1.a") '(1 0 1 1))) + (should (equal (version-to-list "1_0_1.f") '(1 0 1 6))) + (should (equal (version-to-list "1_0_1_a") '(1 0 1 1))) + (should (equal (version-to-list "1_0_1_f") '(1 0 1 6))) + (should (equal (version-to-list "1_0_1a") '(1 0 1 1))) + (should (equal (version-to-list "1_0_1f") '(1 0 1 6))) + (should (equal (version-to-list "1_0_7_5") '(1 0 7 5))) + (should (equal (version-to-list "1_0_git") '(1 0 -4))) + (should (equal (version-to-list "1_0pre2") '(1 0 -1 2))) + (should (equal (version-to-list "22_8 beta3") '(22 8 -2 3))) + (should (equal (version-to-list "22_8-beta3") '(22 8 -2 3))) + (should (equal (version-to-list "22_8.beta3") '(22 8 -2 3))) + (should (equal (version-to-list "22_8beta3") '(22 8 -2 3))) + (should (equal (version-to-list "6_9_30 Beta") '(6 9 30 -2))) + (should (equal (version-to-list "6_9_30-Beta") '(6 9 30 -2))) + (should (equal (version-to-list "6_9_30.Beta") '(6 9 30 -2))) + (should (equal (version-to-list "6_9_30Beta") '(6 9 30 -2))) + + (should (equal + (error-message-string (should-error (version-to-list "1_0__7_5"))) + "Invalid version syntax: `1_0__7_5'")) + (should (equal + (error-message-string (should-error (version-to-list "1_0prepre2"))) + "Invalid version syntax: `1_0prepre2'")) + (should (equal + (error-message-string (should-error (version-to-list "22.8X3"))) + "Invalid version syntax: `22.8X3'")) + (should (equal + (error-message-string (should-error (version-to-list "beta22_8alpha3"))) + "Invalid version syntax: `beta22_8alpha3' (must start with a number)")))) + (provide 'subr-tests) ;;; subr-tests.el ends here diff --git a/test/automated/tramp-tests.el b/test/automated/tramp-tests.el index c5cab7d599..8a1743cd20 100644 --- a/test/automated/tramp-tests.el +++ b/test/automated/tramp-tests.el @@ -1987,7 +1987,10 @@ Use the `perl' command." (let ((tramp-connection-properties (append `((,(regexp-quote (file-remote-p tramp-test-temporary-file-directory)) - "stat" nil)) + "stat" nil) + ;; See `tramp-sh-handle-file-truename'. + (,(regexp-quote (file-remote-p tramp-test-temporary-file-directory)) + "readlink" nil)) tramp-connection-properties))) (tramp--test-special-characters))) @@ -2005,7 +2008,10 @@ Use the `ls' command." `((,(regexp-quote (file-remote-p tramp-test-temporary-file-directory)) "perl" nil) (,(regexp-quote (file-remote-p tramp-test-temporary-file-directory)) - "stat" nil)) + "stat" nil) + ;; See `tramp-sh-handle-file-truename'. + (,(regexp-quote (file-remote-p tramp-test-temporary-file-directory)) + "readlink" nil)) tramp-connection-properties))) (tramp--test-special-characters))) @@ -2059,7 +2065,10 @@ Use the `perl' command." (let ((tramp-connection-properties (append `((,(regexp-quote (file-remote-p tramp-test-temporary-file-directory)) - "stat" nil)) + "stat" nil) + ;; See `tramp-sh-handle-file-truename'. + (,(regexp-quote (file-remote-p tramp-test-temporary-file-directory)) + "readlink" nil)) tramp-connection-properties))) (tramp--test-utf8))) @@ -2077,7 +2086,10 @@ Use the `ls' command." `((,(regexp-quote (file-remote-p tramp-test-temporary-file-directory)) "perl" nil) (,(regexp-quote (file-remote-p tramp-test-temporary-file-directory)) - "stat" nil)) + "stat" nil) + ;; See `tramp-sh-handle-file-truename'. + (,(regexp-quote (file-remote-p tramp-test-temporary-file-directory)) + "readlink" nil)) tramp-connection-properties))) (tramp--test-utf8))) diff --git a/test/etags/CTAGS.good b/test/etags/CTAGS.good index c98e1388d3..245f6703ad 100644 --- a/test/etags/CTAGS.good +++ b/test/etags/CTAGS.good @@ -46,6 +46,7 @@ $user_comment_lc php-src/lce_functions.php 115 ($string,$flag,@string,@temp,@last perl-src/yagrip.pl 40 (a-forth-constant forth-src/test-forth.fth /^constant (a-forth-constant$/ (another-forth-word forth-src/test-forth.fth /^: (another-forth-word) ( -- )$/ ++ ruby-src/test.rb /^ def +(y)$/ + tex-src/texinfo.tex /^\\def+{{\\tt \\char 43}}$/ /.notdef ps-src/rfc1245.ps /^\/.notdef \/.notdef \/.notdef \/.notdef \/.notdef \/.not/ /.notdef ps-src/rfc1245.ps /^\/.notdef \/.notdef \/.notdef \/.notdef \/.notdef \/.not/ @@ -177,6 +178,9 @@ $user_comment_lc php-src/lce_functions.php 115 /yen ps-src/rfc1245.ps /^\/yen \/.notdef \/.notdef \/.notdef \/.notdef \/.notdef / :a-forth-dictionary-entry forth-src/test-forth.fth /^create :a-forth-dictionary-entry$/ < tex-src/texinfo.tex /^\\def<{{\\tt \\less}}$/ +<< ruby-src/test.rb /^ def <<(y)$/ +<= ruby-src/test.rb /^ def <=(y)$/ +<=> ruby-src/test.rb /^ def <=>(y)$/ = tex-src/texinfo.tex /^\\global\\let\\section = \\numberedsec$/ = tex-src/texinfo.tex /^\\global\\let\\subsection = \\numberedsubsec$/ = tex-src/texinfo.tex /^\\global\\let\\subsubsection = \\numberedsubsubsec$/ @@ -191,6 +195,8 @@ $user_comment_lc php-src/lce_functions.php 115 = tex-src/texinfo.tex /^\\global\\let\\subsubsection = \\numberedsubsubsec$/ = tex-src/texinfo.tex /^\\global\\def={{\\tt \\char 61}}}$/ =/f ada-src/etags-test-for.ada /^ function "=" (L, R : System.Address) return Boo/ +== ruby-src/test.rb /^ def ==(y)$/ +=== ruby-src/test.rb /^ def ===(y)$/ =\indexdummyfont tex-src/texinfo.tex /^\\let\\cite=\\indexdummyfont$/ =\relax tex-src/texinfo.tex /^\\let\\chapter=\\relax$/ =\relax tex-src/texinfo.tex /^\\let\\section=\\relax$/ @@ -220,6 +226,7 @@ A cp-src/c.C 73 A cp-src/c.C 117 A cp-src/fail.C 7 A cp-src/fail.C 23 +A ruby-src/test1.ruby /^class A$/ ADDRESS c-src/emacs/src/gmalloc.c /^#define ADDRESS(B) ((void *) (((B) - 1) * BLOCKSIZ/ ALIGNOF_STRUCT_LISP_VECTOR c-src/emacs/src/lisp.h 1378 ALLOCATED_BEFORE_DUMPING c-src/emacs/src/gmalloc.c /^#define ALLOCATED_BEFORE_DUMPING(P) \\$/ @@ -430,6 +437,8 @@ Circle.getPos lua-src/test.lua /^function Circle.getPos ()$/ Cjava_entries c-src/etags.c /^Cjava_entries (FILE *inf)$/ Cjava_help c-src/etags.c 551 Cjava_suffixes c-src/etags.c 549 +ClassExample ruby-src/test.rb /^ class ClassExample$/ +ClassExample.singleton_class_method ruby-src/test.rb /^ def ClassExample.singleton_class_method$/ Clear/p ada-src/2ataspri.adb /^ procedure Clear (Cell : in out TAS_Cell) is$/ Clear/p ada-src/2ataspri.ads /^ procedure Clear (Cell : in out TAS_Cell)/ Cobol_help c-src/etags.c 558 @@ -929,6 +938,8 @@ Mconway.cpp cp-src/conway.cpp /^void main(void)$/ Metags c-src/etags.c /^main (int argc, char **argv)$/ Mfail cp-src/fail.C /^main()$/ Mkai-test.pl perl-src/kai-test.pl /^package main;$/ +ModuleExample ruby-src/test.rb /^module ModuleExample$/ +ModuleExample.singleton_module_method ruby-src/test.rb /^ def ModuleExample.singleton_module_method$/ More_Lisp_Bits c-src/emacs/src/lisp.h 801 MoveLayerAfter lua-src/allegro.lua /^function MoveLayerAfter (this_one)$/ MoveLayerBefore lua-src/allegro.lua /^function MoveLayerBefore (this_one)$/ @@ -1652,6 +1663,8 @@ Yacc_entries c-src/etags.c /^Yacc_entries (FILE *inf)$/ Yacc_help c-src/etags.c 693 Yacc_suffixes c-src/etags.c 691 Z c-src/h.h 100 +[] ruby-src/test.rb /^ def [](y)$/ +[]= ruby-src/test.rb /^ def []=(y, val)$/ \ tex-src/texinfo.tex /^\\def\\ {{\\fontdimen2\\font=\\tclosesave{} }}%$/ \ tex-src/texinfo.tex /^\\gdef\\sepspaces{\\def {\\ }}}$/ \' tex-src/texinfo.tex /^\\def\\'{{'}}$/ @@ -2358,6 +2371,7 @@ _malloc_thread_enabled_p c-src/emacs/src/gmalloc.c 519 _realloc c-src/emacs/src/gmalloc.c /^_realloc (void *ptr, size_t size)$/ _realloc_internal c-src/emacs/src/gmalloc.c /^_realloc_internal (void *ptr, size_t size)$/ _realloc_internal_nolock c-src/emacs/src/gmalloc.c /^_realloc_internal_nolock (void *ptr, size_t size)$/ +` ruby-src/test.rb /^ def `(command)$/ a c.c 152 a c.c 180 a c.c /^a()$/ @@ -2365,6 +2379,7 @@ a c.c /^a ()$/ a c-src/h.h 40 a c-src/h.h 103 a cp-src/c.C 132 +a ruby-src/test1.ruby /^ def a()$/ a-forth-constant! forth-src/test-forth.fth /^99 constant a-forth-constant!$/ a-forth-value? forth-src/test-forth.fth /^55 value a-forth-value?$/ a-forth-word forth-src/test-forth.fth /^: a-forth-word ( a b c -- a*b+c ) + * ;$/ @@ -2489,6 +2504,7 @@ b c-src/h.h 41 b c-src/h.h 103 b c-src/h.h 104 b cp-src/c.C 132 +b ruby-src/test1.ruby /^ def b()$/ backslash=0 tex-src/texinfo.tex /^\\let\\indexbackslash=0 %overridden during \\printin/ bar c-src/c.c /^void bar() {while(0) {}}$/ bar c.c 143 @@ -2604,6 +2620,10 @@ childDidExit objc-src/Subprocess.m /^- childDidExit$/ chunks_free c-src/emacs/src/gmalloc.c 313 chunks_used c-src/emacs/src/gmalloc.c 311 cjava c-src/etags.c 2936 +class_method ruby-src/test.rb /^ def class_method$/ +class_method_equals= ruby-src/test.rb /^ def class_method_equals=$/ +class_method_exclamation! ruby-src/test.rb /^ def class_method_exclamation!$/ +class_method_question? ruby-src/test.rb /^ def class_method_question?$/ classifyLine php-src/lce_functions.php /^ function classifyLine($line)$/ clear cp-src/conway.hpp /^ void clear(void) { alive = 0; }$/ clear-abbrev-table c-src/abbrev.c /^DEFUN ("clear-abbrev-table", Fclear_abbrev_table, / @@ -3405,6 +3425,8 @@ mcCSC cp-src/c.C 6 mcheck c-src/emacs/src/gmalloc.c /^mcheck (void (*func) (enum mcheck_status))$/ mcheck_status c-src/emacs/src/gmalloc.c 283 mcheck_used c-src/emacs/src/gmalloc.c 2012 +me22b lua-src/test.lua /^ local function test.me22b (one)$/ +me_22a lua-src/test.lua /^ function test.me_22a(one, two)$/ memalign c-src/emacs/src/gmalloc.c /^memalign (size_t alignment, size_t size)$/ member prol-src/natded.prolog /^member(X,[X|_]).$/ memclear c-src/emacs/src/lisp.h /^memclear (void *p, ptrdiff_t nbytes)$/ @@ -3428,6 +3450,7 @@ miti html-src/softwarelibero.html /^Sfatiamo alcuni miti$/ modifier_names c-src/emacs/src/keyboard.c 6319 modifier_symbols c-src/emacs/src/keyboard.c 6327 modify_event_symbol c-src/emacs/src/keyboard.c /^modify_event_symbol (ptrdiff_t symbol_num, int mod/ +module_method ruby-src/test.rb /^ def module_method$/ more_aligned_int c.c 165 morecore_nolock c-src/emacs/src/gmalloc.c /^morecore_nolock (size_t size)$/ morecore_recursing c-src/emacs/src/gmalloc.c 604 @@ -4188,6 +4211,8 @@ test c-src/emacs/src/lisp.h 1871 test cp-src/c.C 86 test erl-src/gs_dialog.erl /^test() ->$/ test php-src/ptest.php /^test $/ +test.me22b lua-src/test.lua /^ local function test.me22b (one)$/ +test.me_22a lua-src/test.lua /^ function test.me_22a(one, two)$/ test_undefined c-src/emacs/src/keyboard.c /^test_undefined (Lisp_Object binding)$/ texttreelist prol-src/natded.prolog /^texttreelist([]).$/ this c-src/a/b/b.c 1 diff --git a/test/etags/ETAGS.good_1 b/test/etags/ETAGS.good_1 index 5a5e5d2c3c..2ae4ec4125 100644 --- a/test/etags/ETAGS.good_1 +++ b/test/etags/ETAGS.good_1 @@ -2336,7 +2336,7 @@ function MoveLayerBottom 223,5079 function MoveLayerBefore 236,5457 function MoveLayerAfter 258,6090 -lua-src/test.lua,291 +lua-src/test.lua,442 function Rectangle.getPos 2,15 function Rectangle.getPos getPos2,15 function Circle.getPos 6,61 @@ -2345,6 +2345,10 @@ function Cube.data.getFoo 10,102 function Cube.data.getFoo getFoo10,102 function Square.something:Bar 14,148 function Square.something:Bar Bar14,148 + function test.me_22a(22,241 + function test.me_22a(me_22a22,241 + local function test.me22b 25,297 + local function test.me22b me22b25,297 make-src/Makefile,1133 LATEST=1,0 @@ -2973,6 +2977,31 @@ class Configure(760,24879 def save(797,26022 def nosave(807,26310 +ruby-src/test.rb,594 +module ModuleExample1,0 + class ClassExample2,21 + def class_method3,44 + def ClassExample.singleton_class_method6,116 + def class_method_exclamation!9,221 + def class_method_question?12,319 + def class_method_equals=class_method_equals=15,411 + def `(18,499 + def +(21,589 + def [](24,637 + def []=([]=27,687 + def <<(30,749 + def ==(==33,799 + def <=(<=36,869 + def <=>(<=>39,940 + def ===(===42,987 + def module_method46,1048 + def ModuleExample.singleton_module_method49,1110 + +ruby-src/test1.ruby,37 +class A1,0 + def a(2,8 + def b(5,38 + tex-src/testenv.tex,52 \newcommand{\nm}\nm4,77 \section{blah}blah8,139 diff --git a/test/etags/ETAGS.good_2 b/test/etags/ETAGS.good_2 index 3e5285af1c..3ec5b21d38 100644 --- a/test/etags/ETAGS.good_2 +++ b/test/etags/ETAGS.good_2 @@ -2905,7 +2905,7 @@ function MoveLayerBottom 223,5079 function MoveLayerBefore 236,5457 function MoveLayerAfter 258,6090 -lua-src/test.lua,291 +lua-src/test.lua,442 function Rectangle.getPos 2,15 function Rectangle.getPos getPos2,15 function Circle.getPos 6,61 @@ -2914,6 +2914,10 @@ function Cube.data.getFoo 10,102 function Cube.data.getFoo getFoo10,102 function Square.something:Bar 14,148 function Square.something:Bar Bar14,148 + function test.me_22a(22,241 + function test.me_22a(me_22a22,241 + local function test.me22b 25,297 + local function test.me22b me22b25,297 make-src/Makefile,1156 LATEST=1,0 @@ -3544,6 +3548,31 @@ class Configure(760,24879 def save(797,26022 def nosave(807,26310 +ruby-src/test.rb,594 +module ModuleExample1,0 + class ClassExample2,21 + def class_method3,44 + def ClassExample.singleton_class_method6,116 + def class_method_exclamation!9,221 + def class_method_question?12,319 + def class_method_equals=class_method_equals=15,411 + def `(18,499 + def +(21,589 + def [](24,637 + def []=([]=27,687 + def <<(30,749 + def ==(==33,799 + def <=(<=36,869 + def <=>(<=>39,940 + def ===(===42,987 + def module_method46,1048 + def ModuleExample.singleton_module_method49,1110 + +ruby-src/test1.ruby,37 +class A1,0 + def a(2,8 + def b(5,38 + tex-src/testenv.tex,52 \newcommand{\nm}\nm4,77 \section{blah}blah8,139 diff --git a/test/etags/ETAGS.good_3 b/test/etags/ETAGS.good_3 index 2f91126e1d..43b84eed5d 100644 --- a/test/etags/ETAGS.good_3 +++ b/test/etags/ETAGS.good_3 @@ -2653,7 +2653,7 @@ function MoveLayerBottom 223,5079 function MoveLayerBefore 236,5457 function MoveLayerAfter 258,6090 -lua-src/test.lua,291 +lua-src/test.lua,442 function Rectangle.getPos 2,15 function Rectangle.getPos getPos2,15 function Circle.getPos 6,61 @@ -2662,6 +2662,10 @@ function Cube.data.getFoo 10,102 function Cube.data.getFoo getFoo10,102 function Square.something:Bar 14,148 function Square.something:Bar Bar14,148 + function test.me_22a(22,241 + function test.me_22a(me_22a22,241 + local function test.me22b 25,297 + local function test.me22b me22b25,297 make-src/Makefile,1133 LATEST=1,0 @@ -3317,6 +3321,31 @@ class Configure(760,24879 def save(797,26022 def nosave(807,26310 +ruby-src/test.rb,594 +module ModuleExample1,0 + class ClassExample2,21 + def class_method3,44 + def ClassExample.singleton_class_method6,116 + def class_method_exclamation!9,221 + def class_method_question?12,319 + def class_method_equals=class_method_equals=15,411 + def `(18,499 + def +(21,589 + def [](24,637 + def []=([]=27,687 + def <<(30,749 + def ==(==33,799 + def <=(<=36,869 + def <=>(<=>39,940 + def ===(===42,987 + def module_method46,1048 + def ModuleExample.singleton_module_method49,1110 + +ruby-src/test1.ruby,37 +class A1,0 + def a(2,8 + def b(5,38 + tex-src/testenv.tex,52 \newcommand{\nm}\nm4,77 \section{blah}blah8,139 diff --git a/test/etags/ETAGS.good_4 b/test/etags/ETAGS.good_4 index 71fc2cbda8..434fe13cbd 100644 --- a/test/etags/ETAGS.good_4 +++ b/test/etags/ETAGS.good_4 @@ -2500,7 +2500,7 @@ function MoveLayerBottom 223,5079 function MoveLayerBefore 236,5457 function MoveLayerAfter 258,6090 -lua-src/test.lua,291 +lua-src/test.lua,442 function Rectangle.getPos 2,15 function Rectangle.getPos getPos2,15 function Circle.getPos 6,61 @@ -2509,6 +2509,10 @@ function Cube.data.getFoo 10,102 function Cube.data.getFoo getFoo10,102 function Square.something:Bar 14,148 function Square.something:Bar Bar14,148 + function test.me_22a(22,241 + function test.me_22a(me_22a22,241 + local function test.me22b 25,297 + local function test.me22b me22b25,297 make-src/Makefile,1133 LATEST=1,0 @@ -3137,6 +3141,31 @@ class Configure(760,24879 def save(797,26022 def nosave(807,26310 +ruby-src/test.rb,594 +module ModuleExample1,0 + class ClassExample2,21 + def class_method3,44 + def ClassExample.singleton_class_method6,116 + def class_method_exclamation!9,221 + def class_method_question?12,319 + def class_method_equals=class_method_equals=15,411 + def `(18,499 + def +(21,589 + def [](24,637 + def []=([]=27,687 + def <<(30,749 + def ==(==33,799 + def <=(<=36,869 + def <=>(<=>39,940 + def ===(===42,987 + def module_method46,1048 + def ModuleExample.singleton_module_method49,1110 + +ruby-src/test1.ruby,37 +class A1,0 + def a(2,8 + def b(5,38 + tex-src/testenv.tex,52 \newcommand{\nm}\nm4,77 \section{blah}blah8,139 diff --git a/test/etags/ETAGS.good_5 b/test/etags/ETAGS.good_5 index ca55b3b0ad..425e2526f3 100644 --- a/test/etags/ETAGS.good_5 +++ b/test/etags/ETAGS.good_5 @@ -3386,7 +3386,7 @@ function MoveLayerBottom 223,5079 function MoveLayerBefore 236,5457 function MoveLayerAfter 258,6090 -lua-src/test.lua,291 +lua-src/test.lua,442 function Rectangle.getPos 2,15 function Rectangle.getPos getPos2,15 function Circle.getPos 6,61 @@ -3395,6 +3395,10 @@ function Cube.data.getFoo 10,102 function Cube.data.getFoo getFoo10,102 function Square.something:Bar 14,148 function Square.something:Bar Bar14,148 + function test.me_22a(22,241 + function test.me_22a(me_22a22,241 + local function test.me22b 25,297 + local function test.me22b me22b25,297 make-src/Makefile,1156 LATEST=1,0 @@ -4052,6 +4056,31 @@ class Configure(760,24879 def save(797,26022 def nosave(807,26310 +ruby-src/test.rb,594 +module ModuleExample1,0 + class ClassExample2,21 + def class_method3,44 + def ClassExample.singleton_class_method6,116 + def class_method_exclamation!9,221 + def class_method_question?12,319 + def class_method_equals=class_method_equals=15,411 + def `(18,499 + def +(21,589 + def [](24,637 + def []=([]=27,687 + def <<(30,749 + def ==(==33,799 + def <=(<=36,869 + def <=>(<=>39,940 + def ===(===42,987 + def module_method46,1048 + def ModuleExample.singleton_module_method49,1110 + +ruby-src/test1.ruby,37 +class A1,0 + def a(2,8 + def b(5,38 + tex-src/testenv.tex,52 \newcommand{\nm}\nm4,77 \section{blah}blah8,139 diff --git a/test/etags/ETAGS.good_6 b/test/etags/ETAGS.good_6 index 1ec846334e..39522dbdb9 100644 --- a/test/etags/ETAGS.good_6 +++ b/test/etags/ETAGS.good_6 @@ -3386,7 +3386,7 @@ function MoveLayerBottom 223,5079 function MoveLayerBefore 236,5457 function MoveLayerAfter 258,6090 -lua-src/test.lua,291 +lua-src/test.lua,442 function Rectangle.getPos 2,15 function Rectangle.getPos getPos2,15 function Circle.getPos 6,61 @@ -3395,6 +3395,10 @@ function Cube.data.getFoo 10,102 function Cube.data.getFoo getFoo10,102 function Square.something:Bar 14,148 function Square.something:Bar Bar14,148 + function test.me_22a(22,241 + function test.me_22a(me_22a22,241 + local function test.me22b 25,297 + local function test.me22b me22b25,297 make-src/Makefile,1156 LATEST=1,0 @@ -4052,6 +4056,31 @@ class Configure(760,24879 def save(797,26022 def nosave(807,26310 +ruby-src/test.rb,594 +module ModuleExample1,0 + class ClassExample2,21 + def class_method3,44 + def ClassExample.singleton_class_method6,116 + def class_method_exclamation!9,221 + def class_method_question?12,319 + def class_method_equals=class_method_equals=15,411 + def `(18,499 + def +(21,589 + def [](24,637 + def []=([]=27,687 + def <<(30,749 + def ==(==33,799 + def <=(<=36,869 + def <=>(<=>39,940 + def ===(===42,987 + def module_method46,1048 + def ModuleExample.singleton_module_method49,1110 + +ruby-src/test1.ruby,37 +class A1,0 + def a(2,8 + def b(5,38 + tex-src/testenv.tex,52 \newcommand{\nm}\nm4,77 \section{blah}blah8,139 diff --git a/test/etags/Makefile b/test/etags/Makefile index 1c50f72597..00d5b9f52b 100644 --- a/test/etags/Makefile +++ b/test/etags/Makefile @@ -23,12 +23,13 @@ PHPSRC=$(addprefix ./php-src/,lce_functions.php ptest.php sendmail.php) PSSRC=$(addprefix ./ps-src/,rfc1245.ps) PROLSRC=$(addprefix ./prol-src/,ordsets.prolog natded.prolog) PYTSRC=$(addprefix ./pyt-src/,server.py) +RBSRC=$(addprefix ./ruby-src/,test.rb test1.ruby) TEXSRC=$(addprefix ./tex-src/,testenv.tex gzip.texi texinfo.tex nonewline.tex) YSRC=$(addprefix ./y-src/,parse.y parse.c atest.y cccp.c cccp.y) SRCS=${ADASRC} ${ASRC} ${CSRC} ${CPSRC} ${ELSRC} ${ERLSRC} ${FSRC}\ ${FORTHSRC} ${HTMLSRC} ${JAVASRC} ${LUASRC} ${MAKESRC} ${OBJCSRC}\ ${OBJCPPSRC} ${PASSRC} ${PHPSRC} ${PERLSRC} ${PSSRC} ${PROLSRC} ${PYTSRC}\ - ${TEXSRC} ${YSRC} + ${RBSRC} ${TEXSRC} ${YSRC} NONSRCS=./f-src/entry.strange ./erl-src/lists.erl ./cp-src/clheir.hpp.gz ETAGS_PROG=../../lib-src/etags diff --git a/test/etags/lua-src/test.lua b/test/etags/lua-src/test.lua index 3bfa49c4f5..405eb5f1de 100644 --- a/test/etags/lua-src/test.lua +++ b/test/etags/lua-src/test.lua @@ -13,3 +13,24 @@ end Square = {} function Square.something:Bar () end + +-- Comment line + -- Indented comment line + +test = {} + + function test.me_22a(one, two) + print"me_22a" + end + local function test.me22b (one) + print"me_22b" + end + + + test.i_123 = function (x) + print"i_123" +end + + +test.me_12a(1,2) +test.i_123(1) diff --git a/test/etags/ruby-src/test.rb b/test/etags/ruby-src/test.rb new file mode 100644 index 0000000000..9254c5bffa --- /dev/null +++ b/test/etags/ruby-src/test.rb @@ -0,0 +1,54 @@ +module ModuleExample + class ClassExample + def class_method + puts "in class_method" + end + def ClassExample.singleton_class_method + puts "in singleton_class_method" + end + def class_method_exclamation! + puts "in class_method_exclamation!" + end + def class_method_question? + puts "in class_method_question?" + end + def class_method_equals= + puts "in class_method_equals=" + end + def `(command) + return "just testing a backquote override" + end + def +(y) + @x + y + end + def [](y) + @ary[y] + end + def []=(y, val) + @ary[y] = val + end + def <<(y) + @x << y + end + def ==(y) + @ary.length == y.ary.length + end + def <=(y) + '@ary.length < y.ary.length' + end + def <=>(y) + nil + end + def ===(y) + self == y + end + end + def module_method + puts "in module_method" + end + def ModuleExample.singleton_module_method + puts "in singleton_module_method" + end +end + +ModuleExample::ClassExample.singleton_class_method diff --git a/test/etags/ruby-src/test1.ruby b/test/etags/ruby-src/test1.ruby new file mode 100644 index 0000000000..43b1a14b95 --- /dev/null +++ b/test/etags/ruby-src/test1.ruby @@ -0,0 +1,7 @@ +class A + def a() + super(" do ") + end + def b() + end +end |