diff options
| author | John Wiegley | 2016-01-18 22:59:51 -0800 |
|---|---|---|
| committer | John Wiegley | 2016-01-18 22:59:51 -0800 |
| commit | 1b76d9168336ede8976b980aeaed64ae2908501a (patch) | |
| tree | 749e3c082a8575eee1888ba9e61e1aeaa70d0dbc | |
| parent | bca49307c8ea3f96d6eede375a7f42091ae5d5af (diff) | |
| parent | 2e5a89fad151f8efa97aea3f400823a95bee6289 (diff) | |
| download | emacs-1b76d9168336ede8976b980aeaed64ae2908501a.tar.gz emacs-1b76d9168336ede8976b980aeaed64ae2908501a.zip | |
-
38 files changed, 705 insertions, 484 deletions
| @@ -311,6 +311,9 @@ typical 32-bit host, Emacs integers have 62 bits instead of 30. | |||
| 311 | 311 | ||
| 312 | Use --with-cairo to compile Emacs with Cairo drawing. | 312 | Use --with-cairo to compile Emacs with Cairo drawing. |
| 313 | 313 | ||
| 314 | Use --with-modules to build Emacs with support for loading dynamic | ||
| 315 | modules. | ||
| 316 | |||
| 314 | Use --enable-gcc-warnings to enable compile-time checks that warn | 317 | Use --enable-gcc-warnings to enable compile-time checks that warn |
| 315 | about possibly-questionable C code. This is intended for developers | 318 | about possibly-questionable C code. This is intended for developers |
| 316 | and is useful with GNU-compatible compilers. On a recent GNU system | 319 | and is useful with GNU-compatible compilers. On a recent GNU system |
diff --git a/configure.ac b/configure.ac index ddf0f5fcfa1..d3b518366ef 100644 --- a/configure.ac +++ b/configure.ac | |||
| @@ -3350,7 +3350,6 @@ if test "${HAVE_MODULES}" = yes; then | |||
| 3350 | fi | 3350 | fi |
| 3351 | AC_SUBST(MODULES_OBJ) | 3351 | AC_SUBST(MODULES_OBJ) |
| 3352 | AC_SUBST(LIBMODULES) | 3352 | AC_SUBST(LIBMODULES) |
| 3353 | AX_GCC_VAR_ATTRIBUTE(cleanup) | ||
| 3354 | AC_CHECK_FUNCS(dladdr) | 3353 | AC_CHECK_FUNCS(dladdr) |
| 3355 | 3354 | ||
| 3356 | ### Use -lpng if available, unless '--with-png=no'. | 3355 | ### Use -lpng if available, unless '--with-png=no'. |
diff --git a/doc/emacs/maintaining.texi b/doc/emacs/maintaining.texi index 8842b8ea2f5..989d8ff7485 100644 --- a/doc/emacs/maintaining.texi +++ b/doc/emacs/maintaining.texi | |||
| @@ -1686,19 +1686,38 @@ permitted provided the copyright notice and this notice are preserved. | |||
| 1686 | Of course, you should substitute the proper years and copyright holder. | 1686 | Of course, you should substitute the proper years and copyright holder. |
| 1687 | 1687 | ||
| 1688 | @node Xref | 1688 | @node Xref |
| 1689 | @section Find Identifier Definitions and References | 1689 | @section Find Identifier References |
| 1690 | @cindex xref | 1690 | @cindex xref |
| 1691 | 1691 | ||
| 1692 | An @dfn{identifier} is a syntactic elements of the program: a | 1692 | An @dfn{identifier} is a name of a syntactical subunit of the |
| 1693 | function, a subroutine, a method, a class, a data type, a macro, etc. | 1693 | program: a function, a subroutine, a method, a class, a data type, a |
| 1694 | In a programming language, each identifier is a symbol in the | 1694 | macro, etc. In a programming language, each identifier is a symbol in |
| 1695 | language's syntax. Many program development tools provide | 1695 | the language's syntax. Program development and maintenance requires |
| 1696 | capabilities to extract references to identifiers from source files, | 1696 | capabilities to quickly find where each identifier was defined and |
| 1697 | record them on specialized data bases, and then use those data bases | 1697 | referenced, to rename identifiers across the entire project, etc. |
| 1698 | to quickly find where each identifier was defined and referenced. | ||
| 1699 | 1698 | ||
| 1700 | Emacs provides a unified user interface to these tools, called | 1699 | These capabilities are also useful for finding references in major |
| 1701 | @samp{xref}. The tools supported by @samp{xref} include: | 1700 | modes other than those defined to support programming languages. For |
| 1701 | example, chapters, sections, appendices, etc.@: of a text or a @TeX{} | ||
| 1702 | document can be treated as subunits as well, and their names can be | ||
| 1703 | used as identifiers. In this chapter, we use the term ``identifiers'' | ||
| 1704 | to collectively refer to the names of any kind of subunits, in program | ||
| 1705 | source and in other kinds of text alike. | ||
| 1706 | |||
| 1707 | Emacs provides a unified interface to these capabilities, called | ||
| 1708 | @samp{xref}. | ||
| 1709 | |||
| 1710 | @cindex xref backend | ||
| 1711 | To do its job, @code{xref} needs to make use of information and to | ||
| 1712 | employ methods specific to the major mode. What files to search for | ||
| 1713 | identifiers, how to find references to identifiers, how to complete on | ||
| 1714 | identifiers---all this and more is mode-specific knowledge. | ||
| 1715 | @code{xref} delegates the mode-specific parts of its job to a | ||
| 1716 | @dfn{backend} provided by the mode; it also includes defaults for some | ||
| 1717 | of its commands, for those modes that don't provide their own. | ||
| 1718 | |||
| 1719 | A backend can implement its capabilities in a variety of ways. Here | ||
| 1720 | are a few examples: | ||
| 1702 | 1721 | ||
| 1703 | @enumerate a | 1722 | @enumerate a |
| 1704 | @item | 1723 | @item |
| @@ -1706,49 +1725,25 @@ Some major modes provide built-in means for looking up the language | |||
| 1706 | symbols. For example, Emacs Lisp symbols can be identified by | 1725 | symbols. For example, Emacs Lisp symbols can be identified by |
| 1707 | searching the package load history, maintained by the Emacs Lisp | 1726 | searching the package load history, maintained by the Emacs Lisp |
| 1708 | interpreter, and by consulting the built-in documentation strings; the | 1727 | interpreter, and by consulting the built-in documentation strings; the |
| 1709 | Emacs Lisp mode uses these facilities to find definitions of symbols. | 1728 | Emacs Lisp mode uses these facilities in its backend to allow finding |
| 1710 | 1729 | definitions of symbols. (One disadvantage of this kind of backend is | |
| 1711 | @item | 1730 | that it only knows about subunits that were loaded into the |
| 1712 | Etags, the command for tagging identifier definitions which is part of | 1731 | interpreter.) |
| 1713 | the Emacs distribution. @xref{Create Tags Table}. | ||
| 1714 | |||
| 1715 | @item | ||
| 1716 | @acronym{GNU} GLOBAL, the source code tagging system, which provides | ||
| 1717 | the @command{gtags} command and associated utilities. @xref{Command | ||
| 1718 | Line, gtags, , global, GNU GLOBAL source code tag system}. | ||
| 1719 | 1732 | ||
| 1720 | @item | 1733 | @item |
| 1721 | Cscope (@uref{http://cscope.sourceforge.net/}, a tool for browsing | 1734 | An external program can extract references by scanning the relevant |
| 1722 | source code. | 1735 | files, and build a database of these references. A backend can then |
| 1723 | 1736 | access this database whenever it needs to list or look up references. | |
| 1724 | @item | 1737 | The Emacs distribution includes @command{etags}, a command for tagging |
| 1725 | @acronym{GNU} IDUtils, a package for generating databases of | 1738 | identifier definitions in programs, which supports many programming |
| 1726 | identifier references and querying those databases. @xref{Top,,, | 1739 | languages and other major modes, such as HTML, by extracting |
| 1727 | idutils, ID database utilities}. | 1740 | references into @dfn{tags tables}. @xref{Create Tags Table}. Major |
| 1728 | 1741 | modes for languages supported by @command{etags} can use tags tables | |
| 1729 | @item | 1742 | as basis for their backend. (One disadvantage of this kind of backend |
| 1730 | Grep, the venerable program that searches files for lines matching | 1743 | is that tags tables need to be kept reasonably up to date, by |
| 1731 | patterns. @xref{Invoking,,, grep, GNU Grep Manual}. | 1744 | rebuilding them from time to time.) |
| 1732 | @end enumerate | 1745 | @end enumerate |
| 1733 | 1746 | ||
| 1734 | @noindent | ||
| 1735 | Additional tools could be supported as they become available, or as | ||
| 1736 | user extensions. Each such tool is used as a @dfn{backend} by | ||
| 1737 | commands described in this section. Each command detects which | ||
| 1738 | backends are available for the current major mode, and uses the most | ||
| 1739 | capable of the available backends, with Grep generally serving as the | ||
| 1740 | fall-back backend. | ||
| 1741 | |||
| 1742 | @cindex tag | ||
| 1743 | The commands described here are useful for finding references in major | ||
| 1744 | modes other than those defined to support programming languages. For | ||
| 1745 | example, chapters, sections, appendices, etc. of a text or a @TeX{} | ||
| 1746 | document can be treated as identifiers as well. In this chapter, we | ||
| 1747 | collectively refer to a reference that specifies the name of the file | ||
| 1748 | where the corresponding subunit is defined, and the position of the | ||
| 1749 | subunit's definition in that file, as a @dfn{tag}. We refer to the | ||
| 1750 | backends used by @code{xref} as @dfn{tagging backends}. | ||
| 1751 | |||
| 1752 | @menu | 1747 | @menu |
| 1753 | * Find Identifiers:: Commands to find where an identifier is defined | 1748 | * Find Identifiers:: Commands to find where an identifier is defined |
| 1754 | or referenced, to list identifiers, etc. | 1749 | or referenced, to list identifiers, etc. |
| @@ -1759,14 +1754,16 @@ backends used by @code{xref} as @dfn{tagging backends}. | |||
| 1759 | @node Find Identifiers | 1754 | @node Find Identifiers |
| 1760 | @subsection Find Identifiers | 1755 | @subsection Find Identifiers |
| 1761 | 1756 | ||
| 1762 | This subsection describes the commands that use the tagging backends | 1757 | This subsection describes the commands that find references to |
| 1763 | in order to find definitions of identifiers, references to | 1758 | identifiers and perform various queries about identifiers. Each such |
| 1764 | identifiers, and perform various queries about identifiers. With most | 1759 | reference could @emph{define} an identifier, e.g., provide the |
| 1765 | backends, these definitions and references were recorded as tags in | 1760 | implementation of a program subunit or the text of a document section; |
| 1766 | the database created and maintained by the backend. | 1761 | or it could @emph{use} the identifier, e.g., call a function or a |
| 1762 | method, assign a value to a variable, mention a chapter in a | ||
| 1763 | cross-reference, etc. | ||
| 1767 | 1764 | ||
| 1768 | @menu | 1765 | @menu |
| 1769 | * Looking Up Identifiers:: Commands to find the definition of a specific tag. | 1766 | * Looking Up Identifiers:: Commands to find the definition of an identifier. |
| 1770 | * Xref Commands:: Commands in the @file{*xref*} buffer. | 1767 | * Xref Commands:: Commands in the @file{*xref*} buffer. |
| 1771 | * Identifier Search:: Searching and replacing identifiers. | 1768 | * Identifier Search:: Searching and replacing identifiers. |
| 1772 | * List Identifiers:: Listing identifiers and completing on them. | 1769 | * List Identifiers:: Listing identifiers and completing on them. |
| @@ -1794,7 +1791,7 @@ Find definitions of identifier, but display it in another window | |||
| 1794 | Find definition of identifier, and display it in a new frame | 1791 | Find definition of identifier, and display it in a new frame |
| 1795 | (@code{xref-find-definitions-other-frame}). | 1792 | (@code{xref-find-definitions-other-frame}). |
| 1796 | @item M-, | 1793 | @item M-, |
| 1797 | Pop back to where you previously invoked @kbd{M-.} and friends | 1794 | Go back to where you previously invoked @kbd{M-.} and friends |
| 1798 | (@code{xref-pop-marker-stack}). | 1795 | (@code{xref-pop-marker-stack}). |
| 1799 | @end table | 1796 | @end table |
| 1800 | 1797 | ||
| @@ -1832,7 +1829,8 @@ former is @w{@kbd{C-x 4 .}} | |||
| 1832 | The command @kbd{C-M-.} (@code{xref-find-apropos}) finds the | 1829 | The command @kbd{C-M-.} (@code{xref-find-apropos}) finds the |
| 1833 | definitions of one or more identifiers that match a specified regular | 1830 | definitions of one or more identifiers that match a specified regular |
| 1834 | expression. It is just like @kbd{M-.} except that it does regexp | 1831 | expression. It is just like @kbd{M-.} except that it does regexp |
| 1835 | matching of identifiers instead of symbol name matching. | 1832 | matching of identifiers instead of matching symbol names as fixed |
| 1833 | strings. | ||
| 1836 | 1834 | ||
| 1837 | When any of the above commands finds more than one definition, it | 1835 | When any of the above commands finds more than one definition, it |
| 1838 | presents the @file{*xref*} buffer showing the definition candidates. | 1836 | presents the @file{*xref*} buffer showing the definition candidates. |
| @@ -1896,13 +1894,9 @@ without displaying the references. | |||
| 1896 | @cindex search and replace in multiple files | 1894 | @cindex search and replace in multiple files |
| 1897 | @cindex multiple-file search and replace | 1895 | @cindex multiple-file search and replace |
| 1898 | 1896 | ||
| 1899 | The commands in this section visit and search all the files listed | 1897 | The commands in this section perform various search and replace |
| 1900 | in the @code{xref} backend's database, one by one. For these | 1898 | operations either on identifiers themselves or on files that reference |
| 1901 | commands, the database serves only to specify a sequence of files to | 1899 | them. |
| 1902 | search. These commands scan all the databases starting with the first | ||
| 1903 | one (if any) that describes the current file, proceed from there to | ||
| 1904 | the end of the list, and then scan from the beginning of the list | ||
| 1905 | until they have covered all the databases in the list. | ||
| 1906 | 1900 | ||
| 1907 | @table @kbd | 1901 | @table @kbd |
| 1908 | @item M-? | 1902 | @item M-? |
| @@ -1931,7 +1925,7 @@ referenced. The XREF mode commands are available in this buffer, see | |||
| 1931 | 1925 | ||
| 1932 | @findex xref-query-replace | 1926 | @findex xref-query-replace |
| 1933 | @kbd{M-x xref-query-replace} reads a regexp to match identifier | 1927 | @kbd{M-x xref-query-replace} reads a regexp to match identifier |
| 1934 | names and a string to replace with, just like ordinary @kbd{M-x | 1928 | names and a replacement string, just like ordinary @kbd{M-x |
| 1935 | query-replace-regexp}. It then performs the specified replacement in | 1929 | query-replace-regexp}. It then performs the specified replacement in |
| 1936 | the names of the matching identifiers in all the places in all the | 1930 | the names of the matching identifiers in all the places in all the |
| 1937 | files where these identifiers are referenced. This is useful when you | 1931 | files where these identifiers are referenced. This is useful when you |
| @@ -1943,15 +1937,14 @@ be invoked in the @file{*xref*} buffer generated by @code{M-?}. | |||
| 1943 | searches for matches in all the files in the selected tags table, one | 1937 | searches for matches in all the files in the selected tags table, one |
| 1944 | file at a time. It displays the name of the file being searched so | 1938 | file at a time. It displays the name of the file being searched so |
| 1945 | you can follow its progress. As soon as it finds an occurrence, | 1939 | you can follow its progress. As soon as it finds an occurrence, |
| 1946 | @code{tags-search} returns. This command works only with the etags | 1940 | @code{tags-search} returns. This command requires tags tables to be |
| 1947 | backend, and requires tags tables to be available (@pxref{Tags | 1941 | available (@pxref{Tags Tables}). |
| 1948 | Tables}). | ||
| 1949 | 1942 | ||
| 1950 | @findex tags-loop-continue | 1943 | @findex tags-loop-continue |
| 1951 | Having found one match, you probably want to find all the rest. | 1944 | Having found one match with @code{tags-search}, you probably want to |
| 1952 | Type @kbd{M-x tags-loop-continue}) to resume the @code{tags-search}, | 1945 | find all the rest. Type @kbd{M-x tags-loop-continue} to resume the |
| 1953 | finding one more match. This searches the rest of the current buffer, | 1946 | @code{tags-search}, finding one more match. This searches the rest of |
| 1954 | followed by the remaining files of the tags table. | 1947 | the current buffer, followed by the remaining files of the tags table. |
| 1955 | 1948 | ||
| 1956 | @findex tags-query-replace | 1949 | @findex tags-query-replace |
| 1957 | @kbd{M-x tags-query-replace} performs a single | 1950 | @kbd{M-x tags-query-replace} performs a single |
| @@ -1960,7 +1953,6 @@ reads a regexp to search for and a string to replace with, just like | |||
| 1960 | ordinary @kbd{M-x query-replace-regexp}. It searches much like @kbd{M-x | 1953 | ordinary @kbd{M-x query-replace-regexp}. It searches much like @kbd{M-x |
| 1961 | tags-search}, but repeatedly, processing matches according to your | 1954 | tags-search}, but repeatedly, processing matches according to your |
| 1962 | input. @xref{Query Replace}, for more information on query replace. | 1955 | input. @xref{Query Replace}, for more information on query replace. |
| 1963 | This command works only with the etags backend. | ||
| 1964 | 1956 | ||
| 1965 | @vindex tags-case-fold-search | 1957 | @vindex tags-case-fold-search |
| 1966 | @cindex case-sensitivity and tags search | 1958 | @cindex case-sensitivity and tags search |
| @@ -1976,19 +1968,21 @@ has no special query replace meaning. You can resume the query | |||
| 1976 | replace subsequently by typing @kbd{M-x tags-loop-continue}; this | 1968 | replace subsequently by typing @kbd{M-x tags-loop-continue}; this |
| 1977 | command resumes the last tags search or replace command that you did. | 1969 | command resumes the last tags search or replace command that you did. |
| 1978 | For instance, to skip the rest of the current file, you can type | 1970 | For instance, to skip the rest of the current file, you can type |
| 1979 | @kbd{M-> M-x tags-loop-continue}. | 1971 | @w{@kbd{M-> M-x tags-loop-continue}}. |
| 1980 | 1972 | ||
| 1981 | The commands in this section carry out much broader searches than | 1973 | Note that the commands described above carry out much broader |
| 1982 | the @code{xref-find-definitions} family. The | 1974 | searches than the @code{xref-find-definitions} family. The |
| 1983 | @code{xref-find-definitions} commands search only for definitions of | 1975 | @code{xref-find-definitions} commands search only for definitions of |
| 1984 | identifiers that match your string or regexp. The commands | 1976 | identifiers that match your string or regexp. The commands |
| 1985 | @code{tags-search} and @code{tags-query-replace} find every occurrence | 1977 | @code{xref-find-references}, @code{tags-search}, and |
| 1986 | of the regexp, as ordinary search commands and replace commands do in | 1978 | @code{tags-query-replace} find every occurrence of the identifier or |
| 1987 | the current buffer. | 1979 | regexp, as ordinary search commands and replace commands do in the |
| 1980 | current buffer. | ||
| 1988 | 1981 | ||
| 1989 | As an alternative to @code{tags-search}, you can run @command{grep} | 1982 | As an alternative to @code{xref-find-references} and |
| 1990 | as a subprocess and have Emacs show you the matching lines one by one. | 1983 | @code{tags-search}, you can run @command{grep} as a subprocess and |
| 1991 | @xref{Grep Searching}. | 1984 | have Emacs show you the matching lines one by one. @xref{Grep |
| 1985 | Searching}. | ||
| 1992 | 1986 | ||
| 1993 | @node List Identifiers | 1987 | @node List Identifiers |
| 1994 | @subsubsection Identifier Inquiries | 1988 | @subsubsection Identifier Inquiries |
| @@ -1996,20 +1990,23 @@ as a subprocess and have Emacs show you the matching lines one by one. | |||
| 1996 | @table @kbd | 1990 | @table @kbd |
| 1997 | @item C-M-i | 1991 | @item C-M-i |
| 1998 | @itemx M-@key{TAB} | 1992 | @itemx M-@key{TAB} |
| 1999 | Perform completion on the text around point, using the @code{xref} | 1993 | Perform completion on the text around point, using the selected tags |
| 2000 | backend if one is available (@code{completion-at-point}). | 1994 | table if one is loaded (@code{completion-at-point}). |
| 2001 | @item M-x list-tags @key{RET} @var{file} @key{RET} | ||
| 2002 | Display a list of the tags defined in the program file @var{file}. | ||
| 2003 | @item M-x xref-find-apropos @key{RET} @var{regexp} @key{RET} | 1995 | @item M-x xref-find-apropos @key{RET} @var{regexp} @key{RET} |
| 2004 | Display a list of all known identifiers matching @var{regexp}. | 1996 | Display a list of all known identifiers matching @var{regexp}. |
| 1997 | @item M-x list-tags @key{RET} @var{file} @key{RET} | ||
| 1998 | Display a list of the identifiers defined in the program file | ||
| 1999 | @var{file}. | ||
| 2000 | @item M-x next-file | ||
| 2001 | Visit files recorded in the selected tags table. | ||
| 2005 | @end table | 2002 | @end table |
| 2006 | 2003 | ||
| 2007 | @cindex completion (symbol names) | 2004 | @cindex completion (symbol names) |
| 2008 | In most programming language modes, you can type @kbd{C-M-i} or | 2005 | In most programming language modes, you can type @kbd{C-M-i} or |
| 2009 | @kbd{M-@key{TAB}} (@code{completion-at-point}) to complete the symbol | 2006 | @kbd{M-@key{TAB}} (@code{completion-at-point}) to complete the symbol |
| 2010 | at point. If there is an @code{xref} backend available, this command | 2007 | at point. If there is a tags table loaded, this command can use it to |
| 2011 | can use it to generate completion candidates more intelligently. | 2008 | generate completion candidates more intelligently. @xref{Symbol |
| 2012 | @xref{Symbol Completion}. | 2009 | Completion}. |
| 2013 | 2010 | ||
| 2014 | @findex list-tags | 2011 | @findex list-tags |
| 2015 | @kbd{M-x list-tags} reads the name of one of the files covered by | 2012 | @kbd{M-x list-tags} reads the name of one of the files covered by |
| @@ -2044,12 +2041,15 @@ for details. | |||
| 2044 | The first time it is called, it visits the first file covered by the | 2041 | The first time it is called, it visits the first file covered by the |
| 2045 | table. Each subsequent call visits the next covered file, unless a | 2042 | table. Each subsequent call visits the next covered file, unless a |
| 2046 | prefix argument is supplied, in which case it returns to the first | 2043 | prefix argument is supplied, in which case it returns to the first |
| 2047 | file. This command works only with the etags backend. | 2044 | file. This command requires a tags table to be selected. |
| 2048 | 2045 | ||
| 2049 | @node Tags Tables | 2046 | @node Tags Tables |
| 2050 | @subsection Tags Tables | 2047 | @subsection Tags Tables |
| 2051 | @cindex tags and tag tables | 2048 | @cindex tags and tag tables |
| 2052 | 2049 | ||
| 2050 | @cindex tag | ||
| 2051 | A @dfn{tag} is a synonym for identifier reference. @xref{Xref}. | ||
| 2052 | |||
| 2053 | A @dfn{tags table} records the tags extracted by scanning the source | 2053 | A @dfn{tags table} records the tags extracted by scanning the source |
| 2054 | code of a certain program or a certain document. Tags extracted from | 2054 | code of a certain program or a certain document. Tags extracted from |
| 2055 | generated files reference the original files, rather than the | 2055 | generated files reference the original files, rather than the |
diff --git a/doc/emacs/programs.texi b/doc/emacs/programs.texi index e4bd85c0ddd..780e00ca681 100644 --- a/doc/emacs/programs.texi +++ b/doc/emacs/programs.texi | |||
| @@ -1358,7 +1358,7 @@ the @kbd{M-@key{TAB}} key is usually reserved by the window manager | |||
| 1358 | for switching graphical windows, so you should type @kbd{C-M-i} or | 1358 | for switching graphical windows, so you should type @kbd{C-M-i} or |
| 1359 | @kbd{@key{ESC} @key{TAB}} instead. | 1359 | @kbd{@key{ESC} @key{TAB}} instead. |
| 1360 | 1360 | ||
| 1361 | @cindex xref-based completion | 1361 | @cindex tags-based completion |
| 1362 | @findex completion-at-point | 1362 | @findex completion-at-point |
| 1363 | @cindex Lisp symbol completion | 1363 | @cindex Lisp symbol completion |
| 1364 | @cindex completion (Lisp symbols) | 1364 | @cindex completion (Lisp symbols) |
| @@ -1368,7 +1368,7 @@ which generates its completion list in a flexible way. If Semantic | |||
| 1368 | mode is enabled, it tries to use the Semantic parser data for | 1368 | mode is enabled, it tries to use the Semantic parser data for |
| 1369 | completion (@pxref{Semantic}). If Semantic mode is not enabled or | 1369 | completion (@pxref{Semantic}). If Semantic mode is not enabled or |
| 1370 | fails at performing completion, it tries to complete using the | 1370 | fails at performing completion, it tries to complete using the |
| 1371 | available @code{xref} backend (@pxref{Xref}). If in Emacs Lisp mode, it | 1371 | selected tags table (@pxref{Tags Tables}). If in Emacs Lisp mode, it |
| 1372 | performs completion using the function, variable, or property names | 1372 | performs completion using the function, variable, or property names |
| 1373 | defined in the current Emacs session. | 1373 | defined in the current Emacs session. |
| 1374 | 1374 | ||
diff --git a/doc/emacs/search.texi b/doc/emacs/search.texi index bef74e3b2c5..e854646d056 100644 --- a/doc/emacs/search.texi +++ b/doc/emacs/search.texi | |||
| @@ -12,10 +12,10 @@ a string. Emacs also has commands to replace occurrences of a string | |||
| 12 | with a different string. There are also commands that do the same | 12 | with a different string. There are also commands that do the same |
| 13 | thing, but search for patterns instead of fixed strings. | 13 | thing, but search for patterns instead of fixed strings. |
| 14 | 14 | ||
| 15 | You can also search multiple files under the control of an | 15 | You can also search multiple files under the control of @code{xref} |
| 16 | @code{xref} backend (@pxref{Identifier Search}) or through the Dired | 16 | (@pxref{Identifier Search}) or through the Dired @kbd{A} command |
| 17 | @kbd{A} command (@pxref{Operating on Files}), or ask the @code{grep} | 17 | (@pxref{Operating on Files}), or ask the @code{grep} program to do it |
| 18 | program to do it (@pxref{Grep Searching}). | 18 | (@pxref{Grep Searching}). |
| 19 | 19 | ||
| 20 | @menu | 20 | @menu |
| 21 | * Incremental Search:: Search happens as you type the string. | 21 | * Incremental Search:: Search happens as you type the string. |
diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi index dee43cefb15..9c1df895161 100644 --- a/doc/lispref/commands.texi +++ b/doc/lispref/commands.texi | |||
| @@ -691,6 +691,14 @@ default is the return value of @code{this-command-keys-vector}. | |||
| 691 | @xref{Definition of this-command-keys-vector}. | 691 | @xref{Definition of this-command-keys-vector}. |
| 692 | @end defun | 692 | @end defun |
| 693 | 693 | ||
| 694 | @defun funcall-interactively function &rest arguments | ||
| 695 | This function works like @code{funcall} (@pxref{Calling Functions}), | ||
| 696 | but it makes the call look like an interactive invocation: a call to | ||
| 697 | @code{called-interactively-p} inside @var{function} will return | ||
| 698 | @code{t}. If @var{function} is not a command, it is called without | ||
| 699 | signaling an error. | ||
| 700 | @end defun | ||
| 701 | |||
| 694 | @defun command-execute command &optional record-flag keys special | 702 | @defun command-execute command &optional record-flag keys special |
| 695 | @cindex keyboard macro execution | 703 | @cindex keyboard macro execution |
| 696 | This function executes @var{command}. The argument @var{command} must | 704 | This function executes @var{command}. The argument @var{command} must |
diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi index 1c6674cdda9..614b7db0cac 100644 --- a/doc/lispref/frames.texi +++ b/doc/lispref/frames.texi | |||
| @@ -1188,8 +1188,8 @@ named, this parameter will be @code{nil}. | |||
| 1188 | @cindex window position on display | 1188 | @cindex window position on display |
| 1189 | @cindex frame position | 1189 | @cindex frame position |
| 1190 | 1190 | ||
| 1191 | Position parameters' values are normally measured in pixels, but on | 1191 | Position parameters' values are measured in pixels. (Note that none |
| 1192 | text terminals they count characters or lines instead. | 1192 | of these parameters exist on TTY frames.) |
| 1193 | 1193 | ||
| 1194 | @table @code | 1194 | @table @code |
| 1195 | @vindex left, a frame parameter | 1195 | @vindex left, a frame parameter |
| @@ -2637,18 +2637,19 @@ defined in the file @file{lisp/term/x-win.el}. Use @kbd{M-x apropos | |||
| 2637 | @cindex primary selection | 2637 | @cindex primary selection |
| 2638 | @cindex secondary selection | 2638 | @cindex secondary selection |
| 2639 | 2639 | ||
| 2640 | In the X window system, data can be transferred between different | 2640 | In window systems, such as X, data can be transferred between |
| 2641 | applications by means of @dfn{selections}. X defines an arbitrary | 2641 | different applications by means of @dfn{selections}. X defines an |
| 2642 | number of @dfn{selection types}, each of which can store its own data; | 2642 | arbitrary number of @dfn{selection types}, each of which can store its |
| 2643 | however, only three are commonly used: the @dfn{clipboard}, | 2643 | own data; however, only three are commonly used: the @dfn{clipboard}, |
| 2644 | @dfn{primary selection}, and @dfn{secondary selection}. @xref{Cut and | 2644 | @dfn{primary selection}, and @dfn{secondary selection}. Other window |
| 2645 | Paste,, Cut and Paste, emacs, The GNU Emacs Manual}, for Emacs | 2645 | systems support only the clipboard. @xref{Cut and Paste,, Cut and |
| 2646 | commands that make use of these selections. This section documents | 2646 | Paste, emacs, The GNU Emacs Manual}, for Emacs commands that make use |
| 2647 | the low-level functions for reading and setting X selections. | 2647 | of these selections. This section documents the low-level functions |
| 2648 | for reading and setting window-system selections. | ||
| 2648 | 2649 | ||
| 2649 | @deffn Command x-set-selection type data | 2650 | @deffn Command gui-set-selection type data |
| 2650 | This function sets an X selection. It takes two arguments: a | 2651 | This function sets a window-system selection. It takes two arguments: |
| 2651 | selection type @var{type}, and the value to assign to it, @var{data}. | 2652 | a selection type @var{type}, and the value to assign to it, @var{data}. |
| 2652 | 2653 | ||
| 2653 | @var{type} should be a symbol; it is usually one of @code{PRIMARY}, | 2654 | @var{type} should be a symbol; it is usually one of @code{PRIMARY}, |
| 2654 | @code{SECONDARY} or @code{CLIPBOARD}. These are symbols with | 2655 | @code{SECONDARY} or @code{CLIPBOARD}. These are symbols with |
| @@ -2665,14 +2666,14 @@ stands for text in the overlay or between the markers. The argument | |||
| 2665 | This function returns @var{data}. | 2666 | This function returns @var{data}. |
| 2666 | @end deffn | 2667 | @end deffn |
| 2667 | 2668 | ||
| 2668 | @defun x-get-selection &optional type data-type | 2669 | @defun gui-get-selection &optional type data-type |
| 2669 | This function accesses selections set up by Emacs or by other X | 2670 | This function accesses selections set up by Emacs or by other |
| 2670 | clients. It takes two optional arguments, @var{type} and | 2671 | programs. It takes two optional arguments, @var{type} and |
| 2671 | @var{data-type}. The default for @var{type}, the selection type, is | 2672 | @var{data-type}. The default for @var{type}, the selection type, is |
| 2672 | @code{PRIMARY}. | 2673 | @code{PRIMARY}. |
| 2673 | 2674 | ||
| 2674 | The @var{data-type} argument specifies the form of data conversion to | 2675 | The @var{data-type} argument specifies the form of data conversion to |
| 2675 | use, to convert the raw data obtained from another X client into Lisp | 2676 | use, to convert the raw data obtained from another program into Lisp |
| 2676 | data. Meaningful values include @code{TEXT}, @code{STRING}, | 2677 | data. Meaningful values include @code{TEXT}, @code{STRING}, |
| 2677 | @code{UTF8_STRING}, @code{TARGETS}, @code{LENGTH}, @code{DELETE}, | 2678 | @code{UTF8_STRING}, @code{TARGETS}, @code{LENGTH}, @code{DELETE}, |
| 2678 | @code{FILE_NAME}, @code{CHARACTER_POSITION}, @code{NAME}, | 2679 | @code{FILE_NAME}, @code{CHARACTER_POSITION}, @code{NAME}, |
| @@ -2680,7 +2681,8 @@ data. Meaningful values include @code{TEXT}, @code{STRING}, | |||
| 2680 | @code{HOST_NAME}, @code{USER}, @code{CLASS}, @code{ATOM}, and | 2681 | @code{HOST_NAME}, @code{USER}, @code{CLASS}, @code{ATOM}, and |
| 2681 | @code{INTEGER}. (These are symbols with upper-case names in accord | 2682 | @code{INTEGER}. (These are symbols with upper-case names in accord |
| 2682 | with X conventions.) The default for @var{data-type} is | 2683 | with X conventions.) The default for @var{data-type} is |
| 2683 | @code{STRING}. | 2684 | @code{STRING}. Window systems other than X usually support only a |
| 2685 | small subset of these types, in addition to @code{STRING}. | ||
| 2684 | @end defun | 2686 | @end defun |
| 2685 | 2687 | ||
| 2686 | @defopt selection-coding-system | 2688 | @defopt selection-coding-system |
| @@ -2692,10 +2694,15 @@ converts to the text representation that X11 normally uses. | |||
| 2692 | 2694 | ||
| 2693 | @cindex clipboard support (for MS-Windows) | 2695 | @cindex clipboard support (for MS-Windows) |
| 2694 | When Emacs runs on MS-Windows, it does not implement X selections in | 2696 | When Emacs runs on MS-Windows, it does not implement X selections in |
| 2695 | general, but it does support the clipboard. @code{x-get-selection} | 2697 | general, but it does support the clipboard. @code{gui-get-selection} |
| 2696 | and @code{x-set-selection} on MS-Windows support the text data type | 2698 | and @code{gui-set-selection} on MS-Windows support the text data type |
| 2697 | only; if the clipboard holds other types of data, Emacs treats the | 2699 | only; if the clipboard holds other types of data, Emacs treats the |
| 2698 | clipboard as empty. | 2700 | clipboard as empty. The supported data type is @code{STRING}. |
| 2701 | |||
| 2702 | For backward compatibility, there are obsolete aliases | ||
| 2703 | @code{x-get-selection} and @code{x-set-selection}, which were the | ||
| 2704 | names of @code{gui-get-selection} and @code{gui-set-selection} before | ||
| 2705 | Emacs 25.1. | ||
| 2699 | 2706 | ||
| 2700 | @node Drag and Drop | 2707 | @node Drag and Drop |
| 2701 | @section Drag and Drop | 2708 | @section Drag and Drop |
diff --git a/doc/lispref/functions.texi b/doc/lispref/functions.texi index e596badcdd2..1e8e7540395 100644 --- a/doc/lispref/functions.texi +++ b/doc/lispref/functions.texi | |||
| @@ -623,6 +623,96 @@ definition will have no effect on them. | |||
| 623 | and tells the Lisp compiler to perform inline expansion on it. | 623 | and tells the Lisp compiler to perform inline expansion on it. |
| 624 | @xref{Inline Functions}. | 624 | @xref{Inline Functions}. |
| 625 | 625 | ||
| 626 | Alternatively, you can define a function by providing the code which | ||
| 627 | will inline it as a compiler macro. The following macros make this | ||
| 628 | possible. | ||
| 629 | |||
| 630 | @c FIXME: Can define-inline use the interactive spec? | ||
| 631 | @defmac define-inline name args [doc] [declare] body@dots{} | ||
| 632 | Define a function @var{name} by providing code that does its inlining, | ||
| 633 | as a compiler macro. The function will accept the argument list | ||
| 634 | @var{args} and will have the specified @var{body}. | ||
| 635 | |||
| 636 | If present, @var{doc} should be the function's documentation string | ||
| 637 | (@pxref{Function Documentation}); @var{declare}, if present, should be | ||
| 638 | a @code{declare} form (@pxref{Declare Form}) specifying the function's | ||
| 639 | metadata. | ||
| 640 | @end defmac | ||
| 641 | |||
| 642 | Functions defined via @code{define-inline} have several advantages | ||
| 643 | with respect to macros defined by @code{defsubst} or @code{defmacro}: | ||
| 644 | |||
| 645 | @itemize @minus | ||
| 646 | @item | ||
| 647 | They can be passed to @code{mapcar} (@pxref{Mapping Functions}). | ||
| 648 | |||
| 649 | @item | ||
| 650 | They are more efficient. | ||
| 651 | |||
| 652 | @item | ||
| 653 | They can be used as @dfn{place forms} to store values | ||
| 654 | (@pxref{Generalized Variables}). | ||
| 655 | |||
| 656 | @item | ||
| 657 | They behave in a more predictable way than @code{cl-defsubst} | ||
| 658 | (@pxref{Argument Lists,,, cl, Common Lisp Extensions for GNU Emacs | ||
| 659 | Lisp}). | ||
| 660 | @end itemize | ||
| 661 | |||
| 662 | Like @code{defmacro}, a function inlined with @code{define-inline} | ||
| 663 | inherits the scoping rules, either dynamic or lexical, from the call | ||
| 664 | site. @xref{Variable Scoping}. | ||
| 665 | |||
| 666 | The following macros should be used in the body of a function defined | ||
| 667 | by @code{define-inline}. | ||
| 668 | |||
| 669 | @defmac inline-quote expression | ||
| 670 | Quote @var{expression} for @code{define-inline}. This is similar to | ||
| 671 | the backquote (@pxref{Backquote}), but quotes code and accepts only | ||
| 672 | @code{,}, not @code{,@@}. | ||
| 673 | @end defmac | ||
| 674 | |||
| 675 | @defmac inline-letevals (bindings@dots{}) body@dots{} | ||
| 676 | This is is similar to @code{let} (@pxref{Local Variables}): it sets up | ||
| 677 | local variables as specified by @var{bindings}, and then evaluates | ||
| 678 | @var{body} with those bindings in effect. Each element of | ||
| 679 | @var{bindings} should be either a symbol or a list of the form | ||
| 680 | @w{@code{(@var{var} @var{expr})}}; the result is to evaluate | ||
| 681 | @var{expr} and bind @var{var} to the result. The tail of | ||
| 682 | @var{bindings} can be either @code{nil} or a symbol which should hold | ||
| 683 | a list of arguments, in which case each argument is evaluated, and the | ||
| 684 | symbol is bound to the resulting list. | ||
| 685 | @end defmac | ||
| 686 | |||
| 687 | @defmac inline-const-p expression | ||
| 688 | Return non-@code{nil} if the value of @var{expression} is already | ||
| 689 | known. | ||
| 690 | @end defmac | ||
| 691 | |||
| 692 | @defmac inline-const-val expression | ||
| 693 | Return the value of @var{expression}. | ||
| 694 | @end defmac | ||
| 695 | |||
| 696 | @defmac inline-error format &rest args | ||
| 697 | Signal an error, formatting @var{args} according to @var{format}. | ||
| 698 | @end defmac | ||
| 699 | |||
| 700 | Here's an example of using @code{define-inline}: | ||
| 701 | |||
| 702 | @lisp | ||
| 703 | (define-inline myaccessor (obj) | ||
| 704 | (inline-letevals (obj) | ||
| 705 | (inline-quote (if (foo-p ,obj) (aref (cdr ,obj) 3) (aref ,obj 2))))) | ||
| 706 | @end lisp | ||
| 707 | |||
| 708 | @noindent | ||
| 709 | This is equivalent to | ||
| 710 | |||
| 711 | @lisp | ||
| 712 | (defsubst myaccessor (obj) | ||
| 713 | (if (foo-p obj) (aref (cdr obj) 3) (aref obj 2))) | ||
| 714 | @end lisp | ||
| 715 | |||
| 626 | @node Calling Functions | 716 | @node Calling Functions |
| 627 | @section Calling Functions | 717 | @section Calling Functions |
| 628 | @cindex function invocation | 718 | @cindex function invocation |
| @@ -664,6 +754,10 @@ they make sense only when given the unevaluated argument | |||
| 664 | expressions. @code{funcall} cannot provide these because, as we saw | 754 | expressions. @code{funcall} cannot provide these because, as we saw |
| 665 | above, it never knows them in the first place. | 755 | above, it never knows them in the first place. |
| 666 | 756 | ||
| 757 | If you need to use @code{funcall} to call a command and make it behave | ||
| 758 | as if invoked interactively, use @code{funcall-interactively} | ||
| 759 | (@pxref{Interactive Call}). | ||
| 760 | |||
| 667 | @example | 761 | @example |
| 668 | @group | 762 | @group |
| 669 | (setq f 'list) | 763 | (setq f 'list) |
| @@ -1706,19 +1800,24 @@ features of Emacs, you should not make a function inline, even if it's | |||
| 1706 | small, unless its speed is really crucial, and you've timed the code | 1800 | small, unless its speed is really crucial, and you've timed the code |
| 1707 | to verify that using @code{defun} actually has performance problems. | 1801 | to verify that using @code{defun} actually has performance problems. |
| 1708 | 1802 | ||
| 1709 | It's possible to define a macro to expand into the same code that an | ||
| 1710 | inline function would execute (@pxref{Macros}). But the macro would | ||
| 1711 | be limited to direct use in expressions---a macro cannot be called | ||
| 1712 | with @code{apply}, @code{mapcar} and so on. Also, it takes some work | ||
| 1713 | to convert an ordinary function into a macro. To convert it into an | ||
| 1714 | inline function is easy; just replace @code{defun} with | ||
| 1715 | @code{defsubst}. Since each argument of an inline function is | ||
| 1716 | evaluated exactly once, you needn't worry about how many times the | ||
| 1717 | body uses the arguments, as you do for macros. | ||
| 1718 | |||
| 1719 | After an inline function is defined, its inline expansion can be | 1803 | After an inline function is defined, its inline expansion can be |
| 1720 | performed later on in the same file, just like macros. | 1804 | performed later on in the same file, just like macros. |
| 1721 | 1805 | ||
| 1806 | It's possible to use @code{defsubst} to define a macro to expand | ||
| 1807 | into the same code that an inline function would execute | ||
| 1808 | (@pxref{Macros}). But the macro would be limited to direct use in | ||
| 1809 | expressions---a macro cannot be called with @code{apply}, | ||
| 1810 | @code{mapcar} and so on. Also, it takes some work to convert an | ||
| 1811 | ordinary function into a macro. To convert it into an inline function | ||
| 1812 | is easy; just replace @code{defun} with @code{defsubst}. Since each | ||
| 1813 | argument of an inline function is evaluated exactly once, you needn't | ||
| 1814 | worry about how many times the body uses the arguments, as you do for | ||
| 1815 | macros. | ||
| 1816 | |||
| 1817 | As an alternative to @code{defsubst}, you can use | ||
| 1818 | @code{define-inline} to define functions via their exhaustive compiler | ||
| 1819 | macro. @xref{Defining Functions, define-inline}. | ||
| 1820 | |||
| 1722 | @node Declare Form | 1821 | @node Declare Form |
| 1723 | @section The @code{declare} Form | 1822 | @section The @code{declare} Form |
| 1724 | @findex declare | 1823 | @findex declare |
diff --git a/doc/lispref/lists.texi b/doc/lispref/lists.texi index d961caf49f6..c18c408209a 100644 --- a/doc/lispref/lists.texi +++ b/doc/lispref/lists.texi | |||
| @@ -1556,6 +1556,14 @@ keys may not be symbols: | |||
| 1556 | @end smallexample | 1556 | @end smallexample |
| 1557 | @end defun | 1557 | @end defun |
| 1558 | 1558 | ||
| 1559 | @defun alist-get key value &optional default | ||
| 1560 | This function is like @code{assq}, but instead of returning the entire | ||
| 1561 | association for @var{key}, @code{(@var{key} . @var{value})}, it | ||
| 1562 | returns just the @var{value}. It returns @var{default} if @var{key} | ||
| 1563 | is not found in @var{alist}, defaulting to @code{nil} if @var{default} | ||
| 1564 | is omitted. | ||
| 1565 | @end defun | ||
| 1566 | |||
| 1559 | @defun rassq value alist | 1567 | @defun rassq value alist |
| 1560 | This function returns the first association with value @var{value} in | 1568 | This function returns the first association with value @var{value} in |
| 1561 | @var{alist}. It returns @code{nil} if no association in @var{alist} has | 1569 | @var{alist}. It returns @code{nil} if no association in @var{alist} has |
diff --git a/doc/lispref/loading.texi b/doc/lispref/loading.texi index 18e67f1abfe..06900a49477 100644 --- a/doc/lispref/loading.texi +++ b/doc/lispref/loading.texi | |||
| @@ -73,12 +73,15 @@ To find the file, @code{load} first looks for a file named | |||
| 73 | @var{filename} with the extension @samp{.elc} appended. If such a | 73 | @var{filename} with the extension @samp{.elc} appended. If such a |
| 74 | file exists, it is loaded. If there is no file by that name, then | 74 | file exists, it is loaded. If there is no file by that name, then |
| 75 | @code{load} looks for a file named @file{@var{filename}.el}. If that | 75 | @code{load} looks for a file named @file{@var{filename}.el}. If that |
| 76 | file exists, it is loaded. Finally, if neither of those names is | 76 | file exists, it is loaded. If Emacs was compiled with support for |
| 77 | found, @code{load} looks for a file named @var{filename} with nothing | 77 | dynamic modules (@pxref{Dynamic Modules}), @code{load} next looks for |
| 78 | appended, and loads it if it exists. (The @code{load} function is not | 78 | a file named @file{@var{filename}.@var{ext}}, where @var{ext} is a |
| 79 | clever about looking at @var{filename}. In the perverse case of a | 79 | system-dependent file-name extension of shared libraries. Finally, if |
| 80 | file named @file{foo.el.el}, evaluation of @code{(load "foo.el")} will | 80 | neither of those names is found, @code{load} looks for a file named |
| 81 | indeed find it.) | 81 | @var{filename} with nothing appended, and loads it if it exists. (The |
| 82 | @code{load} function is not clever about looking at @var{filename}. | ||
| 83 | In the perverse case of a file named @file{foo.el.el}, evaluation of | ||
| 84 | @code{(load "foo.el")} will indeed find it.) | ||
| 82 | 85 | ||
| 83 | If Auto Compression mode is enabled, as it is by default, then if | 86 | If Auto Compression mode is enabled, as it is by default, then if |
| 84 | @code{load} can not find a file, it searches for a compressed version | 87 | @code{load} can not find a file, it searches for a compressed version |
| @@ -100,7 +103,8 @@ being tried. | |||
| 100 | If the optional argument @var{must-suffix} is non-@code{nil}, then | 103 | If the optional argument @var{must-suffix} is non-@code{nil}, then |
| 101 | @code{load} insists that the file name used must end in either | 104 | @code{load} insists that the file name used must end in either |
| 102 | @samp{.el} or @samp{.elc} (possibly extended with a compression | 105 | @samp{.el} or @samp{.elc} (possibly extended with a compression |
| 103 | suffix), unless it contains an explicit directory name. | 106 | suffix) or the shared-library extension, unless it contains an |
| 107 | explicit directory name. | ||
| 104 | 108 | ||
| 105 | If the option @code{load-prefer-newer} is non-@code{nil}, then when | 109 | If the option @code{load-prefer-newer} is non-@code{nil}, then when |
| 106 | searching suffixes, @code{load} selects whichever version of a file | 110 | searching suffixes, @code{load} selects whichever version of a file |
diff --git a/doc/lispref/macros.texi b/doc/lispref/macros.texi index 7f3b670e328..3f9db8ce375 100644 --- a/doc/lispref/macros.texi +++ b/doc/lispref/macros.texi | |||
| @@ -160,6 +160,12 @@ expand the embedded calls to @code{inc}: | |||
| 160 | 160 | ||
| 161 | @end defun | 161 | @end defun |
| 162 | 162 | ||
| 163 | @defun macroexpand-1 form &optional environment | ||
| 164 | This function expands macros like @code{macroexpand}, but it only | ||
| 165 | performs one step of the expansion: if the result is another macro | ||
| 166 | call, @code{macroexpand-1} will not expand it. | ||
| 167 | @end defun | ||
| 168 | |||
| 163 | @node Compiling Macros | 169 | @node Compiling Macros |
| 164 | @section Macros and Byte Compilation | 170 | @section Macros and Byte Compilation |
| 165 | @cindex byte-compiling macros | 171 | @cindex byte-compiling macros |
diff --git a/doc/lispref/strings.texi b/doc/lispref/strings.texi index 95723ca4487..091db5e4ebb 100644 --- a/doc/lispref/strings.texi +++ b/doc/lispref/strings.texi | |||
| @@ -571,13 +571,19 @@ no characters is less than any other string. | |||
| 571 | @end example | 571 | @end example |
| 572 | 572 | ||
| 573 | Symbols are also allowed as arguments, in which case their print names | 573 | Symbols are also allowed as arguments, in which case their print names |
| 574 | are used. | 574 | are compared. |
| 575 | @end defun | 575 | @end defun |
| 576 | 576 | ||
| 577 | @defun string-lessp string1 string2 | 577 | @defun string-lessp string1 string2 |
| 578 | @code{string-lessp} is another name for @code{string<}. | 578 | @code{string-lessp} is another name for @code{string<}. |
| 579 | @end defun | 579 | @end defun |
| 580 | 580 | ||
| 581 | @defun string-greaterp string1 string2 | ||
| 582 | This function returns the result of comparing @var{string1} and | ||
| 583 | @var{string2} in the opposite order, i.e., it is equivalent to calling | ||
| 584 | @code{(string-lessp @var{string2} @var{string1})}. | ||
| 585 | @end defun | ||
| 586 | |||
| 581 | @cindex locale-dependent string comparison | 587 | @cindex locale-dependent string comparison |
| 582 | @defun string-collate-lessp string1 string2 &optional locale ignore-case | 588 | @defun string-collate-lessp string1 string2 &optional locale ignore-case |
| 583 | This function returns @code{t} if @var{string1} is less than | 589 | This function returns @code{t} if @var{string1} is less than |
diff --git a/doc/lispref/symbols.texi b/doc/lispref/symbols.texi index c99f993e5da..8c1ec3d85e2 100644 --- a/doc/lispref/symbols.texi +++ b/doc/lispref/symbols.texi | |||
| @@ -461,10 +461,23 @@ You could define @code{put} in terms of @code{setplist} and | |||
| 461 | @end example | 461 | @end example |
| 462 | @end defun | 462 | @end defun |
| 463 | 463 | ||
| 464 | @defun function-get symbol property | 464 | @defun function-get symbol property &optional autoload |
| 465 | This function is identical to @code{get}, except that if @var{symbol} | 465 | This function is identical to @code{get}, except that if @var{symbol} |
| 466 | is the name of a function alias, it looks in the property list of the | 466 | is the name of a function alias, it looks in the property list of the |
| 467 | symbol naming the actual function. @xref{Defining Functions}. | 467 | symbol naming the actual function. @xref{Defining Functions}. If the |
| 468 | optional argument @var{autoload} is non-@code{nil}, and @var{symbol} | ||
| 469 | is auto-loaded, this function will try to autoload it, since | ||
| 470 | autoloading might set @var{property} of @var{symbol}. If | ||
| 471 | @var{autoload} is the symbol @code{macro}, only try autoloading if | ||
| 472 | @var{symbol} is an auto-loaded macro. | ||
| 473 | @end defun | ||
| 474 | |||
| 475 | @defun function-put function property value | ||
| 476 | This function sets @var{property} of @var{function} to @var{value}. | ||
| 477 | @var{function} should be a symbol. This function is preferred to | ||
| 478 | calling @code{put} for setting properties of a function, because it | ||
| 479 | will allow us some day to implement remapping of old properties to new | ||
| 480 | ones. | ||
| 468 | @end defun | 481 | @end defun |
| 469 | 482 | ||
| 470 | @node Standard Properties | 483 | @node Standard Properties |
| @@ -95,6 +95,7 @@ by setting `autoload-timestamps' to nil. | |||
| 95 | This builds Emacs with Cairo drawing. As a side effect, it provides | 95 | This builds Emacs with Cairo drawing. As a side effect, it provides |
| 96 | support for built-in printing, when Emacs was built with GTK+. | 96 | support for built-in printing, when Emacs was built with GTK+. |
| 97 | 97 | ||
| 98 | +++ | ||
| 98 | ** New configure option --with-modules. | 99 | ** New configure option --with-modules. |
| 99 | This enables support for loading dynamic modules; see below. | 100 | This enables support for loading dynamic modules; see below. |
| 100 | 101 | ||
| @@ -178,6 +179,7 @@ and can contain escape sequences for command keys, quotes, and the like. | |||
| 178 | 179 | ||
| 179 | * Changes in Emacs 25.1 | 180 | * Changes in Emacs 25.1 |
| 180 | 181 | ||
| 182 | +++ | ||
| 181 | ** Emacs can now load shared/dynamic libraries (modules). | 183 | ** Emacs can now load shared/dynamic libraries (modules). |
| 182 | A dynamic Emacs module is a shared library that provides additional | 184 | A dynamic Emacs module is a shared library that provides additional |
| 183 | functionality for use in Emacs Lisp programs, just like a package | 185 | functionality for use in Emacs Lisp programs, just like a package |
| @@ -230,12 +232,6 @@ the `network-security-level' variable. | |||
| 230 | puny.el library, so that one can visit web sites like | 232 | puny.el library, so that one can visit web sites like |
| 231 | "http://méxico.icom.museum". | 233 | "http://méxico.icom.museum". |
| 232 | 234 | ||
| 233 | ** If Emacs isn't built with TLS support, an external TLS-capable | ||
| 234 | program is used instead. This program used to be run in --insecure | ||
| 235 | mode by default, but has now changed to be secure instead, and will | ||
| 236 | fail if you try to connect to non-verifiable hosts. This is | ||
| 237 | controlled by the `tls-program' variable. | ||
| 238 | |||
| 239 | +++ | 235 | +++ |
| 240 | ** C-h l now also lists the commands that were run. | 236 | ** C-h l now also lists the commands that were run. |
| 241 | 237 | ||
| @@ -378,6 +374,17 @@ current package keywords are recognized. Set the new option | |||
| 378 | It's meant for use together with `compile': | 374 | It's meant for use together with `compile': |
| 379 | emacs -batch --eval "(checkdoc-file \"subr.el\")" | 375 | emacs -batch --eval "(checkdoc-file \"subr.el\")" |
| 380 | 376 | ||
| 377 | ** Desktop | ||
| 378 | |||
| 379 | --- | ||
| 380 | *** The desktop format version has been upgraded from 206 to 208. | ||
| 381 | Although Emacs 25.1 can read a version 206 desktop, earlier Emacsen | ||
| 382 | cannot read a version 208 desktop. To upgrade your desktop file, you | ||
| 383 | must explicitly request the upgrade, by C-u M-x desktop-save. You are | ||
| 384 | recommended to do this as soon as you have firmly upgraded to Emacs | ||
| 385 | 25.1 (or later). Should you ever need to downgrade your desktop file | ||
| 386 | to version 206, you can do this with C-u C-u M-x desktop-save. | ||
| 387 | |||
| 381 | +++ | 388 | +++ |
| 382 | ** New function `bookmark-set-no-overwrite' bound to C-x r M. | 389 | ** New function `bookmark-set-no-overwrite' bound to C-x r M. |
| 383 | It raises an error if a bookmark of that name already exists, | 390 | It raises an error if a bookmark of that name already exists, |
| @@ -856,6 +863,13 @@ See the doc string of `sh-indent-after-continuation' for details. | |||
| 856 | --- | 863 | --- |
| 857 | *** Fatal TLS errors are now silent by default. | 864 | *** Fatal TLS errors are now silent by default. |
| 858 | 865 | ||
| 866 | --- | ||
| 867 | *** If Emacs isn't built with TLS support, an external TLS-capable | ||
| 868 | program is used instead. This program used to be run in --insecure | ||
| 869 | mode by default, but has now changed to be secure instead, and will | ||
| 870 | fail if you try to connect to non-verifiable hosts. This is | ||
| 871 | controlled by the `tls-program' variable. | ||
| 872 | |||
| 859 | ** URL | 873 | ** URL |
| 860 | 874 | ||
| 861 | +++ | 875 | +++ |
| @@ -1498,11 +1512,14 @@ details. | |||
| 1498 | It should be placed right where the docstring would be, and FORM is then | 1512 | It should be placed right where the docstring would be, and FORM is then |
| 1499 | evaluated (and should return a string) when the closure is built. | 1513 | evaluated (and should return a string) when the closure is built. |
| 1500 | 1514 | ||
| 1515 | +++ | ||
| 1501 | ** define-inline provides a new way to define inlinable functions. | 1516 | ** define-inline provides a new way to define inlinable functions. |
| 1502 | 1517 | ||
| 1503 | ** New function `macroexpand-1' to perform a single step of macroexpansion. | 1518 | +++ |
| 1519 | ** New function `macroexpand-1' to perform a single step of macro expansion. | ||
| 1504 | 1520 | ||
| 1505 | ** Some "x-*" were obsoleted: | 1521 | +++ |
| 1522 | ** Some "x-*" functions were obsoleted and/or renamed: | ||
| 1506 | *** x-select-text is renamed gui-select-text. | 1523 | *** x-select-text is renamed gui-select-text. |
| 1507 | *** x-selection-value is renamed gui-selection-value. | 1524 | *** x-selection-value is renamed gui-selection-value. |
| 1508 | *** x-get-selection is renamed gui-get-selection. | 1525 | *** x-get-selection is renamed gui-get-selection. |
| @@ -1510,6 +1527,7 @@ evaluated (and should return a string) when the closure is built. | |||
| 1510 | *** x-get-selection-value is renamed to gui-get-primary-selection. | 1527 | *** x-get-selection-value is renamed to gui-get-primary-selection. |
| 1511 | *** x-set-selection is renamed to gui-set-selection | 1528 | *** x-set-selection is renamed to gui-set-selection |
| 1512 | 1529 | ||
| 1530 | +++ | ||
| 1513 | ** New function `string-greaterp', which return the opposite result of | 1531 | ** New function `string-greaterp', which return the opposite result of |
| 1514 | `string-lessp'. | 1532 | `string-lessp'. |
| 1515 | 1533 | ||
| @@ -1533,12 +1551,15 @@ emulates the behavior of modern Posix platforms when the locale's | |||
| 1533 | codeset is "UTF-8" (as in "en_US.UTF-8"). This is needed because | 1551 | codeset is "UTF-8" (as in "en_US.UTF-8"). This is needed because |
| 1534 | MS-Windows doesn't support UTF-8 as codeset in its locales. | 1552 | MS-Windows doesn't support UTF-8 as codeset in its locales. |
| 1535 | 1553 | ||
| 1554 | +++ | ||
| 1536 | ** New function `alist-get', which is also a valid place (aka lvalue). | 1555 | ** New function `alist-get', which is also a valid place (aka lvalue). |
| 1537 | 1556 | ||
| 1557 | +++ | ||
| 1538 | ** New function `funcall-interactively', which works like `funcall' | 1558 | ** New function `funcall-interactively', which works like `funcall' |
| 1539 | but makes `called-interactively-p' treat the function as (you guessed it) | 1559 | but makes `called-interactively-p' treat the function as (you guessed it) |
| 1540 | called interactively. | 1560 | called interactively. |
| 1541 | 1561 | ||
| 1562 | +++ | ||
| 1542 | ** New function `function-put' to use instead of `put' for function properties. | 1563 | ** New function `function-put' to use instead of `put' for function properties. |
| 1543 | 1564 | ||
| 1544 | +++ | 1565 | +++ |
diff --git a/lisp/desktop.el b/lisp/desktop.el index cb973c48f8d..e795d9c2300 100644 --- a/lisp/desktop.el +++ b/lisp/desktop.el | |||
| @@ -140,8 +140,15 @@ | |||
| 140 | 140 | ||
| 141 | (defvar desktop-file-version "208" | 141 | (defvar desktop-file-version "208" |
| 142 | "Version number of desktop file format. | 142 | "Version number of desktop file format. |
| 143 | Written into the desktop file and used at desktop read to provide | 143 | Used at desktop read to provide backward compatibility.") |
| 144 | backward compatibility.") | 144 | |
| 145 | (defconst desktop-native-file-version 208 | ||
| 146 | "Format version of the current desktop package, an integer.") | ||
| 147 | (defvar desktop-io-file-version nil | ||
| 148 | "The format version of the current desktop file (an integer) or nil.") | ||
| 149 | ;; Note: Historically, the version number is embedded in the entry for | ||
| 150 | ;; each buffer. It is highly inadvisable for different buffer entries | ||
| 151 | ;; to have different format versions. | ||
| 145 | 152 | ||
| 146 | ;; ---------------------------------------------------------------------------- | 153 | ;; ---------------------------------------------------------------------------- |
| 147 | ;; USER OPTIONS -- settings you might want to play with. | 154 | ;; USER OPTIONS -- settings you might want to play with. |
| @@ -693,6 +700,7 @@ deletes all frames except the selected one (and its minibuffer frame, | |||
| 693 | if different)." | 700 | if different)." |
| 694 | (interactive) | 701 | (interactive) |
| 695 | (desktop-lazy-abort) | 702 | (desktop-lazy-abort) |
| 703 | (setq desktop-io-file-version nil) | ||
| 696 | (dolist (var desktop-globals-to-clear) | 704 | (dolist (var desktop-globals-to-clear) |
| 697 | (if (symbolp var) | 705 | (if (symbolp var) |
| 698 | (eval `(setq-default ,var nil)) | 706 | (eval `(setq-default ,var nil)) |
| @@ -781,44 +789,46 @@ buffer, which is (in order): | |||
| 781 | local variables; | 789 | local variables; |
| 782 | auxiliary information given by `desktop-var-serdes-funs'." | 790 | auxiliary information given by `desktop-var-serdes-funs'." |
| 783 | (set-buffer buffer) | 791 | (set-buffer buffer) |
| 784 | (list | 792 | `( |
| 785 | ;; base name of the buffer; replaces the buffer name if managed by uniquify | 793 | ;; base name of the buffer; replaces the buffer name if managed by uniquify |
| 786 | (and (fboundp 'uniquify-buffer-base-name) (uniquify-buffer-base-name)) | 794 | ,(and (fboundp 'uniquify-buffer-base-name) (uniquify-buffer-base-name)) |
| 787 | ;; basic information | 795 | ;; basic information |
| 788 | (desktop-file-name (buffer-file-name) desktop-dirname) | 796 | ,(desktop-file-name (buffer-file-name) desktop-dirname) |
| 789 | (buffer-name) | 797 | ,(buffer-name) |
| 790 | major-mode | 798 | ,major-mode |
| 791 | ;; minor modes | 799 | ;; minor modes |
| 792 | (let (ret) | 800 | ,(let (ret) |
| 793 | (dolist (minor-mode (mapcar #'car minor-mode-alist) ret) | 801 | (dolist (minor-mode (mapcar #'car minor-mode-alist) ret) |
| 794 | (and (boundp minor-mode) | 802 | (and (boundp minor-mode) |
| 795 | (symbol-value minor-mode) | 803 | (symbol-value minor-mode) |
| 796 | (let* ((special (assq minor-mode desktop-minor-mode-table)) | 804 | (let* ((special (assq minor-mode desktop-minor-mode-table)) |
| 797 | (value (cond (special (cadr special)) | 805 | (value (cond (special (cadr special)) |
| 798 | ((functionp minor-mode) minor-mode)))) | 806 | ((functionp minor-mode) minor-mode)))) |
| 799 | (when value (cl-pushnew value ret)))))) | 807 | (when value (cl-pushnew value ret)))))) |
| 800 | ;; point and mark, and read-only status | 808 | ;; point and mark, and read-only status |
| 801 | (point) | 809 | ,(point) |
| 802 | (list (mark t) mark-active) | 810 | ,(list (mark t) mark-active) |
| 803 | buffer-read-only | 811 | ,buffer-read-only |
| 804 | ;; auxiliary information | 812 | ;; auxiliary information |
| 805 | (when (functionp desktop-save-buffer) | 813 | ,(when (functionp desktop-save-buffer) |
| 806 | (funcall desktop-save-buffer desktop-dirname)) | 814 | (funcall desktop-save-buffer desktop-dirname)) |
| 807 | ;; local variables | 815 | ;; local variables |
| 808 | (let ((loclist (buffer-local-variables)) | 816 | ,(let ((loclist (buffer-local-variables)) |
| 809 | (ll nil)) | 817 | (ll nil)) |
| 810 | (dolist (local desktop-locals-to-save) | 818 | (dolist (local desktop-locals-to-save) |
| 811 | (let ((here (assq local loclist))) | 819 | (let ((here (assq local loclist))) |
| 812 | (cond (here | 820 | (cond (here |
| 813 | (push here ll)) | 821 | (push here ll)) |
| 814 | ((member local loclist) | 822 | ((member local loclist) |
| 815 | (push local ll))))) | 823 | (push local ll))))) |
| 816 | ll) | 824 | ll) |
| 817 | (mapcar (lambda (record) | 825 | ,@(when (>= desktop-io-file-version 208) |
| 818 | (let ((var (car record))) | 826 | (list |
| 819 | (list var | 827 | (mapcar (lambda (record) |
| 820 | (funcall (cadr record) (symbol-value var))))) | 828 | (let ((var (car record))) |
| 821 | desktop-var-serdes-funs))) | 829 | (list var |
| 830 | (funcall (cadr record) (symbol-value var))))) | ||
| 831 | desktop-var-serdes-funs))))) | ||
| 822 | 832 | ||
| 823 | ;; ---------------------------------------------------------------------------- | 833 | ;; ---------------------------------------------------------------------------- |
| 824 | (defun desktop--v2s (value) | 834 | (defun desktop--v2s (value) |
| @@ -983,20 +993,41 @@ Frames with a non-nil `desktop-dont-save' parameter are not saved." | |||
| 983 | :predicate #'desktop--check-dont-save)))) | 993 | :predicate #'desktop--check-dont-save)))) |
| 984 | 994 | ||
| 985 | ;;;###autoload | 995 | ;;;###autoload |
| 986 | (defun desktop-save (dirname &optional release only-if-changed) | 996 | (defun desktop-save (dirname &optional release only-if-changed version) |
| 987 | "Save the desktop in a desktop file. | 997 | "Save the desktop in a desktop file. |
| 988 | Parameter DIRNAME specifies where to save the desktop file. | 998 | Parameter DIRNAME specifies where to save the desktop file. |
| 989 | Optional parameter RELEASE says whether we're done with this desktop. | 999 | Optional parameter RELEASE says whether we're done with this |
| 990 | If ONLY-IF-CHANGED is non-nil, compare the current desktop information | 1000 | desktop. If ONLY-IF-CHANGED is non-nil, compare the current |
| 991 | to that in the desktop file, and if the desktop information has not | 1001 | desktop information to that in the desktop file, and if the |
| 992 | changed since it was last saved then do not rewrite the file." | 1002 | desktop information has not changed since it was last saved then |
| 1003 | do not rewrite the file. | ||
| 1004 | |||
| 1005 | This function can save the desktop in either format version | ||
| 1006 | 208 (which only Emacs 25.1 and later can read) or version | ||
| 1007 | 206 (which is readable by any Emacs from version 22.1 onwards). | ||
| 1008 | By default, it will use the same format the desktop file had when | ||
| 1009 | it was last saved, or version 208 when writing a fresh desktop | ||
| 1010 | file. | ||
| 1011 | |||
| 1012 | To upgrade a version 206 file to version 208, call this command | ||
| 1013 | explicitly with a bare prefix argument: C-u M-x desktop-save. | ||
| 1014 | You are recommended to do this once you have firmly upgraded to | ||
| 1015 | Emacs 25.1 (or later). To downgrade a version 208 file to version | ||
| 1016 | 206, use a double command prefix: C-u C-u M-x desktop-save. | ||
| 1017 | Confirmation will be requested in either case. In a non-interactive | ||
| 1018 | call, VERSION can be given as an integer, either 206 or 208, which | ||
| 1019 | will be accepted as the format version in which to save the file | ||
| 1020 | without further confirmation." | ||
| 993 | (interactive (list | 1021 | (interactive (list |
| 994 | ;; Or should we just use (car desktop-path)? | 1022 | ;; Or should we just use (car desktop-path)? |
| 995 | (let ((default (if (member "." desktop-path) | 1023 | (let ((default (if (member "." desktop-path) |
| 996 | default-directory | 1024 | default-directory |
| 997 | user-emacs-directory))) | 1025 | user-emacs-directory))) |
| 998 | (read-directory-name "Directory to save desktop file in: " | 1026 | (read-directory-name "Directory to save desktop file in: " |
| 999 | default default t)))) | 1027 | default default t)) |
| 1028 | nil | ||
| 1029 | nil | ||
| 1030 | current-prefix-arg)) | ||
| 1000 | (setq desktop-dirname (file-name-as-directory (expand-file-name dirname))) | 1031 | (setq desktop-dirname (file-name-as-directory (expand-file-name dirname))) |
| 1001 | (save-excursion | 1032 | (save-excursion |
| 1002 | (let ((eager desktop-restore-eager) | 1033 | (let ((eager desktop-restore-eager) |
| @@ -1017,12 +1048,34 @@ changed since it was last saved then do not rewrite the file." | |||
| 1017 | (desktop-release-lock) | 1048 | (desktop-release-lock) |
| 1018 | (unless (and new-modtime (desktop-owner)) (desktop-claim-lock))) | 1049 | (unless (and new-modtime (desktop-owner)) (desktop-claim-lock))) |
| 1019 | 1050 | ||
| 1051 | ;; What format are we going to write the file in? | ||
| 1052 | (setq desktop-io-file-version | ||
| 1053 | (cond | ||
| 1054 | ((equal version '(4)) | ||
| 1055 | (if (or (eq desktop-io-file-version 208) | ||
| 1056 | (yes-or-no-p "Save desktop file in format 208 \ | ||
| 1057 | \(Readable by Emacs 25.1 and later only)? ")) | ||
| 1058 | 208 | ||
| 1059 | (or desktop-io-file-version desktop-native-file-version))) | ||
| 1060 | ((equal version '(16)) | ||
| 1061 | (if (or (eq desktop-io-file-version 206) | ||
| 1062 | (yes-or-no-p "Save desktop file in format 206 \ | ||
| 1063 | \(Readable by all Emacs versions since 22.1)? ")) | ||
| 1064 | 206 | ||
| 1065 | (or desktop-io-file-version desktop-native-file-version))) | ||
| 1066 | ((memq version '(206 208)) | ||
| 1067 | version) | ||
| 1068 | ((null desktop-io-file-version) ; As yet, no desktop file exists. | ||
| 1069 | desktop-native-file-version) | ||
| 1070 | (t | ||
| 1071 | desktop-io-file-version))) | ||
| 1072 | |||
| 1020 | (with-temp-buffer | 1073 | (with-temp-buffer |
| 1021 | (insert | 1074 | (insert |
| 1022 | ";; -*- mode: emacs-lisp; coding: emacs-mule; -*-\n" | 1075 | ";; -*- mode: emacs-lisp; coding: emacs-mule; -*-\n" |
| 1023 | desktop-header | 1076 | desktop-header |
| 1024 | ";; Created " (current-time-string) "\n" | 1077 | ";; Created " (current-time-string) "\n" |
| 1025 | ";; Desktop file format version " desktop-file-version "\n" | 1078 | ";; Desktop file format version " (format "%d" desktop-io-file-version) "\n" |
| 1026 | ";; Emacs version " emacs-version "\n") | 1079 | ";; Emacs version " emacs-version "\n") |
| 1027 | (save-excursion (run-hooks 'desktop-save-hook)) | 1080 | (save-excursion (run-hooks 'desktop-save-hook)) |
| 1028 | (goto-char (point-max)) | 1081 | (goto-char (point-max)) |
| @@ -1052,7 +1105,7 @@ changed since it was last saved then do not rewrite the file." | |||
| 1052 | "desktop-create-buffer" | 1105 | "desktop-create-buffer" |
| 1053 | "desktop-append-buffer-args") | 1106 | "desktop-append-buffer-args") |
| 1054 | " " | 1107 | " " |
| 1055 | desktop-file-version) | 1108 | (format "%d" desktop-io-file-version)) |
| 1056 | ;; If there's a non-empty base name, we save it instead of the buffer name | 1109 | ;; If there's a non-empty base name, we save it instead of the buffer name |
| 1057 | (when (and base (not (string= base ""))) | 1110 | (when (and base (not (string= base ""))) |
| 1058 | (setcar (nthcdr 1 l) base)) | 1111 | (setcar (nthcdr 1 l) base)) |
| @@ -1390,6 +1443,8 @@ and try to load that." | |||
| 1390 | compacted-vars | 1443 | compacted-vars |
| 1391 | &rest _unsupported) | 1444 | &rest _unsupported) |
| 1392 | 1445 | ||
| 1446 | (setq desktop-io-file-version file-version) | ||
| 1447 | |||
| 1393 | (let ((desktop-file-version file-version) | 1448 | (let ((desktop-file-version file-version) |
| 1394 | (desktop-buffer-file-name buffer-filename) | 1449 | (desktop-buffer-file-name buffer-filename) |
| 1395 | (desktop-buffer-name buffer-name) | 1450 | (desktop-buffer-name buffer-name) |
diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index a678fca3ea3..ab10edeedbf 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el | |||
| @@ -2713,6 +2713,41 @@ with the command \\[tags-loop-continue]." | |||
| 2713 | (tags-query-replace from to delimited | 2713 | (tags-query-replace from to delimited |
| 2714 | '(dired-get-marked-files nil nil 'dired-nondirectory-p))) | 2714 | '(dired-get-marked-files nil nil 'dired-nondirectory-p))) |
| 2715 | 2715 | ||
| 2716 | (declare-function xref--show-xrefs "xref") | ||
| 2717 | (declare-function xref-query-replace "xref") | ||
| 2718 | |||
| 2719 | ;;;###autoload | ||
| 2720 | (defun dired-do-find-regexp (regexp) | ||
| 2721 | "Find all matches for REGEXP in all marked files, recursively." | ||
| 2722 | (interactive "sSearch marked files (regexp): ") | ||
| 2723 | (require 'grep) | ||
| 2724 | (defvar grep-find-ignored-files) | ||
| 2725 | (let* ((files (dired-get-marked-files)) | ||
| 2726 | (ignores (nconc (mapcar | ||
| 2727 | (lambda (s) (concat s "/")) | ||
| 2728 | vc-directory-exclusion-list) | ||
| 2729 | grep-find-ignored-files)) | ||
| 2730 | (xrefs (cl-mapcan | ||
| 2731 | (lambda (file) | ||
| 2732 | (xref-collect-matches regexp "*" file | ||
| 2733 | (and (file-directory-p file) | ||
| 2734 | ignores))) | ||
| 2735 | files))) | ||
| 2736 | (unless xrefs | ||
| 2737 | (user-error "No matches for: %s" regexp)) | ||
| 2738 | (xref--show-xrefs xrefs nil t))) | ||
| 2739 | |||
| 2740 | ;;;###autoload | ||
| 2741 | (defun dired-do-find-regexp-and-replace (from to) | ||
| 2742 | "Replace matches of FROM with TO, in all marked files, recursively." | ||
| 2743 | (interactive | ||
| 2744 | (let ((common | ||
| 2745 | (query-replace-read-args | ||
| 2746 | "Query replace regexp in marked files" t t))) | ||
| 2747 | (list (nth 0 common) (nth 1 common)))) | ||
| 2748 | (with-current-buffer (dired-do-find-regexp from) | ||
| 2749 | (xref-query-replace from to))) | ||
| 2750 | |||
| 2716 | (defun dired-nondirectory-p (file) | 2751 | (defun dired-nondirectory-p (file) |
| 2717 | (not (file-directory-p file))) | 2752 | (not (file-directory-p file))) |
| 2718 | 2753 | ||
diff --git a/lisp/dired.el b/lisp/dired.el index 63124fce5e5..6c7445c3486 100644 --- a/lisp/dired.el +++ b/lisp/dired.el | |||
| @@ -1453,7 +1453,7 @@ Do so according to the former subdir alist OLD-SUBDIR-ALIST." | |||
| 1453 | (define-key map "." 'dired-clean-directory) | 1453 | (define-key map "." 'dired-clean-directory) |
| 1454 | (define-key map "~" 'dired-flag-backup-files) | 1454 | (define-key map "~" 'dired-flag-backup-files) |
| 1455 | ;; Upper case keys (except !) for operating on the marked files | 1455 | ;; Upper case keys (except !) for operating on the marked files |
| 1456 | (define-key map "A" 'dired-do-search) | 1456 | (define-key map "A" 'dired-do-find-regexp) |
| 1457 | (define-key map "C" 'dired-do-copy) | 1457 | (define-key map "C" 'dired-do-copy) |
| 1458 | (define-key map "B" 'dired-do-byte-compile) | 1458 | (define-key map "B" 'dired-do-byte-compile) |
| 1459 | (define-key map "D" 'dired-do-delete) | 1459 | (define-key map "D" 'dired-do-delete) |
| @@ -1463,7 +1463,7 @@ Do so according to the former subdir alist OLD-SUBDIR-ALIST." | |||
| 1463 | (define-key map "M" 'dired-do-chmod) | 1463 | (define-key map "M" 'dired-do-chmod) |
| 1464 | (define-key map "O" 'dired-do-chown) | 1464 | (define-key map "O" 'dired-do-chown) |
| 1465 | (define-key map "P" 'dired-do-print) | 1465 | (define-key map "P" 'dired-do-print) |
| 1466 | (define-key map "Q" 'dired-do-query-replace-regexp) | 1466 | (define-key map "Q" 'dired-do-find-regexp-and-replace) |
| 1467 | (define-key map "R" 'dired-do-rename) | 1467 | (define-key map "R" 'dired-do-rename) |
| 1468 | (define-key map "S" 'dired-do-symlink) | 1468 | (define-key map "S" 'dired-do-symlink) |
| 1469 | (define-key map "T" 'dired-do-touch) | 1469 | (define-key map "T" 'dired-do-touch) |
diff --git a/lisp/emacs-lisp/inline.el b/lisp/emacs-lisp/inline.el index 56780fbb05a..058c56c3b49 100644 --- a/lisp/emacs-lisp/inline.el +++ b/lisp/emacs-lisp/inline.el | |||
| @@ -102,7 +102,7 @@ VARS should be a list of elements of the form (VAR EXP) or just VAR, in case | |||
| 102 | EXP is equal to VAR. The result is to evaluate EXP and bind the result to VAR. | 102 | EXP is equal to VAR. The result is to evaluate EXP and bind the result to VAR. |
| 103 | 103 | ||
| 104 | The tail of VARS can be either nil or a symbol VAR which should hold a list | 104 | The tail of VARS can be either nil or a symbol VAR which should hold a list |
| 105 | of arguments,in which case each argument is evaluated and the resulting | 105 | of arguments, in which case each argument is evaluated and the resulting |
| 106 | new list is re-bound to VAR. | 106 | new list is re-bound to VAR. |
| 107 | 107 | ||
| 108 | After VARS is handled, BODY is evaluated in the new environment." | 108 | After VARS is handled, BODY is evaluated in the new environment." |
diff --git a/lisp/net/shr.el b/lisp/net/shr.el index 2511d673e7e..290a6422bd7 100644 --- a/lisp/net/shr.el +++ b/lisp/net/shr.el | |||
| @@ -1617,7 +1617,9 @@ The preference is a float determined from `shr-prefer-media-type'." | |||
| 1617 | (shr-insert-table (shr-make-table dom sketch-widths t) sketch-widths))) | 1617 | (shr-insert-table (shr-make-table dom sketch-widths t) sketch-widths))) |
| 1618 | 1618 | ||
| 1619 | (defun shr-table-body (dom) | 1619 | (defun shr-table-body (dom) |
| 1620 | (let ((tbodies (dom-by-tag dom 'tbody))) | 1620 | (let ((tbodies (seq-filter (lambda (child) |
| 1621 | (eq (dom-tag child) 'tbody)) | ||
| 1622 | (dom-children dom)))) | ||
| 1621 | (cond | 1623 | (cond |
| 1622 | ((null tbodies) | 1624 | ((null tbodies) |
| 1623 | dom) | 1625 | dom) |
diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index a972def24b0..85f390746d9 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el | |||
| @@ -264,7 +264,6 @@ DIRS must contain directory names." | |||
| 264 | (symbol-value var))) | 264 | (symbol-value var))) |
| 265 | 265 | ||
| 266 | (declare-function grep-read-files "grep") | 266 | (declare-function grep-read-files "grep") |
| 267 | (declare-function xref-collect-matches "xref") | ||
| 268 | (declare-function xref--show-xrefs "xref") | 267 | (declare-function xref--show-xrefs "xref") |
| 269 | (declare-function xref-backend-identifier-at-point "xref") | 268 | (declare-function xref-backend-identifier-at-point "xref") |
| 270 | (declare-function xref--find-ignores-arguments "xref") | 269 | (declare-function xref--find-ignores-arguments "xref") |
| @@ -295,8 +294,8 @@ pattern to search for." | |||
| 295 | (project--find-regexp-in dirs regexp pr))) | 294 | (project--find-regexp-in dirs regexp pr))) |
| 296 | 295 | ||
| 297 | (defun project--read-regexp () | 296 | (defun project--read-regexp () |
| 298 | (read-regexp "Find regexp" | 297 | (let ((id (xref-backend-identifier-at-point (xref-find-backend)))) |
| 299 | (xref-backend-identifier-at-point (xref-find-backend)))) | 298 | (read-regexp "Find regexp" (and id (regexp-quote id))))) |
| 300 | 299 | ||
| 301 | (defun project--find-regexp-in (dirs regexp project) | 300 | (defun project--find-regexp-in (dirs regexp project) |
| 302 | (require 'grep) | 301 | (require 'grep) |
diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el index 8f08b7c9e60..53f8a6bb4c0 100644 --- a/lisp/progmodes/ruby-mode.el +++ b/lisp/progmodes/ruby-mode.el | |||
| @@ -1830,7 +1830,7 @@ It will be properly highlighted even when the call omits parens.") | |||
| 1830 | "\\)\\s *") | 1830 | "\\)\\s *") |
| 1831 | "Regexp to match text that can be followed by a regular expression.")) | 1831 | "Regexp to match text that can be followed by a regular expression.")) |
| 1832 | 1832 | ||
| 1833 | (defun ruby-syntax-propertize-function (start end) | 1833 | (defun ruby-syntax-propertize (start end) |
| 1834 | "Syntactic keywords for Ruby mode. See `syntax-propertize-function'." | 1834 | "Syntactic keywords for Ruby mode. See `syntax-propertize-function'." |
| 1835 | (let (case-fold-search) | 1835 | (let (case-fold-search) |
| 1836 | (goto-char start) | 1836 | (goto-char start) |
| @@ -1856,6 +1856,8 @@ It will be properly highlighted even when the call omits parens.") | |||
| 1856 | (zerop (skip-syntax-backward "w_"))) | 1856 | (zerop (skip-syntax-backward "w_"))) |
| 1857 | (memq (preceding-char) '(?@ ?$)))) | 1857 | (memq (preceding-char) '(?@ ?$)))) |
| 1858 | (string-to-syntax "_")))) | 1858 | (string-to-syntax "_")))) |
| 1859 | ;; Backtick method redefinition. | ||
| 1860 | ("^[ \t]*def +\\(`\\)" (1 "_")) | ||
| 1859 | ;; Regular expressions. Start with matching unescaped slash. | 1861 | ;; Regular expressions. Start with matching unescaped slash. |
| 1860 | ("\\(?:\\=\\|[^\\]\\)\\(?:\\\\\\\\\\)*\\(/\\)" | 1862 | ("\\(?:\\=\\|[^\\]\\)\\(?:\\\\\\\\\\)*\\(/\\)" |
| 1861 | (1 (let ((state (save-excursion (syntax-ppss (match-beginning 1))))) | 1863 | (1 (let ((state (save-excursion (syntax-ppss (match-beginning 1))))) |
| @@ -1891,6 +1893,9 @@ It will be properly highlighted even when the call omits parens.") | |||
| 1891 | (1 (prog1 "|" (ruby-syntax-propertize-percent-literal end))))) | 1893 | (1 (prog1 "|" (ruby-syntax-propertize-percent-literal end))))) |
| 1892 | (point) end))) | 1894 | (point) end))) |
| 1893 | 1895 | ||
| 1896 | (define-obsolete-function-alias | ||
| 1897 | 'ruby-syntax-propertize-function 'ruby-syntax-propertize "25.1") | ||
| 1898 | |||
| 1894 | (defun ruby-syntax-propertize-heredoc (limit) | 1899 | (defun ruby-syntax-propertize-heredoc (limit) |
| 1895 | (let ((ppss (syntax-ppss)) | 1900 | (let ((ppss (syntax-ppss)) |
| 1896 | (res '())) | 1901 | (res '())) |
| @@ -2252,7 +2257,7 @@ See `font-lock-syntax-table'.") | |||
| 2252 | (setq-local font-lock-keywords ruby-font-lock-keywords) | 2257 | (setq-local font-lock-keywords ruby-font-lock-keywords) |
| 2253 | (setq-local font-lock-syntax-table ruby-font-lock-syntax-table) | 2258 | (setq-local font-lock-syntax-table ruby-font-lock-syntax-table) |
| 2254 | 2259 | ||
| 2255 | (setq-local syntax-propertize-function #'ruby-syntax-propertize-function)) | 2260 | (setq-local syntax-propertize-function #'ruby-syntax-propertize)) |
| 2256 | 2261 | ||
| 2257 | ;;; Invoke ruby-mode when appropriate | 2262 | ;;; Invoke ruby-mode when appropriate |
| 2258 | 2263 | ||
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index 6220b4cdc92..2bccd857576 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el | |||
| @@ -511,11 +511,18 @@ references displayed in the current *xref* buffer." | |||
| 511 | (let ((fr (read-regexp "Xref query-replace (regexp)" ".*"))) | 511 | (let ((fr (read-regexp "Xref query-replace (regexp)" ".*"))) |
| 512 | (list fr | 512 | (list fr |
| 513 | (read-regexp (format "Xref query-replace (regexp) %s with: " fr))))) | 513 | (read-regexp (format "Xref query-replace (regexp) %s with: " fr))))) |
| 514 | (let (pairs item) | 514 | (let ((reporter (make-progress-reporter (format "Saving search results...") |
| 515 | 0 (line-number-at-pos (point-max)))) | ||
| 516 | (counter 0) | ||
| 517 | pairs item) | ||
| 515 | (unwind-protect | 518 | (unwind-protect |
| 516 | (progn | 519 | (progn |
| 517 | (save-excursion | 520 | (save-excursion |
| 518 | (goto-char (point-min)) | 521 | (goto-char (point-min)) |
| 522 | ;; TODO: This list should be computed on-demand instead. | ||
| 523 | ;; As long as the UI just iterates through matches one by | ||
| 524 | ;; one, there's no need to compute them all in advance. | ||
| 525 | ;; Then we can throw away the reporter. | ||
| 519 | (while (setq item (xref--search-property 'xref-item)) | 526 | (while (setq item (xref--search-property 'xref-item)) |
| 520 | (when (xref-match-length item) | 527 | (when (xref-match-length item) |
| 521 | (save-excursion | 528 | (save-excursion |
| @@ -535,9 +542,11 @@ references displayed in the current *xref* buffer." | |||
| 535 | (line-end-position)) | 542 | (line-end-position)) |
| 536 | (xref-item-summary item)) | 543 | (xref-item-summary item)) |
| 537 | (user-error "Search results out of date")) | 544 | (user-error "Search results out of date")) |
| 545 | (progress-reporter-update reporter (cl-incf counter)) | ||
| 538 | (push (cons beg end) pairs))))) | 546 | (push (cons beg end) pairs))))) |
| 539 | (setq pairs (nreverse pairs))) | 547 | (setq pairs (nreverse pairs))) |
| 540 | (unless pairs (user-error "No suitable matches here")) | 548 | (unless pairs (user-error "No suitable matches here")) |
| 549 | (progress-reporter-done reporter) | ||
| 541 | (xref--query-replace-1 from to pairs)) | 550 | (xref--query-replace-1 from to pairs)) |
| 542 | (dolist (pair pairs) | 551 | (dolist (pair pairs) |
| 543 | (move-marker (car pair) nil) | 552 | (move-marker (car pair) nil) |
| @@ -713,9 +722,9 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)." | |||
| 713 | 722 | ||
| 714 | (defvar xref--read-pattern-history nil) | 723 | (defvar xref--read-pattern-history nil) |
| 715 | 724 | ||
| 716 | (defun xref--show-xrefs (xrefs window) | 725 | (defun xref--show-xrefs (xrefs window &optional always-show-list) |
| 717 | (cond | 726 | (cond |
| 718 | ((not (cdr xrefs)) | 727 | ((and (not (cdr xrefs)) (not always-show-list)) |
| 719 | (xref-push-marker-stack) | 728 | (xref-push-marker-stack) |
| 720 | (xref--pop-to-location (car xrefs) window)) | 729 | (xref--pop-to-location (car xrefs) window)) |
| 721 | (t | 730 | (t |
| @@ -866,11 +875,12 @@ tools are used, and when." | |||
| 866 | (mapc #'kill-buffer | 875 | (mapc #'kill-buffer |
| 867 | (cl-set-difference (buffer-list) orig-buffers))))) | 876 | (cl-set-difference (buffer-list) orig-buffers))))) |
| 868 | 877 | ||
| 878 | ;;;###autoload | ||
| 869 | (defun xref-collect-matches (regexp files dir ignores) | 879 | (defun xref-collect-matches (regexp files dir ignores) |
| 870 | "Collect matches for REGEXP inside FILES in DIR. | 880 | "Collect matches for REGEXP inside FILES in DIR. |
| 871 | FILES is a string with glob patterns separated by spaces. | 881 | FILES is a string with glob patterns separated by spaces. |
| 872 | IGNORES is a list of glob patterns." | 882 | IGNORES is a list of glob patterns." |
| 873 | (cl-assert (directory-name-p dir)) | 883 | ;; DIR can also be a regular file for now; let's not advertise that. |
| 874 | (require 'semantic/fw) | 884 | (require 'semantic/fw) |
| 875 | (grep-compute-defaults) | 885 | (grep-compute-defaults) |
| 876 | (defvar grep-find-template) | 886 | (defvar grep-find-template) |
| @@ -885,6 +895,8 @@ IGNORES is a list of glob patterns." | |||
| 885 | (orig-buffers (buffer-list)) | 895 | (orig-buffers (buffer-list)) |
| 886 | (buf (get-buffer-create " *xref-grep*")) | 896 | (buf (get-buffer-create " *xref-grep*")) |
| 887 | (grep-re (caar grep-regexp-alist)) | 897 | (grep-re (caar grep-regexp-alist)) |
| 898 | (counter 0) | ||
| 899 | reporter | ||
| 888 | hits) | 900 | hits) |
| 889 | (with-current-buffer buf | 901 | (with-current-buffer buf |
| 890 | (erase-buffer) | 902 | (erase-buffer) |
| @@ -894,9 +906,17 @@ IGNORES is a list of glob patterns." | |||
| 894 | (push (cons (string-to-number (match-string 2)) | 906 | (push (cons (string-to-number (match-string 2)) |
| 895 | (match-string 1)) | 907 | (match-string 1)) |
| 896 | hits))) | 908 | hits))) |
| 909 | (setq reporter (make-progress-reporter | ||
| 910 | (format "Collecting search results...") | ||
| 911 | 0 (length hits))) | ||
| 897 | (unwind-protect | 912 | (unwind-protect |
| 898 | (cl-mapcan (lambda (hit) (xref--collect-matches hit regexp)) | 913 | (cl-mapcan (lambda (hit) |
| 914 | (prog1 | ||
| 915 | (progress-reporter-update reporter counter) | ||
| 916 | (cl-incf counter)) | ||
| 917 | (xref--collect-matches hit regexp)) | ||
| 899 | (nreverse hits)) | 918 | (nreverse hits)) |
| 919 | (progress-reporter-done reporter) | ||
| 900 | ;; TODO: Same as above. | 920 | ;; TODO: Same as above. |
| 901 | (mapc #'kill-buffer | 921 | (mapc #'kill-buffer |
| 902 | (cl-set-difference (buffer-list) orig-buffers))))) | 922 | (cl-set-difference (buffer-list) orig-buffers))))) |
| @@ -922,23 +942,24 @@ IGNORES is a list of glob patterns." | |||
| 922 | (defun xref--find-ignores-arguments (ignores dir) | 942 | (defun xref--find-ignores-arguments (ignores dir) |
| 923 | ;; `shell-quote-argument' quotes the tilde as well. | 943 | ;; `shell-quote-argument' quotes the tilde as well. |
| 924 | (cl-assert (not (string-match-p "\\`~" dir))) | 944 | (cl-assert (not (string-match-p "\\`~" dir))) |
| 925 | (concat | 945 | (when ignores |
| 926 | (shell-quote-argument "(") | 946 | (concat |
| 927 | " -path " | 947 | (shell-quote-argument "(") |
| 928 | (mapconcat | 948 | " -path " |
| 929 | (lambda (ignore) | 949 | (mapconcat |
| 930 | (when (string-match-p "/\\'" ignore) | 950 | (lambda (ignore) |
| 931 | (setq ignore (concat ignore "*"))) | 951 | (when (string-match-p "/\\'" ignore) |
| 932 | (if (string-match "\\`\\./" ignore) | 952 | (setq ignore (concat ignore "*"))) |
| 933 | (setq ignore (replace-match dir t t ignore)) | 953 | (if (string-match "\\`\\./" ignore) |
| 934 | (unless (string-prefix-p "*" ignore) | 954 | (setq ignore (replace-match dir t t ignore)) |
| 935 | (setq ignore (concat "*/" ignore)))) | 955 | (unless (string-prefix-p "*" ignore) |
| 936 | (shell-quote-argument ignore)) | 956 | (setq ignore (concat "*/" ignore)))) |
| 937 | ignores | 957 | (shell-quote-argument ignore)) |
| 938 | " -o -path ") | 958 | ignores |
| 939 | " " | 959 | " -o -path ") |
| 940 | (shell-quote-argument ")") | 960 | " " |
| 941 | " -prune -o ")) | 961 | (shell-quote-argument ")") |
| 962 | " -prune -o "))) | ||
| 942 | 963 | ||
| 943 | (defun xref--regexp-to-extended (str) | 964 | (defun xref--regexp-to-extended (str) |
| 944 | (replace-regexp-in-string | 965 | (replace-regexp-in-string |
diff --git a/m4/ax_gcc_var_attribute.m4 b/m4/ax_gcc_var_attribute.m4 deleted file mode 100644 index d12fce8934e..00000000000 --- a/m4/ax_gcc_var_attribute.m4 +++ /dev/null | |||
| @@ -1,141 +0,0 @@ | |||
| 1 | # =========================================================================== | ||
| 2 | # http://www.gnu.org/software/autoconf-archive/ax_gcc_var_attribute.html | ||
| 3 | # =========================================================================== | ||
| 4 | # | ||
| 5 | # SYNOPSIS | ||
| 6 | # | ||
| 7 | # AX_GCC_VAR_ATTRIBUTE(ATTRIBUTE) | ||
| 8 | # | ||
| 9 | # DESCRIPTION | ||
| 10 | # | ||
| 11 | # This macro checks if the compiler supports one of GCC's variable | ||
| 12 | # attributes; many other compilers also provide variable attributes with | ||
| 13 | # the same syntax. Compiler warnings are used to detect supported | ||
| 14 | # attributes as unsupported ones are ignored by default so quieting | ||
| 15 | # warnings when using this macro will yield false positives. | ||
| 16 | # | ||
| 17 | # The ATTRIBUTE parameter holds the name of the attribute to be checked. | ||
| 18 | # | ||
| 19 | # If ATTRIBUTE is supported define HAVE_VAR_ATTRIBUTE_<ATTRIBUTE>. | ||
| 20 | # | ||
| 21 | # The macro caches its result in the ax_cv_have_var_attribute_<attribute> | ||
| 22 | # variable. | ||
| 23 | # | ||
| 24 | # The macro currently supports the following variable attributes: | ||
| 25 | # | ||
| 26 | # aligned | ||
| 27 | # cleanup | ||
| 28 | # common | ||
| 29 | # nocommon | ||
| 30 | # deprecated | ||
| 31 | # mode | ||
| 32 | # packed | ||
| 33 | # tls_model | ||
| 34 | # unused | ||
| 35 | # used | ||
| 36 | # vector_size | ||
| 37 | # weak | ||
| 38 | # dllimport | ||
| 39 | # dllexport | ||
| 40 | # init_priority | ||
| 41 | # | ||
| 42 | # Unsupported variable attributes will be tested against a global integer | ||
| 43 | # variable and without any arguments given to the attribute itself; the | ||
| 44 | # result of this check might be wrong or meaningless so use with care. | ||
| 45 | # | ||
| 46 | # LICENSE | ||
| 47 | # | ||
| 48 | # Copyright (c) 2013 Gabriele Svelto <gabriele.svelto@gmail.com> | ||
| 49 | # | ||
| 50 | # Copying and distribution of this file, with or without modification, are | ||
| 51 | # permitted in any medium without royalty provided the copyright notice | ||
| 52 | # and this notice are preserved. This file is offered as-is, without any | ||
| 53 | # warranty. | ||
| 54 | |||
| 55 | #serial 3 | ||
| 56 | |||
| 57 | AC_DEFUN([AX_GCC_VAR_ATTRIBUTE], [ | ||
| 58 | AS_VAR_PUSHDEF([ac_var], [ax_cv_have_var_attribute_$1]) | ||
| 59 | |||
| 60 | AC_CACHE_CHECK([for __attribute__(($1))], [ac_var], [ | ||
| 61 | AC_LINK_IFELSE([AC_LANG_PROGRAM([ | ||
| 62 | m4_case([$1], | ||
| 63 | [aligned], [ | ||
| 64 | int foo __attribute__(($1(32))); | ||
| 65 | ], | ||
| 66 | [cleanup], [ | ||
| 67 | int bar(int *t) { return *t; }; | ||
| 68 | ], | ||
| 69 | [common], [ | ||
| 70 | int foo __attribute__(($1)); | ||
| 71 | ], | ||
| 72 | [nocommon], [ | ||
| 73 | int foo __attribute__(($1)); | ||
| 74 | ], | ||
| 75 | [deprecated], [ | ||
| 76 | int foo __attribute__(($1)) = 0; | ||
| 77 | ], | ||
| 78 | [mode], [ | ||
| 79 | long foo __attribute__(($1(word))); | ||
| 80 | ], | ||
| 81 | [packed], [ | ||
| 82 | struct bar { | ||
| 83 | int baz __attribute__(($1)); | ||
| 84 | }; | ||
| 85 | ], | ||
| 86 | [tls_model], [ | ||
| 87 | __thread int bar1 __attribute__(($1("global-dynamic"))); | ||
| 88 | __thread int bar2 __attribute__(($1("local-dynamic"))); | ||
| 89 | __thread int bar3 __attribute__(($1("initial-exec"))); | ||
| 90 | __thread int bar4 __attribute__(($1("local-exec"))); | ||
| 91 | ], | ||
| 92 | [unused], [ | ||
| 93 | int foo __attribute__(($1)); | ||
| 94 | ], | ||
| 95 | [used], [ | ||
| 96 | int foo __attribute__(($1)); | ||
| 97 | ], | ||
| 98 | [vector_size], [ | ||
| 99 | int foo __attribute__(($1(16))); | ||
| 100 | ], | ||
| 101 | [weak], [ | ||
| 102 | int foo __attribute__(($1)); | ||
| 103 | ], | ||
| 104 | [dllimport], [ | ||
| 105 | int foo __attribute__(($1)); | ||
| 106 | ], | ||
| 107 | [dllexport], [ | ||
| 108 | int foo __attribute__(($1)); | ||
| 109 | ], | ||
| 110 | [init_priority], [ | ||
| 111 | struct bar { bar() {} ~bar() {} }; | ||
| 112 | bar b __attribute__(($1(65535/2))); | ||
| 113 | ], | ||
| 114 | [ | ||
| 115 | m4_warn([syntax], [Unsupported attribute $1, the test may fail]) | ||
| 116 | int foo __attribute__(($1)); | ||
| 117 | ] | ||
| 118 | )], [ | ||
| 119 | m4_case([$1], | ||
| 120 | [cleanup], [ | ||
| 121 | int foo __attribute__(($1(bar))) = 0; | ||
| 122 | foo = foo + 1; | ||
| 123 | ], | ||
| 124 | [] | ||
| 125 | )]) | ||
| 126 | ], | ||
| 127 | dnl GCC doesn't exit with an error if an unknown attribute is | ||
| 128 | dnl provided but only outputs a warning, so accept the attribute | ||
| 129 | dnl only if no warning were issued. | ||
| 130 | [AS_IF([test -s conftest.err], | ||
| 131 | [AS_VAR_SET([ac_var], [no])], | ||
| 132 | [AS_VAR_SET([ac_var], [yes])])], | ||
| 133 | [AS_VAR_SET([ac_var], [no])]) | ||
| 134 | ]) | ||
| 135 | |||
| 136 | AS_IF([test yes = AS_VAR_GET([ac_var])], | ||
| 137 | [AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_VAR_ATTRIBUTE_$1), 1, | ||
| 138 | [Define to 1 if the system has the `$1' variable attribute])], []) | ||
| 139 | |||
| 140 | AS_VAR_POPDEF([ac_var]) | ||
| 141 | ]) | ||
diff --git a/src/conf_post.h b/src/conf_post.h index 98ff12e5a53..5c332a05a5c 100644 --- a/src/conf_post.h +++ b/src/conf_post.h | |||
| @@ -51,10 +51,21 @@ typedef bool bool_bf; | |||
| 51 | #endif | 51 | #endif |
| 52 | #endif | 52 | #endif |
| 53 | 53 | ||
| 54 | /* When not using Clang, assume its attributes and features are absent. */ | 54 | /* Simulate __has_attribute on compilers that lack it. It is used only |
| 55 | on arguments like alloc_size that are handled in this simulation. */ | ||
| 55 | #ifndef __has_attribute | 56 | #ifndef __has_attribute |
| 56 | # define __has_attribute(a) false | 57 | # define __has_attribute(a) __has_attribute_##a |
| 57 | #endif | 58 | # define __has_attribute_alloc_size (4 < __GNUC__ + (3 <= __GNUC_MINOR__)) |
| 59 | # define __has_attribute_cleanup (3 < __GNUC__ + (4 <= __GNUC_MINOR__)) | ||
| 60 | # define __has_attribute_externally_visible \ | ||
| 61 | (4 < __GNUC__ + (1 <= __GNUC_MINOR__)) | ||
| 62 | # define __has_attribute_no_address_safety_analysis false | ||
| 63 | # define __has_attribute_no_sanitize_address \ | ||
| 64 | (4 < __GNUC__ + (8 <= __GNUC_MINOR__)) | ||
| 65 | #endif | ||
| 66 | |||
| 67 | /* Simulate __has_feature on compilers that lack it. It is used only | ||
| 68 | to define ADDRESS_SANITIZER below. */ | ||
| 58 | #ifndef __has_feature | 69 | #ifndef __has_feature |
| 59 | # define __has_feature(a) false | 70 | # define __has_feature(a) false |
| 60 | #endif | 71 | #endif |
| @@ -222,9 +233,7 @@ extern int emacs_setenv_TZ (char const *); | |||
| 222 | #define NO_INLINE | 233 | #define NO_INLINE |
| 223 | #endif | 234 | #endif |
| 224 | 235 | ||
| 225 | #if (__clang__ \ | 236 | #if __has_attribute (externally_visible) |
| 226 | ? __has_attribute (externally_visible) \ | ||
| 227 | : (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1))) | ||
| 228 | #define EXTERNALLY_VISIBLE __attribute__((externally_visible)) | 237 | #define EXTERNALLY_VISIBLE __attribute__((externally_visible)) |
| 229 | #else | 238 | #else |
| 230 | #define EXTERNALLY_VISIBLE | 239 | #define EXTERNALLY_VISIBLE |
| @@ -253,9 +262,7 @@ extern int emacs_setenv_TZ (char const *); | |||
| 253 | # define ATTRIBUTE_MALLOC | 262 | # define ATTRIBUTE_MALLOC |
| 254 | #endif | 263 | #endif |
| 255 | 264 | ||
| 256 | #if (__clang__ \ | 265 | #if __has_attribute (alloc_size) |
| 257 | ? __has_attribute (alloc_size) \ | ||
| 258 | : 4 < __GNUC__ + (3 <= __GNUC_MINOR__)) | ||
| 259 | # define ATTRIBUTE_ALLOC_SIZE(args) __attribute__ ((__alloc_size__ args)) | 266 | # define ATTRIBUTE_ALLOC_SIZE(args) __attribute__ ((__alloc_size__ args)) |
| 260 | #else | 267 | #else |
| 261 | # define ATTRIBUTE_ALLOC_SIZE(args) | 268 | # define ATTRIBUTE_ALLOC_SIZE(args) |
| @@ -278,8 +285,7 @@ extern int emacs_setenv_TZ (char const *); | |||
| 278 | /* Attribute of functions whose code should not have addresses | 285 | /* Attribute of functions whose code should not have addresses |
| 279 | sanitized. */ | 286 | sanitized. */ |
| 280 | 287 | ||
| 281 | #if (__has_attribute (no_sanitize_address) \ | 288 | #if __has_attribute (no_sanitize_address) |
| 282 | || 4 < __GNUC__ + (8 <= __GNUC_MINOR__)) | ||
| 283 | # define ATTRIBUTE_NO_SANITIZE_ADDRESS \ | 289 | # define ATTRIBUTE_NO_SANITIZE_ADDRESS \ |
| 284 | __attribute__ ((no_sanitize_address)) ADDRESS_SANITIZER_WORKAROUND | 290 | __attribute__ ((no_sanitize_address)) ADDRESS_SANITIZER_WORKAROUND |
| 285 | #elif __has_attribute (no_address_safety_analysis) | 291 | #elif __has_attribute (no_address_safety_analysis) |
diff --git a/src/emacs-module.c b/src/emacs-module.c index b5e044e758f..79a077b3cb4 100644 --- a/src/emacs-module.c +++ b/src/emacs-module.c | |||
| @@ -35,8 +35,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 35 | 35 | ||
| 36 | /* Feature tests. */ | 36 | /* Feature tests. */ |
| 37 | 37 | ||
| 38 | /* True if __attribute__ ((cleanup (...))) works, false otherwise. */ | 38 | #if __has_attribute (cleanup) |
| 39 | #ifdef HAVE_VAR_ATTRIBUTE_CLEANUP | ||
| 40 | enum { module_has_cleanup = true }; | 39 | enum { module_has_cleanup = true }; |
| 41 | #else | 40 | #else |
| 42 | enum { module_has_cleanup = false }; | 41 | enum { module_has_cleanup = false }; |
| @@ -50,7 +50,8 @@ All integers representable in Lisp, i.e. between `most-negative-fixnum' | |||
| 50 | and `most-positive-fixnum', inclusive, are equally likely. | 50 | and `most-positive-fixnum', inclusive, are equally likely. |
| 51 | 51 | ||
| 52 | With positive integer LIMIT, return random number in interval [0,LIMIT). | 52 | With positive integer LIMIT, return random number in interval [0,LIMIT). |
| 53 | With argument t, set the random number seed from the current time and pid. | 53 | With argument t, set the random number seed from the system's entropy |
| 54 | pool if available, otherwise from less-random volatile data such as the time. | ||
| 54 | With a string argument, set the seed based on the string's contents. | 55 | With a string argument, set the seed based on the string's contents. |
| 55 | Other values of LIMIT are ignored. | 56 | Other values of LIMIT are ignored. |
| 56 | 57 | ||
diff --git a/src/gnutls.c b/src/gnutls.c index a1d058fcd48..01a5983d3b0 100644 --- a/src/gnutls.c +++ b/src/gnutls.c | |||
| @@ -1112,15 +1112,17 @@ The return value is a property list with top-level keys :warnings and | |||
| 1112 | /* Initialize global GnuTLS state to defaults. | 1112 | /* Initialize global GnuTLS state to defaults. |
| 1113 | Call `gnutls-global-deinit' when GnuTLS usage is no longer needed. | 1113 | Call `gnutls-global-deinit' when GnuTLS usage is no longer needed. |
| 1114 | Return zero on success. */ | 1114 | Return zero on success. */ |
| 1115 | static Lisp_Object | 1115 | Lisp_Object |
| 1116 | emacs_gnutls_global_init (void) | 1116 | emacs_gnutls_global_init (void) |
| 1117 | { | 1117 | { |
| 1118 | int ret = GNUTLS_E_SUCCESS; | 1118 | int ret = GNUTLS_E_SUCCESS; |
| 1119 | 1119 | ||
| 1120 | if (!gnutls_global_initialized) | 1120 | if (!gnutls_global_initialized) |
| 1121 | ret = gnutls_global_init (); | 1121 | { |
| 1122 | 1122 | ret = gnutls_global_init (); | |
| 1123 | gnutls_global_initialized = 1; | 1123 | if (ret == GNUTLS_E_SUCCESS) |
| 1124 | gnutls_global_initialized = 1; | ||
| 1125 | } | ||
| 1124 | 1126 | ||
| 1125 | return gnutls_make_error (ret); | 1127 | return gnutls_make_error (ret); |
| 1126 | } | 1128 | } |
diff --git a/src/gnutls.h b/src/gnutls.h index c4fe738bfa0..8e879c168bd 100644 --- a/src/gnutls.h +++ b/src/gnutls.h | |||
| @@ -83,6 +83,7 @@ extern ptrdiff_t emacs_gnutls_record_check_pending (gnutls_session_t state); | |||
| 83 | extern void emacs_gnutls_transport_set_errno (gnutls_session_t state, int err); | 83 | extern void emacs_gnutls_transport_set_errno (gnutls_session_t state, int err); |
| 84 | #endif | 84 | #endif |
| 85 | extern Lisp_Object emacs_gnutls_deinit (Lisp_Object); | 85 | extern Lisp_Object emacs_gnutls_deinit (Lisp_Object); |
| 86 | extern Lisp_Object emacs_gnutls_global_init (void); | ||
| 86 | 87 | ||
| 87 | #endif | 88 | #endif |
| 88 | 89 | ||
diff --git a/src/sysdep.c b/src/sysdep.c index e73acec733e..a86b53642f2 100644 --- a/src/sysdep.c +++ b/src/sysdep.c | |||
| @@ -99,6 +99,14 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 99 | #include "process.h" | 99 | #include "process.h" |
| 100 | #include "cm.h" | 100 | #include "cm.h" |
| 101 | 101 | ||
| 102 | #include "gnutls.h" | ||
| 103 | #if 0x020c00 <= GNUTLS_VERSION_NUMBER && !defined WINDOWSNT | ||
| 104 | # include <gnutls/crypto.h> | ||
| 105 | #else | ||
| 106 | # define emacs_gnutls_global_init() Qnil | ||
| 107 | # define gnutls_rnd(level, data, len) (-1) | ||
| 108 | #endif | ||
| 109 | |||
| 102 | #ifdef WINDOWSNT | 110 | #ifdef WINDOWSNT |
| 103 | #include <direct.h> | 111 | #include <direct.h> |
| 104 | /* In process.h which conflicts with the local copy. */ | 112 | /* In process.h which conflicts with the local copy. */ |
| @@ -2071,36 +2079,56 @@ init_signals (bool dumping) | |||
| 2071 | # endif /* !HAVE_RANDOM */ | 2079 | # endif /* !HAVE_RANDOM */ |
| 2072 | #endif /* !RAND_BITS */ | 2080 | #endif /* !RAND_BITS */ |
| 2073 | 2081 | ||
| 2082 | #ifdef HAVE_RANDOM | ||
| 2083 | typedef unsigned int random_seed; | ||
| 2084 | static void set_random_seed (random_seed arg) { srandom (arg); } | ||
| 2085 | #elif defined HAVE_LRAND48 | ||
| 2086 | /* Although srand48 uses a long seed, this is unsigned long to avoid | ||
| 2087 | undefined behavior on signed integer overflow in init_random. */ | ||
| 2088 | typedef unsigned long int random_seed; | ||
| 2089 | static void set_random_seed (random_seed arg) { srand48 (arg); } | ||
| 2090 | #else | ||
| 2091 | typedef unsigned int random_seed; | ||
| 2092 | static void set_random_seed (random_seed arg) { srand (arg); } | ||
| 2093 | #endif | ||
| 2094 | |||
| 2074 | void | 2095 | void |
| 2075 | seed_random (void *seed, ptrdiff_t seed_size) | 2096 | seed_random (void *seed, ptrdiff_t seed_size) |
| 2076 | { | 2097 | { |
| 2077 | #if defined HAVE_RANDOM || ! defined HAVE_LRAND48 | 2098 | random_seed arg = 0; |
| 2078 | unsigned int arg = 0; | ||
| 2079 | #else | ||
| 2080 | long int arg = 0; | ||
| 2081 | #endif | ||
| 2082 | unsigned char *argp = (unsigned char *) &arg; | 2099 | unsigned char *argp = (unsigned char *) &arg; |
| 2083 | unsigned char *seedp = seed; | 2100 | unsigned char *seedp = seed; |
| 2084 | ptrdiff_t i; | 2101 | for (ptrdiff_t i = 0; i < seed_size; i++) |
| 2085 | for (i = 0; i < seed_size; i++) | ||
| 2086 | argp[i % sizeof arg] ^= seedp[i]; | 2102 | argp[i % sizeof arg] ^= seedp[i]; |
| 2087 | #ifdef HAVE_RANDOM | 2103 | set_random_seed (arg); |
| 2088 | srandom (arg); | ||
| 2089 | #else | ||
| 2090 | # ifdef HAVE_LRAND48 | ||
| 2091 | srand48 (arg); | ||
| 2092 | # else | ||
| 2093 | srand (arg); | ||
| 2094 | # endif | ||
| 2095 | #endif | ||
| 2096 | } | 2104 | } |
| 2097 | 2105 | ||
| 2098 | void | 2106 | void |
| 2099 | init_random (void) | 2107 | init_random (void) |
| 2100 | { | 2108 | { |
| 2101 | struct timespec t = current_timespec (); | 2109 | random_seed v; |
| 2102 | uintmax_t v = getpid () ^ t.tv_sec ^ t.tv_nsec; | 2110 | if (! (EQ (emacs_gnutls_global_init (), Qt) |
| 2103 | seed_random (&v, sizeof v); | 2111 | && gnutls_rnd (GNUTLS_RND_NONCE, &v, sizeof v) == 0)) |
| 2112 | { | ||
| 2113 | bool success = false; | ||
| 2114 | #ifndef WINDOWSNT | ||
| 2115 | int fd = emacs_open ("/dev/urandom", O_RDONLY | O_BINARY, 0); | ||
| 2116 | if (0 <= fd) | ||
| 2117 | { | ||
| 2118 | success = emacs_read (fd, &v, sizeof v) == sizeof v; | ||
| 2119 | emacs_close (fd); | ||
| 2120 | } | ||
| 2121 | #else | ||
| 2122 | success = w32_init_random (&v, sizeof v) == 0; | ||
| 2123 | #endif | ||
| 2124 | if (! success) | ||
| 2125 | { | ||
| 2126 | /* Fall back to current time value + PID. */ | ||
| 2127 | struct timespec t = current_timespec (); | ||
| 2128 | v = getpid () ^ t.tv_sec ^ t.tv_nsec; | ||
| 2129 | } | ||
| 2130 | } | ||
| 2131 | set_random_seed (v); | ||
| 2104 | } | 2132 | } |
| 2105 | 2133 | ||
| 2106 | /* | 2134 | /* |
diff --git a/src/window.c b/src/window.c index bb414e7d311..4aeb8b39a70 100644 --- a/src/window.c +++ b/src/window.c | |||
| @@ -4979,27 +4979,34 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror) | |||
| 4979 | 4979 | ||
| 4980 | if (n > 0) | 4980 | if (n > 0) |
| 4981 | { | 4981 | { |
| 4982 | int last_y = it.last_visible_y - this_scroll_margin - 1; | ||
| 4983 | |||
| 4982 | /* We moved the window start towards ZV, so PT may be now | 4984 | /* We moved the window start towards ZV, so PT may be now |
| 4983 | in the scroll margin at the top. */ | 4985 | in the scroll margin at the top. */ |
| 4984 | move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS); | 4986 | move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS); |
| 4985 | if (IT_CHARPOS (it) == PT && it.current_y >= this_scroll_margin | 4987 | if (IT_CHARPOS (it) == PT |
| 4988 | && it.current_y >= this_scroll_margin | ||
| 4989 | && it.current_y <= last_y - WINDOW_HEADER_LINE_HEIGHT (w) | ||
| 4986 | && (NILP (Vscroll_preserve_screen_position) | 4990 | && (NILP (Vscroll_preserve_screen_position) |
| 4987 | || EQ (Vscroll_preserve_screen_position, Qt))) | 4991 | || EQ (Vscroll_preserve_screen_position, Qt))) |
| 4988 | /* We found PT at a legitimate height. Leave it alone. */ | 4992 | /* We found PT at a legitimate height. Leave it alone. */ |
| 4989 | ; | 4993 | ; |
| 4990 | else if (window_scroll_pixel_based_preserve_y >= 0) | ||
| 4991 | { | ||
| 4992 | /* If we have a header line, take account of it. | ||
| 4993 | This is necessary because we set it.current_y to 0, above. */ | ||
| 4994 | move_it_to (&it, -1, | ||
| 4995 | window_scroll_pixel_based_preserve_x, | ||
| 4996 | (window_scroll_pixel_based_preserve_y | ||
| 4997 | - WINDOW_WANTS_HEADER_LINE_P (w)), | ||
| 4998 | -1, MOVE_TO_Y | MOVE_TO_X); | ||
| 4999 | SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it)); | ||
| 5000 | } | ||
| 5001 | else | 4994 | else |
| 5002 | { | 4995 | { |
| 4996 | if (window_scroll_pixel_based_preserve_y >= 0) | ||
| 4997 | { | ||
| 4998 | /* Don't enter the scroll margin at the end of the window. */ | ||
| 4999 | int goal_y = min (last_y, window_scroll_pixel_based_preserve_y); | ||
| 5000 | |||
| 5001 | /* If we have a header line, take account of it. This | ||
| 5002 | is necessary because we set it.current_y to 0, above. */ | ||
| 5003 | move_it_to (&it, -1, | ||
| 5004 | window_scroll_pixel_based_preserve_x, | ||
| 5005 | goal_y - WINDOW_HEADER_LINE_HEIGHT (w), | ||
| 5006 | -1, MOVE_TO_Y | MOVE_TO_X); | ||
| 5007 | } | ||
| 5008 | |||
| 5009 | /* Get out of the scroll margin at the top of the window. */ | ||
| 5003 | while (it.current_y < this_scroll_margin) | 5010 | while (it.current_y < this_scroll_margin) |
| 5004 | { | 5011 | { |
| 5005 | int prev = it.current_y; | 5012 | int prev = it.current_y; |
| @@ -5023,7 +5030,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror) | |||
| 5023 | /* We moved the window start towards BEGV, so PT may be now | 5030 | /* We moved the window start towards BEGV, so PT may be now |
| 5024 | in the scroll margin at the bottom. */ | 5031 | in the scroll margin at the bottom. */ |
| 5025 | move_it_to (&it, PT, -1, | 5032 | move_it_to (&it, PT, -1, |
| 5026 | (it.last_visible_y - CURRENT_HEADER_LINE_HEIGHT (w) | 5033 | (it.last_visible_y - WINDOW_HEADER_LINE_HEIGHT (w) |
| 5027 | - this_scroll_margin - 1), | 5034 | - this_scroll_margin - 1), |
| 5028 | -1, | 5035 | -1, |
| 5029 | MOVE_TO_POS | MOVE_TO_Y); | 5036 | MOVE_TO_POS | MOVE_TO_Y); |
| @@ -5074,14 +5081,20 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror) | |||
| 5074 | ; | 5081 | ; |
| 5075 | else if (window_scroll_pixel_based_preserve_y >= 0) | 5082 | else if (window_scroll_pixel_based_preserve_y >= 0) |
| 5076 | { | 5083 | { |
| 5084 | int goal_y = min (it.last_visible_y - this_scroll_margin - 1, | ||
| 5085 | window_scroll_pixel_based_preserve_y); | ||
| 5086 | |||
| 5087 | /* Don't let the preserved screen Y coordinate put us inside | ||
| 5088 | any of the two margins. */ | ||
| 5089 | if (goal_y < this_scroll_margin) | ||
| 5090 | goal_y = this_scroll_margin; | ||
| 5077 | SET_TEXT_POS_FROM_MARKER (start, w->start); | 5091 | SET_TEXT_POS_FROM_MARKER (start, w->start); |
| 5078 | start_display (&it, w, start); | 5092 | start_display (&it, w, start); |
| 5079 | /* It would be wrong to subtract CURRENT_HEADER_LINE_HEIGHT | 5093 | /* It would be wrong to subtract CURRENT_HEADER_LINE_HEIGHT |
| 5080 | here because we called start_display again and did not | 5094 | here because we called start_display again and did not |
| 5081 | alter it.current_y this time. */ | 5095 | alter it.current_y this time. */ |
| 5082 | move_it_to (&it, -1, window_scroll_pixel_based_preserve_x, | 5096 | move_it_to (&it, -1, window_scroll_pixel_based_preserve_x, |
| 5083 | window_scroll_pixel_based_preserve_y, -1, | 5097 | goal_y, -1, MOVE_TO_Y | MOVE_TO_X); |
| 5084 | MOVE_TO_Y | MOVE_TO_X); | ||
| 5085 | SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it)); | 5098 | SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it)); |
| 5086 | } | 5099 | } |
| 5087 | else | 5100 | else |
| @@ -5197,6 +5210,7 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, bool noerror) | |||
| 5197 | w->force_start = true; | 5210 | w->force_start = true; |
| 5198 | 5211 | ||
| 5199 | if (!NILP (Vscroll_preserve_screen_position) | 5212 | if (!NILP (Vscroll_preserve_screen_position) |
| 5213 | && this_scroll_margin == 0 | ||
| 5200 | && (whole || !EQ (Vscroll_preserve_screen_position, Qt))) | 5214 | && (whole || !EQ (Vscroll_preserve_screen_position, Qt))) |
| 5201 | { | 5215 | { |
| 5202 | SET_PT_BOTH (pos, pos_byte); | 5216 | SET_PT_BOTH (pos, pos_byte); |
| @@ -5222,8 +5236,16 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, bool noerror) | |||
| 5222 | marker_byte_position (opoint_marker)); | 5236 | marker_byte_position (opoint_marker)); |
| 5223 | else if (!NILP (Vscroll_preserve_screen_position)) | 5237 | else if (!NILP (Vscroll_preserve_screen_position)) |
| 5224 | { | 5238 | { |
| 5239 | int nlines = window_scroll_preserve_vpos; | ||
| 5240 | |||
| 5225 | SET_PT_BOTH (pos, pos_byte); | 5241 | SET_PT_BOTH (pos, pos_byte); |
| 5226 | Fvertical_motion (original_pos, window, Qnil); | 5242 | if (window_scroll_preserve_vpos < this_scroll_margin) |
| 5243 | nlines = this_scroll_margin; | ||
| 5244 | else if (window_scroll_preserve_vpos | ||
| 5245 | >= w->total_lines - this_scroll_margin) | ||
| 5246 | nlines = w->total_lines - this_scroll_margin - 1; | ||
| 5247 | Fvertical_motion (Fcons (make_number (window_scroll_preserve_hpos), | ||
| 5248 | make_number (nlines)), window, Qnil); | ||
| 5227 | } | 5249 | } |
| 5228 | else | 5250 | else |
| 5229 | SET_PT (top_margin); | 5251 | SET_PT (top_margin); |
| @@ -5249,8 +5271,16 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, bool noerror) | |||
| 5249 | { | 5271 | { |
| 5250 | if (!NILP (Vscroll_preserve_screen_position)) | 5272 | if (!NILP (Vscroll_preserve_screen_position)) |
| 5251 | { | 5273 | { |
| 5274 | int nlines = window_scroll_preserve_vpos; | ||
| 5275 | |||
| 5252 | SET_PT_BOTH (pos, pos_byte); | 5276 | SET_PT_BOTH (pos, pos_byte); |
| 5253 | Fvertical_motion (original_pos, window, Qnil); | 5277 | if (window_scroll_preserve_vpos < this_scroll_margin) |
| 5278 | nlines = this_scroll_margin; | ||
| 5279 | else if (window_scroll_preserve_vpos | ||
| 5280 | >= ht - this_scroll_margin) | ||
| 5281 | nlines = ht - this_scroll_margin - 1; | ||
| 5282 | Fvertical_motion (Fcons (make_number (window_scroll_preserve_hpos), | ||
| 5283 | make_number (nlines)), window, Qnil); | ||
| 5254 | } | 5284 | } |
| 5255 | else | 5285 | else |
| 5256 | Fvertical_motion (make_number (-1), window, Qnil); | 5286 | Fvertical_motion (make_number (-1), window, Qnil); |
diff --git a/test/manual/etags/CTAGS.good b/test/manual/etags/CTAGS.good index 245f6703adf..86b019a2b4c 100644 --- a/test/manual/etags/CTAGS.good +++ b/test/manual/etags/CTAGS.good | |||
| @@ -438,7 +438,7 @@ Cjava_entries c-src/etags.c /^Cjava_entries (FILE *inf)$/ | |||
| 438 | Cjava_help c-src/etags.c 551 | 438 | Cjava_help c-src/etags.c 551 |
| 439 | Cjava_suffixes c-src/etags.c 549 | 439 | Cjava_suffixes c-src/etags.c 549 |
| 440 | ClassExample ruby-src/test.rb /^ class ClassExample$/ | 440 | ClassExample ruby-src/test.rb /^ class ClassExample$/ |
| 441 | ClassExample.singleton_class_method ruby-src/test.rb /^ def ClassExample.singleton_class_method$/ | 441 | ClassExample.class_method ruby-src/test.rb /^ def ClassExample.class_method$/ |
| 442 | Clear/p ada-src/2ataspri.adb /^ procedure Clear (Cell : in out TAS_Cell) is$/ | 442 | Clear/p ada-src/2ataspri.adb /^ procedure Clear (Cell : in out TAS_Cell) is$/ |
| 443 | Clear/p ada-src/2ataspri.ads /^ procedure Clear (Cell : in out TAS_Cell)/ | 443 | Clear/p ada-src/2ataspri.ads /^ procedure Clear (Cell : in out TAS_Cell)/ |
| 444 | Cobol_help c-src/etags.c 558 | 444 | Cobol_help c-src/etags.c 558 |
| @@ -939,7 +939,7 @@ Metags c-src/etags.c /^main (int argc, char **argv)$/ | |||
| 939 | Mfail cp-src/fail.C /^main()$/ | 939 | Mfail cp-src/fail.C /^main()$/ |
| 940 | Mkai-test.pl perl-src/kai-test.pl /^package main;$/ | 940 | Mkai-test.pl perl-src/kai-test.pl /^package main;$/ |
| 941 | ModuleExample ruby-src/test.rb /^module ModuleExample$/ | 941 | ModuleExample ruby-src/test.rb /^module ModuleExample$/ |
| 942 | ModuleExample.singleton_module_method ruby-src/test.rb /^ def ModuleExample.singleton_module_method$/ | 942 | ModuleExample.module_class_method ruby-src/test.rb /^ def ModuleExample.module_class_method$/ |
| 943 | More_Lisp_Bits c-src/emacs/src/lisp.h 801 | 943 | More_Lisp_Bits c-src/emacs/src/lisp.h 801 |
| 944 | MoveLayerAfter lua-src/allegro.lua /^function MoveLayerAfter (this_one)$/ | 944 | MoveLayerAfter lua-src/allegro.lua /^function MoveLayerAfter (this_one)$/ |
| 945 | MoveLayerBefore lua-src/allegro.lua /^function MoveLayerBefore (this_one)$/ | 945 | MoveLayerBefore lua-src/allegro.lua /^function MoveLayerBefore (this_one)$/ |
| @@ -2620,10 +2620,10 @@ childDidExit objc-src/Subprocess.m /^- childDidExit$/ | |||
| 2620 | chunks_free c-src/emacs/src/gmalloc.c 313 | 2620 | chunks_free c-src/emacs/src/gmalloc.c 313 |
| 2621 | chunks_used c-src/emacs/src/gmalloc.c 311 | 2621 | chunks_used c-src/emacs/src/gmalloc.c 311 |
| 2622 | cjava c-src/etags.c 2936 | 2622 | cjava c-src/etags.c 2936 |
| 2623 | class_method ruby-src/test.rb /^ def class_method$/ | 2623 | instance_method ruby-src/test.rb /^ def instance_method$/ |
| 2624 | class_method_equals= ruby-src/test.rb /^ def class_method_equals=$/ | 2624 | instance_method_equals= ruby-src/test.rb /^ def instance_method_equals=$/ |
| 2625 | class_method_exclamation! ruby-src/test.rb /^ def class_method_exclamation!$/ | 2625 | instance_method_exclamation! ruby-src/test.rb /^ def instance_method_exclamation!$/ |
| 2626 | class_method_question? ruby-src/test.rb /^ def class_method_question?$/ | 2626 | instance_method_question? ruby-src/test.rb /^ def instance_method_question?$/ |
| 2627 | classifyLine php-src/lce_functions.php /^ function classifyLine($line)$/ | 2627 | classifyLine php-src/lce_functions.php /^ function classifyLine($line)$/ |
| 2628 | clear cp-src/conway.hpp /^ void clear(void) { alive = 0; }$/ | 2628 | clear cp-src/conway.hpp /^ void clear(void) { alive = 0; }$/ |
| 2629 | clear-abbrev-table c-src/abbrev.c /^DEFUN ("clear-abbrev-table", Fclear_abbrev_table, / | 2629 | clear-abbrev-table c-src/abbrev.c /^DEFUN ("clear-abbrev-table", Fclear_abbrev_table, / |
| @@ -3450,7 +3450,7 @@ miti html-src/softwarelibero.html /^Sfatiamo alcuni miti$/ | |||
| 3450 | modifier_names c-src/emacs/src/keyboard.c 6319 | 3450 | modifier_names c-src/emacs/src/keyboard.c 6319 |
| 3451 | modifier_symbols c-src/emacs/src/keyboard.c 6327 | 3451 | modifier_symbols c-src/emacs/src/keyboard.c 6327 |
| 3452 | modify_event_symbol c-src/emacs/src/keyboard.c /^modify_event_symbol (ptrdiff_t symbol_num, int mod/ | 3452 | modify_event_symbol c-src/emacs/src/keyboard.c /^modify_event_symbol (ptrdiff_t symbol_num, int mod/ |
| 3453 | module_method ruby-src/test.rb /^ def module_method$/ | 3453 | module_instance_method ruby-src/test.rb /^ def module_instance_method$/ |
| 3454 | more_aligned_int c.c 165 | 3454 | more_aligned_int c.c 165 |
| 3455 | morecore_nolock c-src/emacs/src/gmalloc.c /^morecore_nolock (size_t size)$/ | 3455 | morecore_nolock c-src/emacs/src/gmalloc.c /^morecore_nolock (size_t size)$/ |
| 3456 | morecore_recursing c-src/emacs/src/gmalloc.c 604 | 3456 | morecore_recursing c-src/emacs/src/gmalloc.c 604 |
diff --git a/test/manual/etags/ETAGS.good_1 b/test/manual/etags/ETAGS.good_1 index 2ae4ec41256..dac20910347 100644 --- a/test/manual/etags/ETAGS.good_1 +++ b/test/manual/etags/ETAGS.good_1 | |||
| @@ -2980,11 +2980,11 @@ class Configure(760,24879 | |||
| 2980 | ruby-src/test.rb,594 | 2980 | ruby-src/test.rb,594 |
| 2981 | module ModuleExample1,0 | 2981 | module ModuleExample1,0 |
| 2982 | class ClassExample2,21 | 2982 | class ClassExample2,21 |
| 2983 | def class_method3,44 | 2983 | def instance_method3,44 |
| 2984 | def ClassExample.singleton_class_method6,116 | 2984 | def ClassExample.class_method6,116 |
| 2985 | def class_method_exclamation!9,221 | 2985 | def instance_method_exclamation!9,221 |
| 2986 | def class_method_question?12,319 | 2986 | def instance_method_question?12,319 |
| 2987 | def class_method_equals=class_method_equals=15,411 | 2987 | def instance_method_equals=class_method_equals=15,411 |
| 2988 | def `(18,499 | 2988 | def `(18,499 |
| 2989 | def +(21,589 | 2989 | def +(21,589 |
| 2990 | def [](24,637 | 2990 | def [](24,637 |
| @@ -2994,8 +2994,8 @@ module ModuleExample1,0 | |||
| 2994 | def <=(<=36,869 | 2994 | def <=(<=36,869 |
| 2995 | def <=>(<=>39,940 | 2995 | def <=>(<=>39,940 |
| 2996 | def ===(===42,987 | 2996 | def ===(===42,987 |
| 2997 | def module_method46,1048 | 2997 | def module_instance_method46,1048 |
| 2998 | def ModuleExample.singleton_module_method49,1110 | 2998 | def ModuleExample.module_class_method49,1110 |
| 2999 | 2999 | ||
| 3000 | ruby-src/test1.ruby,37 | 3000 | ruby-src/test1.ruby,37 |
| 3001 | class A1,0 | 3001 | class A1,0 |
diff --git a/test/manual/etags/ETAGS.good_2 b/test/manual/etags/ETAGS.good_2 index 3ec5b21d384..e5dbefbbd0d 100644 --- a/test/manual/etags/ETAGS.good_2 +++ b/test/manual/etags/ETAGS.good_2 | |||
| @@ -3551,11 +3551,11 @@ class Configure(760,24879 | |||
| 3551 | ruby-src/test.rb,594 | 3551 | ruby-src/test.rb,594 |
| 3552 | module ModuleExample1,0 | 3552 | module ModuleExample1,0 |
| 3553 | class ClassExample2,21 | 3553 | class ClassExample2,21 |
| 3554 | def class_method3,44 | 3554 | def instance_method3,44 |
| 3555 | def ClassExample.singleton_class_method6,116 | 3555 | def ClassExample.class_method6,116 |
| 3556 | def class_method_exclamation!9,221 | 3556 | def instance_method_exclamation!9,221 |
| 3557 | def class_method_question?12,319 | 3557 | def instance_method_question?12,319 |
| 3558 | def class_method_equals=class_method_equals=15,411 | 3558 | def instance_method_equals=class_method_equals=15,411 |
| 3559 | def `(18,499 | 3559 | def `(18,499 |
| 3560 | def +(21,589 | 3560 | def +(21,589 |
| 3561 | def [](24,637 | 3561 | def [](24,637 |
| @@ -3565,8 +3565,8 @@ module ModuleExample1,0 | |||
| 3565 | def <=(<=36,869 | 3565 | def <=(<=36,869 |
| 3566 | def <=>(<=>39,940 | 3566 | def <=>(<=>39,940 |
| 3567 | def ===(===42,987 | 3567 | def ===(===42,987 |
| 3568 | def module_method46,1048 | 3568 | def module_instance_method46,1048 |
| 3569 | def ModuleExample.singleton_module_method49,1110 | 3569 | def ModuleExample.module_class_method49,1110 |
| 3570 | 3570 | ||
| 3571 | ruby-src/test1.ruby,37 | 3571 | ruby-src/test1.ruby,37 |
| 3572 | class A1,0 | 3572 | class A1,0 |
diff --git a/test/manual/etags/ETAGS.good_3 b/test/manual/etags/ETAGS.good_3 index 43b84eed5d2..804440aad6d 100644 --- a/test/manual/etags/ETAGS.good_3 +++ b/test/manual/etags/ETAGS.good_3 | |||
| @@ -3324,11 +3324,11 @@ class Configure(760,24879 | |||
| 3324 | ruby-src/test.rb,594 | 3324 | ruby-src/test.rb,594 |
| 3325 | module ModuleExample1,0 | 3325 | module ModuleExample1,0 |
| 3326 | class ClassExample2,21 | 3326 | class ClassExample2,21 |
| 3327 | def class_method3,44 | 3327 | def instance_method3,44 |
| 3328 | def ClassExample.singleton_class_method6,116 | 3328 | def ClassExample.class_method6,116 |
| 3329 | def class_method_exclamation!9,221 | 3329 | def instance_method_exclamation!9,221 |
| 3330 | def class_method_question?12,319 | 3330 | def instance_method_question?12,319 |
| 3331 | def class_method_equals=class_method_equals=15,411 | 3331 | def instance_method_equals=class_method_equals=15,411 |
| 3332 | def `(18,499 | 3332 | def `(18,499 |
| 3333 | def +(21,589 | 3333 | def +(21,589 |
| 3334 | def [](24,637 | 3334 | def [](24,637 |
| @@ -3338,8 +3338,8 @@ module ModuleExample1,0 | |||
| 3338 | def <=(<=36,869 | 3338 | def <=(<=36,869 |
| 3339 | def <=>(<=>39,940 | 3339 | def <=>(<=>39,940 |
| 3340 | def ===(===42,987 | 3340 | def ===(===42,987 |
| 3341 | def module_method46,1048 | 3341 | def module_instance_method46,1048 |
| 3342 | def ModuleExample.singleton_module_method49,1110 | 3342 | def ModuleExample.module_class_method49,1110 |
| 3343 | 3343 | ||
| 3344 | ruby-src/test1.ruby,37 | 3344 | ruby-src/test1.ruby,37 |
| 3345 | class A1,0 | 3345 | class A1,0 |
diff --git a/test/manual/etags/ETAGS.good_4 b/test/manual/etags/ETAGS.good_4 index 434fe13cbd4..3b904ebe37c 100644 --- a/test/manual/etags/ETAGS.good_4 +++ b/test/manual/etags/ETAGS.good_4 | |||
| @@ -3144,11 +3144,11 @@ class Configure(760,24879 | |||
| 3144 | ruby-src/test.rb,594 | 3144 | ruby-src/test.rb,594 |
| 3145 | module ModuleExample1,0 | 3145 | module ModuleExample1,0 |
| 3146 | class ClassExample2,21 | 3146 | class ClassExample2,21 |
| 3147 | def class_method3,44 | 3147 | def instance_method3,44 |
| 3148 | def ClassExample.singleton_class_method6,116 | 3148 | def ClassExample.class_method6,116 |
| 3149 | def class_method_exclamation!9,221 | 3149 | def instance_method_exclamation!9,221 |
| 3150 | def class_method_question?12,319 | 3150 | def instance_method_question?12,319 |
| 3151 | def class_method_equals=class_method_equals=15,411 | 3151 | def instance_method_equals=class_method_equals=15,411 |
| 3152 | def `(18,499 | 3152 | def `(18,499 |
| 3153 | def +(21,589 | 3153 | def +(21,589 |
| 3154 | def [](24,637 | 3154 | def [](24,637 |
| @@ -3158,8 +3158,8 @@ module ModuleExample1,0 | |||
| 3158 | def <=(<=36,869 | 3158 | def <=(<=36,869 |
| 3159 | def <=>(<=>39,940 | 3159 | def <=>(<=>39,940 |
| 3160 | def ===(===42,987 | 3160 | def ===(===42,987 |
| 3161 | def module_method46,1048 | 3161 | def module_instance_method46,1048 |
| 3162 | def ModuleExample.singleton_module_method49,1110 | 3162 | def ModuleExample.module_class_method49,1110 |
| 3163 | 3163 | ||
| 3164 | ruby-src/test1.ruby,37 | 3164 | ruby-src/test1.ruby,37 |
| 3165 | class A1,0 | 3165 | class A1,0 |
diff --git a/test/manual/etags/ETAGS.good_5 b/test/manual/etags/ETAGS.good_5 index 425e2526f35..c3a277829f0 100644 --- a/test/manual/etags/ETAGS.good_5 +++ b/test/manual/etags/ETAGS.good_5 | |||
| @@ -4059,11 +4059,11 @@ class Configure(760,24879 | |||
| 4059 | ruby-src/test.rb,594 | 4059 | ruby-src/test.rb,594 |
| 4060 | module ModuleExample1,0 | 4060 | module ModuleExample1,0 |
| 4061 | class ClassExample2,21 | 4061 | class ClassExample2,21 |
| 4062 | def class_method3,44 | 4062 | def instance_method3,44 |
| 4063 | def ClassExample.singleton_class_method6,116 | 4063 | def ClassExample.class_method6,116 |
| 4064 | def class_method_exclamation!9,221 | 4064 | def instance_method_exclamation!9,221 |
| 4065 | def class_method_question?12,319 | 4065 | def instance_method_question?12,319 |
| 4066 | def class_method_equals=class_method_equals=15,411 | 4066 | def instance_method_equals=class_method_equals=15,411 |
| 4067 | def `(18,499 | 4067 | def `(18,499 |
| 4068 | def +(21,589 | 4068 | def +(21,589 |
| 4069 | def [](24,637 | 4069 | def [](24,637 |
| @@ -4073,8 +4073,8 @@ module ModuleExample1,0 | |||
| 4073 | def <=(<=36,869 | 4073 | def <=(<=36,869 |
| 4074 | def <=>(<=>39,940 | 4074 | def <=>(<=>39,940 |
| 4075 | def ===(===42,987 | 4075 | def ===(===42,987 |
| 4076 | def module_method46,1048 | 4076 | def module_instance_method46,1048 |
| 4077 | def ModuleExample.singleton_module_method49,1110 | 4077 | def ModuleExample.module_class_method49,1110 |
| 4078 | 4078 | ||
| 4079 | ruby-src/test1.ruby,37 | 4079 | ruby-src/test1.ruby,37 |
| 4080 | class A1,0 | 4080 | class A1,0 |
diff --git a/test/manual/etags/ETAGS.good_6 b/test/manual/etags/ETAGS.good_6 index 39522dbdb9b..2014283a89c 100644 --- a/test/manual/etags/ETAGS.good_6 +++ b/test/manual/etags/ETAGS.good_6 | |||
| @@ -4059,11 +4059,11 @@ class Configure(760,24879 | |||
| 4059 | ruby-src/test.rb,594 | 4059 | ruby-src/test.rb,594 |
| 4060 | module ModuleExample1,0 | 4060 | module ModuleExample1,0 |
| 4061 | class ClassExample2,21 | 4061 | class ClassExample2,21 |
| 4062 | def class_method3,44 | 4062 | def instance_method3,44 |
| 4063 | def ClassExample.singleton_class_method6,116 | 4063 | def ClassExample.class_method6,116 |
| 4064 | def class_method_exclamation!9,221 | 4064 | def instance_method_exclamation!9,221 |
| 4065 | def class_method_question?12,319 | 4065 | def instance_method_question?12,319 |
| 4066 | def class_method_equals=class_method_equals=15,411 | 4066 | def instance_method_equals=class_method_equals=15,411 |
| 4067 | def `(18,499 | 4067 | def `(18,499 |
| 4068 | def +(21,589 | 4068 | def +(21,589 |
| 4069 | def [](24,637 | 4069 | def [](24,637 |
| @@ -4073,8 +4073,8 @@ module ModuleExample1,0 | |||
| 4073 | def <=(<=36,869 | 4073 | def <=(<=36,869 |
| 4074 | def <=>(<=>39,940 | 4074 | def <=>(<=>39,940 |
| 4075 | def ===(===42,987 | 4075 | def ===(===42,987 |
| 4076 | def module_method46,1048 | 4076 | def module_instance_method46,1048 |
| 4077 | def ModuleExample.singleton_module_method49,1110 | 4077 | def ModuleExample.module_class_method49,1110 |
| 4078 | 4078 | ||
| 4079 | ruby-src/test1.ruby,37 | 4079 | ruby-src/test1.ruby,37 |
| 4080 | class A1,0 | 4080 | class A1,0 |
diff --git a/test/manual/etags/ruby-src/test.rb b/test/manual/etags/ruby-src/test.rb index 9254c5bffa9..adb2cb1d0bc 100644 --- a/test/manual/etags/ruby-src/test.rb +++ b/test/manual/etags/ruby-src/test.rb | |||
| @@ -1,19 +1,19 @@ | |||
| 1 | module ModuleExample | 1 | module ModuleExample |
| 2 | class ClassExample | 2 | class ClassExample |
| 3 | def class_method | 3 | def instance_method |
| 4 | puts "in class_method" | 4 | puts "in instane_method" |
| 5 | end | 5 | end |
| 6 | def ClassExample.singleton_class_method | 6 | def ClassExample.class_method |
| 7 | puts "in singleton_class_method" | 7 | puts "in class_method" |
| 8 | end | 8 | end |
| 9 | def class_method_exclamation! | 9 | def instance_method_exclamation! |
| 10 | puts "in class_method_exclamation!" | 10 | puts "in instance_method_exclamation!" |
| 11 | end | 11 | end |
| 12 | def class_method_question? | 12 | def instance_method_question? |
| 13 | puts "in class_method_question?" | 13 | puts "in instance_method_question?" |
| 14 | end | 14 | end |
| 15 | def class_method_equals= | 15 | def instance_method_equals= |
| 16 | puts "in class_method_equals=" | 16 | puts "in instance_method_equals=" |
| 17 | end | 17 | end |
| 18 | def `(command) | 18 | def `(command) |
| 19 | return "just testing a backquote override" | 19 | return "just testing a backquote override" |
| @@ -43,12 +43,16 @@ module ModuleExample | |||
| 43 | self == y | 43 | self == y |
| 44 | end | 44 | end |
| 45 | end | 45 | end |
| 46 | def module_method | 46 | def module_instance_method |
| 47 | puts "in module_method" | 47 | puts "in module_instance_method" |
| 48 | end | 48 | end |
| 49 | def ModuleExample.singleton_module_method | 49 | def ModuleExample.module_class_method |
| 50 | puts "in singleton_module_method" | 50 | puts "in module_class_method" |
| 51 | end | 51 | end |
| 52 | end | 52 | end |
| 53 | 53 | ||
| 54 | ModuleExample::ClassExample.singleton_class_method | 54 | ModuleExample::ClassExample.class_method |
| 55 | |||
| 56 | # Local Variables: | ||
| 57 | # ruby-indent-level: 4 | ||
| 58 | # End: | ||