Merge emacs-26

This commit is contained in:
Stefan Monnier 2017-10-06 09:50:54 -04:00
commit 11f9cb522f
63 changed files with 31479 additions and 2206 deletions

28971
ChangeLog.3

File diff suppressed because it is too large Load diff

View file

@ -273,8 +273,10 @@ a POP3 server by default. Versions of the POP protocol older than
POP3 are not supported. While POP3 support is typically enabled, POP3 are not supported. While POP3 support is typically enabled,
whether Emacs actually uses POP3 is controlled by individual users; whether Emacs actually uses POP3 is controlled by individual users;
see the Rmail chapter of the Emacs manual. Unless --with-mailutils is see the Rmail chapter of the Emacs manual. Unless --with-mailutils is
in effect, it is a good idea to configure --without-pop so that users in effect, it is a good idea to configure without POP3 support so that
are less likely to inadvertently read email via insecure channels. users are less likely to inadvertently read email via insecure
channels. On native MS-Windows, --with-pop is the default; on other
platforms, --without-pop is the default.
For image support you may have to download, build, and install the For image support you may have to download, build, and install the
appropriate image support libraries for image types other than XBM and appropriate image support libraries for image types other than XBM and

View file

@ -1115,7 +1115,7 @@ ChangeLog:
./$(emacslog) -o $(CHANGELOG) -n $(CHANGELOG_HISTORY_INDEX_MAX) ./$(emacslog) -o $(CHANGELOG) -n $(CHANGELOG_HISTORY_INDEX_MAX)
# Check that we are in a good state for changing history. # Check that we are in a good state for changing history.
PREFERRED_BRANCH = master PREFERRED_BRANCH = emacs-26
preferred-branch-is-current: preferred-branch-is-current:
git branch | grep -q '^\* $(PREFERRED_BRANCH)$$' git branch | grep -q '^\* $(PREFERRED_BRANCH)$$'
unchanged-history-files: unchanged-history-files:

View file

@ -1,3 +1,4 @@
;;; authors.el --- utility for maintaining Emacs's AUTHORS file ;;; authors.el --- utility for maintaining Emacs's AUTHORS file
;; Copyright (C) 2000-2017 Free Software Foundation, Inc. ;; Copyright (C) 2000-2017 Free Software Foundation, Inc.
@ -391,7 +392,7 @@ Changes to files matching one of the regexps in this list are not listed.")
"vms" "mac" "url" "tree-widget" "vms" "mac" "url" "tree-widget"
"info/dir" "info/dir"
;; Not in gnulib anymore ;; Not in gnulib anymore
"lib/qset-acl.c" "lib/qcopy-acl.c" "lib/file-has-acl.c" "lib/qset-acl.c" "lib/qcopy-acl.c" "lib/file-has-acl.c" "lib/secure_getenv.c"
;; files from old MS Windows build procedures ;; files from old MS Windows build procedures
"nt/gnulib-modules-to-delete.cfg" "nt/gnulib-modules-to-delete.cfg"
"makefile.w32-in" "makefile.w32-in"
@ -736,6 +737,8 @@ Changes to files in this list are not listed.")
"org-exp-blocks.el" ; maybe this is ob-exp now? dunno "org-exp-blocks.el" ; maybe this is ob-exp now? dunno
"org-lparse.el" "org-lparse.el"
"org-special-blocks.el" "org-taskjuggler.el" "org-special-blocks.el" "org-taskjuggler.el"
"ob-sh.el"
"ob-scala.el"
"progmodes/cap-words.el" "progmodes/cap-words.el"
"w32-common-fns.el" "w32-common-fns.el"
;; gnus ;; gnus
@ -751,7 +754,7 @@ Changes to files in this list are not listed.")
"format-spec.el" "gnus-move.el" "gnus-sync.el" "format-spec.el" "gnus-move.el" "gnus-sync.el"
"auth-source.el" "ecomplete.el" "gravatar.el" "mailcap.el" "plstore.el" "auth-source.el" "ecomplete.el" "gravatar.el" "mailcap.el" "plstore.el"
"pop3.el" "qp.el" "registry.el" "rfc2231.el" "rtree.el" "pop3.el" "qp.el" "registry.el" "rfc2231.el" "rtree.el"
"sieve.el" "sieve-mode.el" "sieve.el" "sieve-mode.el" "gnus-ems.el"
;; doc ;; doc
"getopt.c" "texindex.c" "news.texi" "vc.texi" "vc2-xtra.texi" "getopt.c" "texindex.c" "news.texi" "vc.texi" "vc2-xtra.texi"
"back.texi" "vol1.texi" "vol2.texi" "elisp-covers.texi" "two.el" "back.texi" "vol1.texi" "vol2.texi" "elisp-covers.texi" "two.el"
@ -801,7 +804,12 @@ Changes to files in this list are not listed.")
"cedet-utests.el" "ede-tests.el" "semantic-ia-utest.el" "cedet-utests.el" "ede-tests.el" "semantic-ia-utest.el"
"semantic-tests.el" "semantic-utest-c.el" "semantic-utest.el" "semantic-tests.el" "semantic-utest-c.el" "semantic-utest.el"
"srecode-tests.el" "make-test-deps.emacs-lisp" "srecode-tests.el" "make-test-deps.emacs-lisp"
) "nxml-uchnm.el"
"decoder-tests.el"
"obsolete/scribe.el"
"cp51932.el"
"eucjp-ms.el"
"lisp.mk")
"File names which are valid, but no longer exist (or cannot be found) "File names which are valid, but no longer exist (or cannot be found)
in the repository.") in the repository.")
@ -906,6 +914,8 @@ in the repository.")
("patcomp.el" . "patcomp.el") ("patcomp.el" . "patcomp.el")
("emulation/ws-mode.el" . "ws-mode.el") ("emulation/ws-mode.el" . "ws-mode.el")
("vc/vc-arch.el" . "vc-arch.el") ("vc/vc-arch.el" . "vc-arch.el")
("lisp/gnus/messcompat.el" . "messcompat.el")
("html2text.el" . "html2text.el")
;; From lisp to etc/forms. ;; From lisp to etc/forms.
("forms-d2.el" . "forms-d2.el") ("forms-d2.el" . "forms-d2.el")
("forms-pass.el" . "forms-pass.el") ("forms-pass.el" . "forms-pass.el")
@ -950,9 +960,17 @@ in the repository.")
;; Moved from lisp/gnus/ to lisp/mail/ ;; Moved from lisp/gnus/ to lisp/mail/
("binhex.el" . "mail/binhex.el") ("binhex.el" . "mail/binhex.el")
("uudecode.el" . "mail/uudecode.el") ("uudecode.el" . "mail/uudecode.el")
("mail-parse.el" . "mail/mail-parse.el")
("yenc.el" . "mail/yenc.el")
("flow-fill.el" . "mail/flow-fill.el")
("ietf-drums.el" . "mail/ietf-drums.el")
("sieve-manage.el" . "mail/sieve-manage.el")
;; Moved from lisp/gnus/ to lisp/image/
("compface.el" . "image/compface.el")
;; Moved from lisp/gnus/ to lisp/net/ ;; Moved from lisp/gnus/ to lisp/net/
("imap.el" . "net/imap.el") ("imap.el" . "net/imap.el")
("rfc2104.el" . "net/rfc2104.el") ("rfc2104.el" . "net/rfc2104.el")
("starttls.el" . "net/starttls.el")
;; And from emacs/ to misc/ and back again. ;; And from emacs/ to misc/ and back again.
("ns-emacs.texi" . "macos.texi") ("ns-emacs.texi" . "macos.texi")
("overrides.texi" . "gnus-overrides.texi") ("overrides.texi" . "gnus-overrides.texi")
@ -993,6 +1011,7 @@ in the repository.")
("edt-user.doc" . "edt.texi") ("edt-user.doc" . "edt.texi")
("DEV-NOTES" . "nextstep") ("DEV-NOTES" . "nextstep")
("org/COPYRIGHT-AND-LICENSE" . "org/README") ("org/COPYRIGHT-AND-LICENSE" . "org/README")
("lisp/net/idna.el" . "puny.el")
;; Moved to different directories. ;; Moved to different directories.
("ctags.1" . "ctags.1") ("ctags.1" . "ctags.1")
("etags.1" . "etags.1") ("etags.1" . "etags.1")
@ -1021,6 +1040,8 @@ in the repository.")
;; module.* moved to emacs-module.* ;; module.* moved to emacs-module.*
("src/module.h" . "src/emacs-module.h") ("src/module.h" . "src/emacs-module.h")
("src/module.c" . "src/emacs-module.c") ("src/module.c" . "src/emacs-module.c")
;; gnulib
("lib/strftime.c" . "lib/nstrftime.c")
) )
"Alist of files which have been renamed during their lifetime. "Alist of files which have been renamed during their lifetime.
Elements are (OLDNAME . NEWNAME).") Elements are (OLDNAME . NEWNAME).")

View file

@ -232,9 +232,9 @@ AC_DEFUN([OPTION_DEFAULT_ON], [dnl
m4_bpatsubst([with_$1], [[^0-9a-z]], [_])=$with_features])dnl m4_bpatsubst([with_$1], [[^0-9a-z]], [_])=$with_features])dnl
])dnl ])dnl
# FIXME: The default options '--without-mailutils --with-pop' result # For retrieving mail, unencrypted network connections are the default
# in a movemail implementation that supports only unencrypted POP3 # only on native MS-Windows platforms. (FIXME: These platforms should
# connections. Encrypted connections should be the default. # also be secure by default.)
AC_ARG_WITH([mailutils], AC_ARG_WITH([mailutils],
[AS_HELP_STRING([--with-mailutils], [AS_HELP_STRING([--with-mailutils],
@ -251,9 +251,16 @@ if test "$with_mailutils" = no; then
fi fi
AC_SUBST([with_mailutils]) AC_SUBST([with_mailutils])
OPTION_DEFAULT_ON([pop], AC_ARG_WITH([pop],
[don't support POP mail retrieval with movemail (--without-pop or [AS_HELP_STRING([--with-pop],
--with-mailutils is recommended, as movemail POP is insecure)]) [Support POP mail retrieval if Emacs movemail is used (not recommended,
as Emacs movemail POP is insecure). This is the default only on
native MS-Windows.])],
[],
[case $host in
*-mingw*) with_pop=yes;;
*) with_pop=no-by-default;;
esac])
if test "$with_pop" = yes; then if test "$with_pop" = yes; then
AC_DEFINE(MAIL_USE_POP) AC_DEFINE(MAIL_USE_POP)
fi fi
@ -1313,7 +1320,7 @@ dnl For a long time, -znocombreloc was added to LDFLAGS rather than
dnl LD_SWITCH_SYSTEM_TEMACS. That is: dnl LD_SWITCH_SYSTEM_TEMACS. That is:
dnl * inappropriate, as LDFLAGS is a user option but this is essential. dnl * inappropriate, as LDFLAGS is a user option but this is essential.
dnl Eg "make LDFLAGS=... all" could run into problems, dnl Eg "make LDFLAGS=... all" could run into problems,
dnl http://bugs.debian.org/684788 dnl https://bugs.debian.org/684788
dnl * unnecessary, since temacs is the only thing that actually needs it. dnl * unnecessary, since temacs is the only thing that actually needs it.
dnl Indeed this is where it was originally, prior to: dnl Indeed this is where it was originally, prior to:
dnl https://lists.gnu.org/archive/html/emacs-pretest-bug/2004-03/msg00170.html dnl https://lists.gnu.org/archive/html/emacs-pretest-bug/2004-03/msg00170.html
@ -1392,10 +1399,6 @@ case "$opsys" in
# The resulting binary has a complete symbol table, and is better # The resulting binary has a complete symbol table, and is better
# for debugging and other observability tools (debuggers, pstack, etc). # for debugging and other observability tools (debuggers, pstack, etc).
# #
# If you encounter a problem using dldump(), please consider sending
# a message to the OpenSolaris tools-linking mailing list:
# http://mail.opensolaris.org/mailman/listinfo/tools-linking
#
# It is likely that dldump() works with older Solaris too, but this has # It is likely that dldump() works with older Solaris too, but this has
# not been tested, so for now this change is for Solaris 10 or newer. # not been tested, so for now this change is for Solaris 10 or newer.
UNEXEC_OBJ=unexsol.o UNEXEC_OBJ=unexsol.o
@ -2644,7 +2647,7 @@ if test x"$pkg_check_gtk" = xyes; then
closing open displays. This is no problem if you just use closing open displays. This is no problem if you just use
one display, but if you use more than one and close one of them one display, but if you use more than one and close one of them
Emacs may crash. Emacs may crash.
See http://bugzilla.gnome.org/show_bug.cgi?id=85715]]) See https://bugzilla.gnome.org/show_bug.cgi?id=85715]])
fi fi
fi fi
@ -4457,7 +4460,6 @@ emacs_broken_SIGIO=no
case $opsys in case $opsys in
dnl SIGIO exists, but the feature doesn't work in the way Emacs needs. dnl SIGIO exists, but the feature doesn't work in the way Emacs needs.
dnl See eg <http://article.gmane.org/gmane.os.openbsd.ports/46831>.
hpux* | nacl | openbsd | sol2* | unixware ) hpux* | nacl | openbsd | sol2* | unixware )
emacs_broken_SIGIO=yes emacs_broken_SIGIO=yes
;; ;;
@ -5568,6 +5570,12 @@ if test ! "$with_mailutils"; then
AC_MSG_WARN([This configuration installs a 'movemail' program AC_MSG_WARN([This configuration installs a 'movemail' program
that retrieves POP3 email via only insecure channels. that retrieves POP3 email via only insecure channels.
To omit insecure POP3, you can use '$0 --without-pop'.]) To omit insecure POP3, you can use '$0 --without-pop'.])
elif test "$with_pop" = no-by-default; then
AC_MSG_WARN([This configuration installs a 'movemail' program
that does not retrieve POP3 email. By default, Emacs 25 and earlier
installed a 'movemail' program that retrieved POP3 email via only
insecure channels, a practice that is no longer recommended but that
you can continue to support by using '$0 --with-pop'.])
fi fi
case $opsys in case $opsys in
@ -5579,7 +5587,7 @@ To omit insecure POP3, you can use '$0 --without-pop'.])
case `(movemail --version) 2>/dev/null` in case `(movemail --version) 2>/dev/null` in
*Mailutils*) ;; *Mailutils*) ;;
*) emacs_fix_movemail="install GNU Mailutils *) emacs_fix_movemail="install GNU Mailutils
<http://mailutils.org> and $emacs_fix_movemail";; <https://mailutils.org> and $emacs_fix_movemail";;
esac esac
AC_MSG_NOTICE([You might want to $emacs_fix_movemail.]);; AC_MSG_NOTICE([You might want to $emacs_fix_movemail.]);;
esac esac

View file

@ -812,15 +812,19 @@ formatting feature described here; they differ from @code{format-message} only
in how they use the result of formatting. in how they use the result of formatting.
@defun format string &rest objects @defun format string &rest objects
This function returns a new string that is made by copying This function returns a string equal to @var{string}, replacing any format
@var{string} and then replacing any format specification specifications with encodings of the corresponding @var{objects}. The
in the copy with encodings of the corresponding @var{objects}. The
arguments @var{objects} are the computed values to be formatted. arguments @var{objects} are the computed values to be formatted.
The characters in @var{string}, other than the format specifications, The characters in @var{string}, other than the format specifications,
are copied directly into the output, including their text properties, are copied directly into the output, including their text properties,
if any. Any text properties of the format specifications are copied if any. Any text properties of the format specifications are copied
to the produced string representations of the argument @var{objects}. to the produced string representations of the argument @var{objects}.
The output string need not be newly-allocated. For example, if
@code{x} is the string @code{"foo"}, the expressions @code{(eq x
(format x))} and @code{(eq x (format "%s" x))} might both yield
@code{t}.
@end defun @end defun
@defun format-message string &rest objects @defun format-message string &rest objects

View file

@ -4,7 +4,7 @@
@set VERSION 0.3 @set VERSION 0.3
@set UPDATED April 2004 @set UPDATED April 2004
@settitle GNU Flymake @value{VERSION} @settitle GNU Flymake @value{VERSION}
@include docstyle.texi @include ../emacs/docstyle.texi
@syncodeindex pg cp @syncodeindex pg cp
@comment %**end of header @comment %**end of header
@ -35,7 +35,7 @@ modify this GNU manual.''
@titlepage @titlepage
@title GNU Flymake @title GNU Flymake
@subtitle for version @value{VERSION}, @value{UPDATED} @subtitle for version @value{VERSION}, @value{UPDATED}
@author Pavel Kobiakov(@email{pk_at_work@@yahoo.com}) @author Pavel Kobiakov(@email{pk_at_work@@yahoo.com}) and João Távora.
@page @page
@vskip 0pt plus 1filll @vskip 0pt plus 1filll
@insertcopying @insertcopying
@ -53,8 +53,8 @@ modify this GNU manual.''
* Overview of Flymake:: * Overview of Flymake::
* Installing Flymake:: * Installing Flymake::
* Using Flymake:: * Using Flymake::
* Configuring Flymake:: * Extending Flymake::
* Flymake Implementation:: * The legacy Proc backend::
* GNU Free Documentation License:: * GNU Free Documentation License::
* Index:: * Index::
@end menu @end menu
@ -63,67 +63,56 @@ modify this GNU manual.''
@chapter Overview @chapter Overview
@cindex Overview of Flymake @cindex Overview of Flymake
Flymake is a universal on-the-fly syntax checker implemented as an Flymake is a universal on-the-fly buffer checker implemented as an
Emacs minor mode. Flymake runs the pre-configured syntax check tool Emacs minor mode. When enabled, Flymake visually annotates the buffer
(compiler for C++ files, @code{perl} for perl files, etc.)@: in the with diagnostic information coming from one or more different sources,
background, passing it a temporary copy of the current buffer, and or @emph{backends}.
parses the output for known error/warning message patterns. Flymake
then highlights erroneous lines (i.e., lines for which at least one
error or warning has been reported by the syntax check tool), and
displays an overall buffer status in the mode line. Status information
displayed by Flymake contains total number of errors and warnings
reported for the buffer during the last syntax check.
@code{flymake-goto-next-error} and @code{flymake-goto-prev-error} Historically, Flymake used to accept diagnostics from a single, albeit
functions allow for easy navigation to the next/previous erroneous reasonably flexible, backend.
line, respectively.
Calling @code{flymake-display-err-menu-for-current-line} will popup a This backend isn't (yet) obsolete and so is still available as a
menu containing error messages reported by the syntax check tool for fallback and active by default(@pxref{The legacy Proc backend}). It works by
the current line. Errors/warnings belonging to another file, such as a selecting a syntax check tool from a preconfigured list (compiler for
@code{.h} header file included by a @code{.c} file, are shown in the C++ files, @code{perl} for perl files, etc.), and executing it in the
current buffer as belonging to the first line. Menu items for such background, passing it a temporary file which is a copy of the current
messages also contain a filename and a line number. Selecting such a buffer, and parsing the output for known error/warning message
menu item will automatically open the file and jump to the line with patterns.
error.
Flymake annotates the buffer by highlighting problematic buffer
regions with a special space. It also displays an overall buffer
status in the mode line. Status information displayed by Flymake
contains totals for different types of diagnostics.
@code{flymake-goto-next-error} and @code{flymake-goto-prev-error} are
commands that allow easy navigation to the next/previous erroneous
line, respectively. If might be a good idea to map them to @kbd{M-n}
and @kbd{M-p} in @code{flymake-mode}, by adding to your init file:
@lisp
(define-key flymake-mode-map (kbd "M-n") 'flymake-goto-next-error)
(define-key flymake-mode-map (kbd "M-p") 'flymake-goto-prev-error)
@end lisp
Syntax check is done ``on-the-fly''. It is started whenever Syntax check is done ``on-the-fly''. It is started whenever
@itemize @bullet @itemize @bullet
@item buffer is loaded @item @code{flymake-mode} is started;
@item a newline character is added to the buffer @item a newline character is added to the buffer;
@item some changes were made to the buffer more than @code{0.5} seconds ago (the @item some changes were made to the buffer more than @code{0.5} seconds ago (the
delay is configurable). delay is configurable).
@end itemize @end itemize
Flymake is a universal syntax checker in the sense that it's easily Flymake is a universal syntax checker in the sense that it's easily
extended to support new syntax check tools and error message extended to support new backends. @xref{Customizable variables}.
patterns. @xref{Configuring Flymake}.
@node Installing Flymake @node Installing Flymake
@chapter Installing @chapter Installing
@cindex Installing Flymake @cindex Installing Flymake
Flymake is included with Emacs and its main commands, like
Flymake is packaged in a single file, @code{flymake.el}. @code{flymake-mode}, are autoloaded. This means there is usually
nothing to do by way of installation.
To install/update Flymake, place @code{flymake.el} to a directory
somewhere on Emacs load path. You might also want to byte-compile
@code{flymake.el} to improve performance.
Also, place the following line in the @code{.emacs} file.
@lisp
(require 'flymake)
@end lisp
You might also map the most frequently used Flymake functions, such as
@code{flymake-goto-next-error}, to some keyboard shortcuts:
@lisp
(global-set-key [f3] 'flymake-display-err-menu-for-current-line)
(global-set-key [f4] 'flymake-goto-next-error)
@end lisp
@node Using Flymake @node Using Flymake
@chapter Using Flymake @chapter Using Flymake
@ -132,10 +121,10 @@ You might also map the most frequently used Flymake functions, such as
@menu @menu
* Flymake mode:: * Flymake mode::
* Running the syntax check:: * Running the syntax check::
* Navigating to error lines:: * Navigating to error lines:: @c * Viewing error messages::
* Viewing error messages::
* Syntax check statuses:: * Syntax check statuses::
* Troubleshooting:: * Troubleshooting::
* Customizable variables::
@end menu @end menu
@node Flymake mode @node Flymake mode
@ -161,10 +150,8 @@ line in @code{.emacs}:
When @code{flymake-mode} is active, syntax check is started When @code{flymake-mode} is active, syntax check is started
automatically on any of the three conditions mentioned above. Syntax automatically on any of the three conditions mentioned above. Syntax
check can also be started manually by using the check can also be started manually by using the @code{flymake-start}
@code{flymake-start-syntax-check-for-current-buffer} function. This function.
can be used, for example, when changes were made to some other buffer
affecting the current buffer.
@node Navigating to error lines @node Navigating to error lines
@section Navigating to error lines @section Navigating to error lines
@ -185,69 +172,37 @@ navigate the highlighted lines.
@end multitable @end multitable
These functions treat erroneous lines as a linked list. Therefore, If the user option @code{flymake-wrap-around} is active
@code{flymake-goto-next-error} will go to the first erroneous line (@pxref{Customizable variables}), these functions treat diagnostics
when invoked in the end of the buffer. as a linked list. Therefore, @code{flymake-goto-next-error} will go
to the first diagnostic when invoked in the end of the buffer.
@node Viewing error messages
@section Viewing error messages
@cindex Viewing error messages
To view error messages belonging to the current line, use the
@code{flymake-display-err-menu-for-current-line} function. If there's
at least one error or warning reported for the current line, this
function will display a popup menu with error/warning texts.
Selecting the menu item whose error belongs to another file brings
forward that file with the help of the
@code{flymake-goto-file-and-line} function.
@node Syntax check statuses @node Syntax check statuses
@section Syntax check statuses @section Syntax check statuses
@cindex Syntax check statuses @cindex Syntax check statuses
After syntax check is finished, its status is displayed in the mode line. After syntax check is finished, its status is displayed in the mode line.
The following statuses are defined. The following statuses are defined:
@multitable @columnfractions 0.25 0.75 @multitable @columnfractions 0.25 0.75
@item Flymake* or Flymake:E/W* @item @code{Wait}
@tab Flymake is currently running. For the second case, E/W contains the @tab Some flymake backends haven't reported since the last time they
error and warning count for the previous run. where questioned.
@item Flymake @item @code{!}
@tab Syntax check is not running. Usually this means syntax check was @tab All the configured Flymake backends have disabled themselves.
successfully passed (no errors, no warnings). Other possibilities are: Left-clicking the ``Flymake'' mode line indicator beings the user
syntax check was killed as a result of executing @code{*Flymake log*} buffer where these situations may be investigated
@code{flymake-compile}, or syntax check cannot start as compilation
is currently in progress.
@item Flymake:E/W @item @code{?}
@tab Number of errors/warnings found by the syntax check process. @tab There are no configured Flymake backends in
@code{flymake-diagnostic-functions}.
@item Flymake:! @item @emph{[nerrors nwarnings]}
@tab Flymake was unable to find master file for the current buffer. @tab Normal operation, number of errors/warnings found by the syntax
check process.
@end multitable @end multitable
The following errors cause a warning message and switch flymake mode
OFF for the buffer.
@multitable @columnfractions 0.25 0.75
@item CFGERR
@tab Syntax check process returned nonzero exit code, but no
errors/warnings were reported. This indicates a possible configuration
error (for example, no suitable error message patterns for the
syntax check tool).
@item NOMASTER
@tab Flymake was unable to find master file for the current buffer.
@item NOMK
@tab Flymake was unable to find a suitable buildfile for the current buffer.
@item PROCERR
@tab Flymake was unable to launch a syntax check process.
@end multitable
@node Troubleshooting @node Troubleshooting
@section Troubleshooting @section Troubleshooting
@cindex Logging @cindex Logging
@ -255,70 +210,20 @@ syntax check tool).
Flymake uses a simple logging facility for indicating important points Flymake uses a simple logging facility for indicating important points
in the control flow. The logging facility sends logging messages to in the control flow. The logging facility sends logging messages to
the @file{*Messages*} buffer. The information logged can be used for the @file{*Flymake log*} buffer. The information logged can be used for
resolving various problems related to Flymake. resolving various problems related to Flymake.
Logging output is controlled by the @code{flymake-log-level} Logging output is controlled by the Emacs @code{warning-minimum-log-level}
variable. @code{3} is the most verbose level, and @code{-1} switches and @code{warning-minimum-level} variables.
logging off.
@node Configuring Flymake
@chapter Configuring and Extending Flymake
@cindex Configuring and Extending Flymake
@menu
* Customizable variables::
* Adding support for a new syntax check tool::
@end menu
Flymake was designed to be easily extended for supporting new syntax
check tools and error message patterns.
@node Customizable variables @node Customizable variables
@section Customizable variables @section Customizable variables
@cindex Customizable variables @cindex Customizable variables
This section summarizes variables used for Flymake This section summarizes variables used for the configuration of the
configuration. Flymake user interface.
@table @code @table @code
@item flymake-log-level
Controls logging output, see @ref{Troubleshooting}.
@item flymake-allowed-file-name-masks
A list of @code{(filename-regexp, init-function, cleanup-function
getfname-function)} for configuring syntax check tools. @xref{Adding
support for a new syntax check tool}.
@ignore
@item flymake-buildfile-dirs
A list of directories (relative paths) for searching a
buildfile. @xref{Locating the buildfile}.
@end ignore
@item flymake-master-file-dirs
A list of directories for searching a master file. @xref{Locating a
master file}.
@item flymake-get-project-include-dirs-function
A function used for obtaining a list of project include dirs (C/C++
specific). @xref{Getting the include directories}.
@item flymake-master-file-count-limit
@itemx flymake-check-file-limit
Used when looking for a master file. @xref{Locating a master file}.
@item flymake-err-line-patterns
Patterns for error/warning messages in the form @code{(regexp file-idx
line-idx col-idx err-text-idx)}. @xref{Parsing the output}.
@item flymake-warning-predicate
Predicate to classify error text as warning. @xref{Parsing the output}.
@item flymake-compilation-prevents-syntax-check
A flag indicating whether compilation and syntax check of the same
file cannot be run simultaneously.
@item flymake-no-changes-timeout @item flymake-no-changes-timeout
If any changes are made to the buffer, syntax check is automatically If any changes are made to the buffer, syntax check is automatically
started after @code{flymake-no-changes-timeout} seconds. started after @code{flymake-no-changes-timeout} seconds.
@ -327,13 +232,17 @@ started after @code{flymake-no-changes-timeout} seconds.
A boolean flag indicating whether to start syntax check after a A boolean flag indicating whether to start syntax check after a
newline character is added to the buffer. newline character is added to the buffer.
@item flymake-errline @item flymake-error
A custom face for highlighting lines for which at least one error has A custom face for highlighting regions for which an error has been
been reported. reported.
@item flymake-warnline @item flymake-warning
A custom face for highlighting lines for which at least one warning A custom face for highlighting regions for which a warning has been
and no errors have been reported. reported.
@item flymake-note
A custom face for highlighting regions for which a note has been
reported.
@item flymake-error-bitmap @item flymake-error-bitmap
A bitmap used in the fringe to mark lines for which an error has A bitmap used in the fringe to mark lines for which an error has
@ -346,6 +255,76 @@ been reported.
@item flymake-fringe-indicator-position @item flymake-fringe-indicator-position
Which fringe (if any) should show the warning/error bitmaps. Which fringe (if any) should show the warning/error bitmaps.
@item flymake-wrap-around
If non-nil, moving to errors with @code{flymake-goto-next-error} and
@code{flymake-goto-prev-error} wraps around buffer boundaries.
@end table
@node Extending Flymake
@chapter Extending Flymake
@cindex Extending Flymake
@node The legacy Proc backend
@chapter The legacy ``Proc'' backend
@cindex The legacy Proc backend
@menu
* Proc customization variables::
* Adding support for a new syntax check tool::
* Implementation overview::
* Making a temporary copy::
* Locating a master file::
* Getting the include directories::
* Locating the buildfile::
* Starting the syntax check process::
* Parsing the output::
* Interaction with other modes::
@end menu
The backend @code{flymake-proc-legacy-backend} was originally designed
to be extended for supporting new syntax check tools and error message
patterns. It is also controlled by its own set of customization variables
@node Proc customization variables
@section Customization variables for the Proc backend
@cindex Proc customization variables
@table @code
@item flymake-proc-allowed-file-name-masks
A list of @code{(filename-regexp, init-function, cleanup-function
getfname-function)} for configuring syntax check tools. @xref{Adding
support for a new syntax check tool}.
@item flymake-proc-master-file-dirs
A list of directories for searching a master file. @xref{Locating a
master file}.
@item flymake-proc-get-project-include-dirs-function
A function used for obtaining a list of project include dirs (C/C++
specific). @xref{Getting the include directories}.
@item flymake-proc-master-file-count-limit
@itemx flymake-proc-check-file-limit
Used when looking for a master file. @xref{Locating a master file}.
@item flymake-proc-err-line-patterns
Patterns for error/warning messages in the form @code{(regexp file-idx
line-idx col-idx err-text-idx)}. @xref{Parsing the output}.
@item flymake-proc-diagnostic-type-pred
A function to classify a diagnostic text as particular type of
error. Should be a function taking an error text and returning one of
the symbols indexing @code{flymake-diagnostic-types-alist}. If non-nil
is returned but there is no such symbol in that table, a warning is
assumed. If nil is returned, an error is assumed. Can also be a
regular expression that should match only warnings. This variable
replaces the old @code{flymake-warning-re} and
@code{flymake-warning-predicate}.
@item flymake-proc-compilation-prevents-syntax-check
A flag indicating whether compilation and syntax check of the same
file cannot be run simultaneously.
@end table @end table
@node Adding support for a new syntax check tool @node Adding support for a new syntax check tool
@ -358,7 +337,7 @@ Which fringe (if any) should show the warning/error bitmaps.
@end menu @end menu
Syntax check tools are configured using the Syntax check tools are configured using the
@code{flymake-allowed-file-name-masks} list. Each item of this list @code{flymake-proc-allowed-file-name-masks} list. Each item of this list
has the following format: has the following format:
@lisp @lisp
@ -369,15 +348,15 @@ has the following format:
@item filename-regexp @item filename-regexp
This field is used as a key for locating init/cleanup/getfname This field is used as a key for locating init/cleanup/getfname
functions for the buffer. Items in functions for the buffer. Items in
@code{flymake-allowed-file-name-masks} are searched sequentially. The @code{flymake-proc-allowed-file-name-masks} are searched sequentially.
first item with @code{filename-regexp} matching buffer filename is The first item with @code{filename-regexp} matching buffer filename is
selected. If no match is found, @code{flymake-mode} is switched off. selected. If no match is found, @code{flymake-mode} is switched off.
@item init-function @item init-function
@code{init-function} is required to initialize the syntax check, @code{init-function} is required to initialize the syntax check,
usually by creating a temporary copy of the buffer contents. The usually by creating a temporary copy of the buffer contents. The
function must return @code{(list cmd-name arg-list)}. If function must return @code{(list cmd-name arg-list)}. If
@code{init-function} returns null, syntax check is aborted, by @code{init-function} returns null, syntax check is aborted, but
@code{flymake-mode} is not switched off. @code{flymake-mode} is not switched off.
@item cleanup-function @item cleanup-function
@ -390,16 +369,16 @@ This function is used for translating filenames reported by the syntax
check tool into ``real'' filenames. Filenames reported by the tool check tool into ``real'' filenames. Filenames reported by the tool
will be different from the real ones, as actually the tool works with will be different from the real ones, as actually the tool works with
the temporary copy. In most cases, the default implementation the temporary copy. In most cases, the default implementation
provided by Flymake, @code{flymake-get-real-file-name}, can be used as provided by Flymake, @code{flymake-proc-get-real-file-name}, can be
@code{getfname-function}. used as @code{getfname-function}.
@end table @end table
To add support for a new syntax check tool, write corresponding To add support for a new syntax check tool, write corresponding
@code{init-function}, and, optionally @code{cleanup-function} and @code{init-function} and, optionally, @code{cleanup-function} and
@code{getfname-function}. If the format of error messages reported by @code{getfname-function}. If the format of error messages reported by
the new tool is not yet supported by Flymake, add a new entry to the new tool is not yet supported by Flymake, add a new entry to
the @code{flymake-err-line-patterns} list. the @code{flymake-proc-err-line-patterns} list.
The following sections contain some examples of configuring Flymake The following sections contain some examples of configuring Flymake
support for various syntax check tools. support for various syntax check tools.
@ -415,42 +394,42 @@ checking.
First, we write the @code{init-function}: First, we write the @code{init-function}:
@lisp @lisp
(defun flymake-perl-init () (defun flymake-proc-perl-init ()
(let* ((temp-file (flymake-init-create-temp-buffer-copy (let* ((temp-file (flymake-proc-init-create-temp-buffer-copy
'flymake-create-temp-inplace)) 'flymake-proc-create-temp-inplace))
(local-file (file-relative-name (local-file (file-relative-name
temp-file temp-file
(file-name-directory buffer-file-name)))) (file-name-directory buffer-file-name))))
(list "perl" (list "-wc " local-file)))) (list "perl" (list "-wc " local-file))))
@end lisp @end lisp
@code{flymake-perl-init} creates a temporary copy of the buffer @code{flymake-proc-perl-init} creates a temporary copy of the buffer
contents with the help of contents with the help of
@code{flymake-init-create-temp-buffer-copy}, and builds an appropriate @code{flymake-proc-init-create-temp-buffer-copy}, and builds an appropriate
command line. command line.
Next, we add a new entry to the Next, we add a new entry to the
@code{flymake-allowed-file-name-masks}: @code{flymake-proc-allowed-file-name-masks}:
@lisp @lisp
(setq flymake-allowed-file-name-masks (setq flymake-proc-allowed-file-name-masks
(cons '(".+\\.pl$" (cons '(".+\\.pl$"
flymake-perl-init flymake-proc-perl-init
flymake-simple-cleanup flymake-proc-simple-cleanup
flymake-get-real-file-name) flymake-proc-get-real-file-name)
flymake-allowed-file-name-masks)) flymake-proc-allowed-file-name-masks))
@end lisp @end lisp
Note that we use standard @code{cleanup-function} and Note that we use standard @code{cleanup-function} and
@code{getfname-function}. @code{getfname-function}.
Finally, we add an entry to @code{flymake-err-line-patterns}: Finally, we add an entry to @code{flymake-proc-err-line-patterns}:
@lisp @lisp
(setq flymake-err-line-patterns (setq flymake-proc-err-line-patterns
(cons '("\\(.*\\) at \\([^ \n]+\\) line \\([0-9]+\\)[,.\n]" (cons '("\\(.*\\) at \\([^ \n]+\\) line \\([0-9]+\\)[,.\n]"
2 3 nil 1) 2 3 nil 1)
flymake-err-line-patterns)) flymake-proc-err-line-patterns))
@end lisp @end lisp
@node Example---Configuring a tool called via make @node Example---Configuring a tool called via make
@ -462,18 +441,18 @@ In this example we will add support for C files syntax checked by
We're not required to write any new functions, as Flymake already has We're not required to write any new functions, as Flymake already has
functions for @command{make}. We just add a new entry to the functions for @command{make}. We just add a new entry to the
@code{flymake-allowed-file-name-masks}: @code{flymake-proc-allowed-file-name-masks}:
@lisp @lisp
(setq flymake-allowed-file-name-masks (setq flymake-proc-allowed-file-name-masks
(cons '(".+\\.c$" (cons '(".+\\.c$"
flymake-simple-make-init flymake-proc-simple-make-init
flymake-simple-cleanup flymake-proc-simple-cleanup
flymake-get-real-file-name) flymake-proc-get-real-file-name)
flymake-allowed-file-name-masks)) flymake-proc-allowed-file-name-masks))
@end lisp @end lisp
@code{flymake-simple-make-init} builds the following @command{make} @code{flymake-proc-simple-make-init} builds the following @command{make}
command line: command line:
@lisp @lisp
@ -492,7 +471,7 @@ our case this target might look like this:
@verbatim @verbatim
check-syntax: check-syntax:
gcc -o /dev/null -S ${CHK_SOURCES} gcc -o /dev/null -S ${CHK_SOURCES} || true
@end verbatim @end verbatim
@noindent @noindent
@ -504,42 +483,25 @@ Automake variable @code{COMPILE}:
@verbatim @verbatim
check-syntax: check-syntax:
$(COMPILE) -o /dev/null -S ${CHK_SOURCES} $(COMPILE) -o /dev/null -S ${CHK_SOURCES} || true
@end verbatim @end verbatim
@node Flymake Implementation @node Implementation overview
@chapter Flymake Implementation @section Implementation overview
@cindex Implementation details
@menu
* Determining whether syntax check is possible::
* Making a temporary copy::
* Locating a master file::
* Getting the include directories::
* Locating the buildfile::
* Starting the syntax check process::
* Parsing the output::
* Highlighting erroneous lines::
* Interaction with other modes::
@end menu
Syntax check is started by calling @code{flymake-start-syntax-check-for-current-buffer}.
Flymake first determines whether it is able to do syntax
check. It then saves a copy of the buffer in a temporary file in the
buffer's directory (or in the system temp directory, for java
files), creates a syntax check command and launches a process with
this command. The output is parsed using a list of error message patterns,
and error information (file name, line number, type and text) is
saved. After the process has finished, Flymake highlights erroneous
lines in the buffer using the accumulated error information.
@node Determining whether syntax check is possible
@section Determining whether syntax check is possible
@cindex Syntax check models @cindex Syntax check models
@cindex Master file @cindex Master file
@code{flymake-proc-legacy-backend} saves a copy of the buffer in a
temporary file in the buffer's directory (or in the system temp
directory, for Java files), creates a syntax check command and
launches a process with this command. The output is parsed using a
list of error message patterns, and error information (file name, line
number, type and text) is saved. After the process has finished,
Flymake highlights erroneous lines in the buffer using the accumulated
error information.
Syntax check is considered possible if there's an entry in Syntax check is considered possible if there's an entry in
@code{flymake-allowed-file-name-masks} matching buffer's filename and @code{flymake-proc-allowed-file-name-masks} matching buffer's filename and
its @code{init-function} returns non-@code{nil} value. its @code{init-function} returns non-@code{nil} value.
Two syntax check modes are distinguished: Two syntax check modes are distinguished:
@ -564,10 +526,10 @@ will also check syntax in the current file. Examples are C/C++ (.h,
These modes are handled inside init/cleanup/getfname functions, see These modes are handled inside init/cleanup/getfname functions, see
@ref{Adding support for a new syntax check tool}. @ref{Adding support for a new syntax check tool}.
Flymake contains implementations of all functionality required to The Proc backend contains implementations of all functionality
support different syntax check modes described above (making temporary required to support different syntax check modes described above
copies, finding master files, etc.), as well as some tool-specific (making temporary copies, finding master files, etc.), as well as some
(routines for Make, Ant, etc.)@: code. tool-specific (routines for Make, Ant, etc.)@: code.
@node Making a temporary copy @node Making a temporary copy
@ -609,15 +571,16 @@ Master file is located in two steps.
First, a list of possible master files is built. A simple name First, a list of possible master files is built. A simple name
matching is used to find the files. For a C++ header @code{file.h}, matching is used to find the files. For a C++ header @code{file.h},
Flymake searches for all @code{.cpp} files in the directories whose relative paths are the Proc backend searches for all @code{.cpp} files in the directories
stored in a customizable variable @code{flymake-master-file-dirs}, which whose relative paths are stored in a customizable variable
usually contains something like @code{("." "./src")}. No more than @code{flymake-proc-master-file-dirs}, which usually contains something
@code{flymake-master-file-count-limit} entries is added to the master file like @code{("." "./src")}. No more than
list. The list is then sorted to move files with names @code{file.cpp} to @code{flymake-proc-master-file-count-limit} entries is added to the
the top. master file list. The list is then sorted to move files with names
@code{file.cpp} to the top.
Next, each master file in a list is checked to contain the appropriate Next, each master file in a list is checked to contain the appropriate
include directives. No more than @code{flymake-check-file-limit} of each include directives. No more than @code{flymake-proc-check-file-limit} of each
file are parsed. file are parsed.
For @code{file.h}, the include directives to look for are For @code{file.h}, the include directives to look for are
@ -639,10 +602,10 @@ and project include directories. The former is just the contents of the
@code{INCLUDE} environment variable. The latter is not so easy to obtain, @code{INCLUDE} environment variable. The latter is not so easy to obtain,
and the way it can be obtained can vary greatly for different projects. and the way it can be obtained can vary greatly for different projects.
Therefore, a customizable variable Therefore, a customizable variable
@code{flymake-get-project-include-dirs-function} is used to provide the @code{flymake-proc-get-project-include-dirs-function} is used to provide the
way to implement the desired behavior. way to implement the desired behavior.
The default implementation, @code{flymake-get-project-include-dirs-imp}, The default implementation, @code{flymake-proc-get-project-include-dirs-imp},
uses a @command{make} call. This requires a correct base directory, that is, a uses a @command{make} call. This requires a correct base directory, that is, a
directory containing a correct @file{Makefile}, to be determined. directory containing a correct @file{Makefile}, to be determined.
@ -656,27 +619,27 @@ of every syntax check attempt.
@cindex buildfile, locating @cindex buildfile, locating
@cindex Makefile, locating @cindex Makefile, locating
Flymake can be configured to use different tools for performing syntax The Proc backend can be configured to use different tools for
checks. For example, it can use direct compiler call to syntax check a perl performing syntax checks. For example, it can use direct compiler
script or a call to @command{make} for a more complicated case of a call to syntax check a perl script or a call to @command{make} for a
@code{C/C++} source. The general idea is that simple files, like perl more complicated case of a @code{C/C++} source. The general idea is
scripts and html pages, can be checked by directly invoking a that simple files, like perl scripts and html pages, can be checked by
corresponding tool. Files that are usually more complex and generally directly invoking a corresponding tool. Files that are usually more
used as part of larger projects, might require non-trivial options to complex and generally used as part of larger projects, might require
be passed to the syntax check tool, like include directories for non-trivial options to be passed to the syntax check tool, like
C++. The latter files are syntax checked using some build tool, like include directories for C++. The latter files are syntax checked
Make or Ant. using some build tool, like Make or Ant.
All Make configuration data is usually stored in a file called All Make configuration data is usually stored in a file called
@code{Makefile}. To allow for future extensions, flymake uses a notion of @code{Makefile}. To allow for future extensions, Flymake uses a notion of
buildfile to reference the 'project configuration' file. buildfile to reference the 'project configuration' file.
Special function, @code{flymake-find-buildfile} is provided for locating buildfiles. Special function, @code{flymake-proc-find-buildfile} is provided for locating buildfiles.
Searching for a buildfile is done in a manner similar to that of searching Searching for a buildfile is done in a manner similar to that of searching
for possible master files. for possible master files.
@ignore @ignore
A customizable variable A customizable variable
@code{flymake-buildfile-dirs} holds a list of relative paths to the @code{flymake-proc-buildfile-dirs} holds a list of relative paths to the
buildfile. They are checked sequentially until a buildfile is found. buildfile. They are checked sequentially until a buildfile is found.
@end ignore @end ignore
In case there's no build file, syntax check is aborted. In case there's no build file, syntax check is aborted.
@ -687,12 +650,12 @@ Buildfile values are also cached.
@section Starting the syntax check process @section Starting the syntax check process
@cindex Syntax check process @cindex Syntax check process
The command line (command name and the list of arguments) for launching a process is returned by the The command line (command name and the list of arguments) for
initialization function. Flymake then just calls @code{start-process} launching a process is returned by the initialization function. The
to start an asynchronous process and configures a process filter and Proc backend then just starts an asynchronous process and configures a
sentinel, which are used for processing the output of the syntax check process filter and sentinel, which are used for processing the output
tool. When exiting Emacs, running Flymake processes will be killed of the syntax check tool. When exiting Emacs, running processes will
without prompting the user. be killed without prompting the user.
@node Parsing the output @node Parsing the output
@section Parsing the output @section Parsing the output
@ -700,7 +663,7 @@ without prompting the user.
The output generated by the syntax check tool is parsed in the process The output generated by the syntax check tool is parsed in the process
filter/sentinel using the error message patterns stored in the filter/sentinel using the error message patterns stored in the
@code{flymake-err-line-patterns} variable. This variable contains a @code{flymake-proc-err-line-patterns} variable. This variable contains a
list of items of the form @code{(regexp file-idx line-idx list of items of the form @code{(regexp file-idx line-idx
err-text-idx)}, used to determine whether a particular line is an err-text-idx)}, used to determine whether a particular line is an
error message and extract file name, line number and error text, error message and extract file name, line number and error text,
@ -709,66 +672,39 @@ error text with the '@code{^[wW]arning}' pattern. Anything that was not
classified as a warning is considered an error. Type is then used to classified as a warning is considered an error. Type is then used to
sort error menu items, which shows error messages first. sort error menu items, which shows error messages first.
Flymake is also able to interpret error message patterns missing err-text-idx The Proc backend is also able to interpret error message patterns
information. This is done by merely taking the rest of the matched line missing err-text-idx information. This is done by merely taking the
(@code{(substring line (match-end 0))}) as error text. This trick allows rest of the matched line (@code{(substring line (match-end 0))}) as
making use of a huge collection of error message line patterns from error text. This trick allows making use of a huge collection of
@code{compile.el}. All these error patterns are appended to error message line patterns from @code{compile.el}. All these error
the end of @code{flymake-err-line-patterns}. patterns are appended to the end of
@code{flymake-proc-err-line-patterns}.
The error information obtained is saved in a buffer local The error information obtained is saved in a buffer local
variable. The buffer for which the process output belongs is variable. The buffer for which the process output belongs is
determined from the process-id@w{}->@w{}buffer mapping updated determined from the process-id@w{}->@w{}buffer mapping updated
after every process launch/exit. after every process launch/exit.
@node Highlighting erroneous lines
@section Highlighting erroneous lines
@cindex Erroneous lines, faces
Highlighting is implemented with overlays and happens in the process
sentinel, after calling the cleanup function. Two customizable faces
are used: @code{flymake-errline} and
@code{flymake-warnline}. Errors belonging outside the current
buffer are considered to belong to line 1 of the current buffer.
@c This manual does not use vindex.
@c @vindex flymake-fringe-indicator-position
@c @vindex flymake-error-bitmap
@c @vindex flymake-warning-bitmap
If the option @code{flymake-fringe-indicator-position} is non-@code{nil},
errors and warnings are also highlighted in the left or right fringe,
using the bitmaps specified by @code{flymake-error-bitmap}
and @code{flymake-warning-bitmap}.
@node Interaction with other modes @node Interaction with other modes
@section Interaction with other modes @section Interaction with other modes
@cindex Interaction with other modes @cindex Interaction with other modes
@cindex Interaction with compile mode @cindex Interaction with compile mode
The only mode flymake currently knows about is @code{compile}. The only mode the Proc backend currently knows about is
@code{compile}.
Flymake can be configured to not start syntax check if it thinks the The Proc backend can be configured to not start syntax check if it
compilation is in progress. The check is made by the thinks the compilation is in progress, by testing the
@code{flymake-compilation-is-running}, which tests the
@code{compilation-in-progress} variable. The reason why this might be @code{compilation-in-progress} variable. The reason why this might be
useful is saving CPU time in case both syntax check and compilation useful is saving CPU time in case both syntax check and compilation
are very CPU intensive. The original reason for adding this feature, are very CPU intensive. The original reason for adding this feature,
though, was working around a locking problem with MS Visual C++ though, was working around a locking problem with MS Visual C++
compiler. compiler. The variable in question is
@code{flymake-proc-compilation-prevents-syntax-check}.
Flymake also provides an alternative command for starting compilation, The Proc backend also provides an alternative command for starting
@code{flymake-compile}: compilation, @code{flymake-proc-compile}. It just kills all the active
syntax check processes before calling @code{compile}.
@lisp
(defun flymake-compile ()
"Kill all flymake syntax checks then start compilation."
(interactive)
(flymake-stop-all-syntax-checks)
(call-interactively 'compile))
@end lisp
It just kills all the active syntax check processes before calling
@code{compile}.
@node GNU Free Documentation License @node GNU Free Documentation License
@appendix GNU Free Documentation License @appendix GNU Free Documentation License

View file

@ -4,7 +4,7 @@
@settitle The Org Manual @settitle The Org Manual
@include docstyle.texi @include docstyle.texi
@set VERSION 9.1.1 @set VERSION 9.1.2
@set DATE 2017-09-17 @set DATE 2017-09-17
@c Version and Contact Info @c Version and Contact Info
@ -1257,13 +1257,8 @@ Org uses just two commands, bound to @key{TAB} and
@end example @end example
@vindex org-cycle-emulate-tab @vindex org-cycle-emulate-tab
@vindex org-cycle-global-at-bob
The cursor must be on a headline for this to work@footnote{see, however, The cursor must be on a headline for this to work@footnote{see, however,
the option @code{org-cycle-emulate-tab}.}. When the cursor is at the the option @code{org-cycle-emulate-tab}.}.
beginning of the buffer and the first line is not a headline, then
@key{TAB} actually runs global cycling (see below)@footnote{see the
option @code{org-cycle-global-at-bob}.}. Also when called with a prefix
argument (@kbd{C-u @key{TAB}}), global cycling is invoked.
@cindex global visibility states @cindex global visibility states
@cindex global cycling @cindex global cycling
@ -1283,6 +1278,11 @@ When @kbd{S-@key{TAB}} is called with a numeric prefix argument N, the
CONTENTS view up to headlines of level N will be shown. Note that inside CONTENTS view up to headlines of level N will be shown. Note that inside
tables, @kbd{S-@key{TAB}} jumps to the previous field. tables, @kbd{S-@key{TAB}} jumps to the previous field.
@vindex org-cycle-global-at-bob
You can run global cycling using @key{TAB} only if point is at the very
beginning of the buffer, but not on a headline, and
@code{org-cycle-global-at-bob} is set to a non-@code{nil} value.
@cindex set startup visibility, command @cindex set startup visibility, command
@orgcmd{C-u C-u @key{TAB},org-set-startup-visibility} @orgcmd{C-u C-u @key{TAB},org-set-startup-visibility}
Switch back to the startup visibility of the buffer (@pxref{Initial visibility}). Switch back to the startup visibility of the buffer (@pxref{Initial visibility}).
@ -1659,11 +1659,9 @@ line. In particular, if an ordered list reaches number @samp{10.}, then the
list. An item ends before the next line that is less or equally indented list. An item ends before the next line that is less or equally indented
than its bullet/number. than its bullet/number.
@vindex org-list-empty-line-terminates-plain-lists
A list ends whenever every item has ended, which means before any line less A list ends whenever every item has ended, which means before any line less
or equally indented than items at top level. It also ends before two blank or equally indented than items at top level. It also ends before two blank
lines@footnote{See also @code{org-list-empty-line-terminates-plain-lists}.}. lines. In that case, all items are closed. Here is an example:
In that case, all items are closed. Here is an example:
@example @example
@group @group
@ -14991,6 +14989,7 @@ directory on the local machine.
'(("org" '(("org"
:base-directory "~/org/" :base-directory "~/org/"
:publishing-directory "~/public_html" :publishing-directory "~/public_html"
:publishing-function org-html-publish-to-html
:section-numbers nil :section-numbers nil
:with-toc nil :with-toc nil
:html-head "<link rel=\"stylesheet\" :html-head "<link rel=\"stylesheet\"

View file

@ -35,8 +35,9 @@ GNU Mailutils to retrieve email. It is recommended, and is the
default if GNU Mailutils is installed. When --with-mailutils is not default if GNU Mailutils is installed. When --with-mailutils is not
in effect, the Emacs build procedure by default continues to build and in effect, the Emacs build procedure by default continues to build and
install a limited 'movemail' substitute that retrieves POP3 email only install a limited 'movemail' substitute that retrieves POP3 email only
via insecure channels; to avoid this problem, use either via insecure channels. To avoid this problem, use either
--with-mailutils or --without-pop when configuring. --with-mailutils or --without-pop when configuring; --without-pop
is the default on platforms other than native MS-Windows.
** The new option 'configure --enable-gcc-warnings=warn-only' causes ** The new option 'configure --enable-gcc-warnings=warn-only' causes
GCC to issue warnings without stopping the build. This behavior is GCC to issue warnings without stopping the build. This behavior is
@ -1111,7 +1112,7 @@ See the 'vc-faces' customization group.
*** 'vc-dir-mode' now binds 'vc-log-outgoing' to 'O'; and has various *** 'vc-dir-mode' now binds 'vc-log-outgoing' to 'O'; and has various
branch-related commands on a keymap bound to 'B'. branch-related commands on a keymap bound to 'B'.
--- +++
*** 'vc-region-history' is now bound to 'C-x v h', replacing the older *** 'vc-region-history' is now bound to 'C-x v h', replacing the older
'vc-insert-headers' binding. 'vc-insert-headers' binding.
@ -1555,6 +1556,13 @@ Emacs integers with %e, %f, or %g conversions. For example, on these
hosts (eql N (string-to-number (format "%.0f" N))) now returns t for hosts (eql N (string-to-number (format "%.0f" N))) now returns t for
all Emacs integers N. all Emacs integers N.
+++
** 'format' is no longer documented to return a newly-allocated string.
This documentation was not correct, as (eq x (format x)) returned t
when x was the empty string. 'format' now takes advantage of the doc
change to avoid making copies of strings in common cases like (format
"foo") and (format "%s" "foo").
--- ---
** Calls that accept floating-point integers (for use on hosts with ** Calls that accept floating-point integers (for use on hosts with
limited integer range) now signal an error if arguments are not limited integer range) now signal an error if arguments are not

View file

@ -2029,6 +2029,19 @@ Definitions" to make them defined.
We list bugs in current versions here. See also the section on legacy We list bugs in current versions here. See also the section on legacy
systems. systems.
*** On Solaris 10, Emacs crashes during the build process.
This was reported for Emacs 25.2 on i386-pc-solaris2.10 with Sun
Studio 12 (Sun C 5.9) and with Oracle Developer Studio 12.6 (Sun C
5.15), and intermittently for sparc-sun-solaris2.10 with Oracle
Developer Studio 12.5 (Sun C 5.14). Disabling compiler optimization
seems to fix the bug, as does upgrading the Solaris 10 operating
system to Update 11. The cause of the bug is unknown: it may be that
Emacs's archaic memory-allocation scheme is not compatible with
slightly-older versions of Solaris and/or Oracle Studio, or it may be
something else. Since the cause is not known, possibly the bug is
still present in newer versions of Emacs, Oracle Studio, and/or
Solaris. See Bug#26638.
*** On Solaris, C-x doesn't get through to Emacs when you use the console. *** On Solaris, C-x doesn't get through to Emacs when you use the console.
This is a Solaris feature (at least on Intel x86 cpus). Type C-r This is a Solaris feature (at least on Intel x86 cpus). Type C-r

View file

@ -1,5 +1,5 @@
% Reference Card for Org Mode % Reference Card for Org Mode
\def\orgversionnumber{9.1.1} \def\orgversionnumber{9.1.2}
\def\versionyear{2017} % latest update \def\versionyear{2017} % latest update
\input emacsver.tex \input emacsver.tex

View file

@ -1183,7 +1183,29 @@ Each function's symbol gets added to `byte-compile-noruntime-functions'."
(compilation-forget-errors) (compilation-forget-errors)
pt)))) pt))))
(defvar byte-compile-log-warning-function
#'byte-compile--log-warning-for-byte-compile
"Function called when encountering a warning or error.
Called with arguments (STRING POSITION FILL LEVEL). STRING is a
message describing the problem. POSITION is a buffer position
where the problem was detected. FILL is a prefix as in
`warning-fill-prefix'. LEVEL is the level of the
problem (`:warning' or `:error'). POSITION, FILL and LEVEL may be
nil.")
(defun byte-compile-log-warning (string &optional fill level) (defun byte-compile-log-warning (string &optional fill level)
"Log a byte-compilation warning.
STRING, FILL and LEVEL are as described in
`byte-compile-log-warning-function', which see."
(funcall byte-compile-log-warning-function
string byte-compile-last-position
fill
level))
(defun byte-compile--log-warning-for-byte-compile (string &optional
_position
fill
level)
"Log a message STRING in `byte-compile-log-buffer'. "Log a message STRING in `byte-compile-log-buffer'.
Also log the current function and file if not already done. If Also log the current function and file if not already done. If
FILL is non-nil, set `warning-fill-prefix' to four spaces. LEVEL FILL is non-nil, set `warning-fill-prefix' to four spaces. LEVEL

View file

@ -1147,14 +1147,27 @@ Prefix argument is the same as for `checkdoc-defun'"
;; features and behaviors, so we need some ways of specifying ;; features and behaviors, so we need some ways of specifying
;; them, and making them easier to use in the wacked-out interfaces ;; them, and making them easier to use in the wacked-out interfaces
;; people are requesting ;; people are requesting
(defun checkdoc-create-error (text start end &optional unfixable) (defvar checkdoc-create-error-function #'checkdoc--create-error-for-checkdoc
"Used to create the return error text returned from all engines. "Function called when Checkdoc encounters an error.
Should accept as arguments (TEXT START END &optional UNFIXABLE).
TEXT is the descriptive text of the error. START and END define the region TEXT is the descriptive text of the error. START and END define the region
it is sensible to highlight when describing the problem. it is sensible to highlight when describing the problem.
Optional argument UNFIXABLE means that the error has no auto-fix available. Optional argument UNFIXABLE means that the error has no auto-fix available.
A list of the form (TEXT START END UNFIXABLE) is returned if we are not A list of the form (TEXT START END UNFIXABLE) is returned if we are not
generating a buffered list of errors." generating a buffered list of errors.")
(defun checkdoc-create-error (text start end &optional unfixable)
"Used to create the return error text returned from all engines.
TEXT, START, END and UNFIXABLE conform to
`checkdoc-create-error-function', which see."
(funcall checkdoc-create-error-function text start end unfixable))
(defun checkdoc--create-error-for-checkdoc (text start end &optional unfixable)
"Create an error for Checkdoc.
TEXT, START, END and UNFIXABLE conform to
`checkdoc-create-error-function', which see."
(if checkdoc-generate-compile-warnings-flag (if checkdoc-generate-compile-warnings-flag
(progn (checkdoc-error start text) (progn (checkdoc-error start text)
nil) nil)

View file

@ -268,7 +268,7 @@ into a button whose action shows the function's disassembly.")
Output is further controlled by the variables Output is further controlled by the variables
`cl-print-readably', `cl-print-compiled', along with output `cl-print-readably', `cl-print-compiled', along with output
variables for the standard printing functions. See Info variables for the standard printing functions. See Info
node `(elisp)Output Variables'. " node `(elisp)Output Variables'."
(cond (cond
(cl-print-readably (prin1 object stream)) (cl-print-readably (prin1 object stream))
((not print-circle) (cl-print-object object stream)) ((not print-circle) (cl-print-object object stream))

View file

@ -142,8 +142,7 @@ the CPS state machinery.
`(let ((,dynamic-var ,static-var)) `(let ((,dynamic-var ,static-var))
(unwind-protect ; Update the static shadow after evaluation is done (unwind-protect ; Update the static shadow after evaluation is done
,form ,form
(setf ,static-var ,dynamic-var)) (setf ,static-var ,dynamic-var)))))
,form)))
(defmacro cps--with-dynamic-binding (dynamic-var static-var &rest body) (defmacro cps--with-dynamic-binding (dynamic-var static-var &rest body)
"Evaluate BODY such that generated atomic evaluations run with "Evaluate BODY such that generated atomic evaluations run with

View file

@ -329,6 +329,8 @@ Check the current row, the previous one and the next row."
(string-width (if (stringp nt) nt (car nt))))) (string-width (if (stringp nt) nt (car nt)))))
tabulated-list--near-rows))) tabulated-list--near-rows)))
(defvar tabulated-list-entry-lnum-width nil)
(defun tabulated-list-print (&optional remember-pos update) (defun tabulated-list-print (&optional remember-pos update)
"Populate the current Tabulated List mode buffer. "Populate the current Tabulated List mode buffer.
This sorts the `tabulated-list-entries' list if sorting is This sorts the `tabulated-list-entries' list if sorting is
@ -371,6 +373,7 @@ changing `tabulated-list-sort-key'."
(unless tabulated-list-use-header-line (unless tabulated-list-use-header-line
(tabulated-list-print-fake-header))) (tabulated-list-print-fake-header)))
;; Finally, print the resulting list. ;; Finally, print the resulting list.
(setq tabulated-list-entry-lnum-width (tabulated-list-line-number-width))
(while entries (while entries
(let* ((elt (car entries)) (let* ((elt (car entries))
(tabulated-list--near-rows (tabulated-list--near-rows
@ -383,7 +386,7 @@ changing `tabulated-list-sort-key'."
(equal entry-id id) (equal entry-id id)
(setq entry-id nil (setq entry-id nil
saved-pt (point))) saved-pt (point)))
;; If the buffer this empty, simply print each elt. ;; If the buffer is empty, simply print each elt.
(if (or (not update) (eobp)) (if (or (not update) (eobp))
(apply tabulated-list-printer elt) (apply tabulated-list-printer elt)
(while (let ((local-id (tabulated-list-get-id))) (while (let ((local-id (tabulated-list-get-id)))
@ -424,12 +427,10 @@ of column descriptors."
(let ((beg (point)) (let ((beg (point))
(x (max tabulated-list-padding 0)) (x (max tabulated-list-padding 0))
(ncols (length tabulated-list-format)) (ncols (length tabulated-list-format))
(lnum-width (tabulated-list-line-number-width))
(inhibit-read-only t)) (inhibit-read-only t))
(if display-line-numbers (setq x (+ x tabulated-list-entry-lnum-width))
(setq x (+ x lnum-width)))
(if (> tabulated-list-padding 0) (if (> tabulated-list-padding 0)
(insert (make-string (- x lnum-width) ?\s))) (insert (make-string (- x tabulated-list-entry-lnum-width) ?\s)))
(let ((tabulated-list--near-rows ; Bind it if not bound yet (Bug#25506). (let ((tabulated-list--near-rows ; Bind it if not bound yet (Bug#25506).
(or (bound-and-true-p tabulated-list--near-rows) (or (bound-and-true-p tabulated-list--near-rows)
(list (or (tabulated-list-get-entry (point-at-bol 0)) (list (or (tabulated-list-get-entry (point-at-bol 0))

View file

@ -9303,7 +9303,7 @@
* mail-source.el, message.el, mm-bodies.el, mm-decode.el, mm-extern.el: * mail-source.el, message.el, mm-bodies.el, mm-decode.el, mm-extern.el:
* mm-util.el, mm-view.el, mml-smime.el, mml.el, mml1991.el, mml2015.el: * mm-util.el, mm-view.el, mml-smime.el, mml.el, mml1991.el, mml2015.el:
* nnfolder.el, nnheader.el, nnmail.el, nnmaildir.el, nnrss.el, nntp.el: * nnfolder.el, nnheader.el, nnmail.el, nnmaildir.el, nnrss.el, nntp.el:
* rfc1843.el, sieve-manage.el, smime.el, spam.el: * gnus-rfc1843.el, sieve-manage.el, smime.el, spam.el:
Fix comment for declare-function. Fix comment for declare-function.
2010-10-11 Lars Magne Ingebrigtsen <larsi@gnus.org> 2010-10-11 Lars Magne Ingebrigtsen <larsi@gnus.org>
@ -10470,7 +10470,7 @@
2010-09-25 Julien Danjou <julien@danjou.info> 2010-09-25 Julien Danjou <julien@danjou.info>
* rfc1843.el: Remove useless rfc1843-old-gnus-decode-header-function * gnus-rfc1843.el: Remove useless rfc1843-old-gnus-decode-header-function
variables. variables.
* nnheader.el: Remove useless variables news-reply-yank-from and * nnheader.el: Remove useless variables news-reply-yank-from and
@ -14716,14 +14716,14 @@
* mml2015.el (gnus-buffer-live-p, gnus-get-buffer-create): * mml2015.el (gnus-buffer-live-p, gnus-get-buffer-create):
* nnfolder.el (gnus-request-group): * nnfolder.el (gnus-request-group):
* nnheader.el (ietf-drums-unfold-fws): * nnheader.el (ietf-drums-unfold-fws):
* rfc1843.el (mail-header-parse-content-type, message-narrow-to-head): * gnus-rfc1843.el (mail-header-parse-content-type, message-narrow-to-head):
* smime.el (gnus-run-mode-hooks): * smime.el (gnus-run-mode-hooks):
* spam-stat.el (gnus-message): Autoload. * spam-stat.el (gnus-message): Autoload.
* gnus-cache.el, gnus-fun.el, gnus-group.el, gnus.el, mail-source.el: * gnus-cache.el, gnus-fun.el, gnus-group.el, gnus.el, mail-source.el:
* mm-bodies.el, mm-decode.el, mm-extern.el, mm-util.el: * mm-bodies.el, mm-decode.el, mm-extern.el, mm-util.el:
* mml-smime.el, mml.el, mml1991.el, mml2015.el, nndb.el, nnfolder.el: * mml-smime.el, mml.el, mml1991.el, mml2015.el, nndb.el, nnfolder.el:
* nnmail.el, nnmaildir.el, nnrss.el, rfc1843.el, spam.el: * nnmail.el, nnmaildir.el, nnrss.el, gnus-rfc1843.el, spam.el:
Add declare-function compatibility definition. Add declare-function compatibility definition.
* gnus-cache.el (nnvirtual-find-group-art): * gnus-cache.el (nnvirtual-find-group-art):
@ -14753,7 +14753,7 @@
* nnmail.el (gnus-activate-group, gnus-group-mark-article-read): * nnmail.el (gnus-activate-group, gnus-group-mark-article-read):
* nnmaildir.el (gnus-group-mark-article-read): * nnmaildir.el (gnus-group-mark-article-read):
* nnrss.el (w3-parse-buffer, gnus-group-make-rss-group): * nnrss.el (w3-parse-buffer, gnus-group-make-rss-group):
* rfc1843.el (message-fetch-field): * gnus-rfc1843.el (message-fetch-field):
* spam.el (gnus-extract-address-components): * spam.el (gnus-extract-address-components):
Declare as functions. Declare as functions.
@ -19139,7 +19139,7 @@
(mml-insert-parameter): Fold lines properly even if a parameter is (mml-insert-parameter): Fold lines properly even if a parameter is
segmented into two or more lines; change the max column to 76. segmented into two or more lines; change the max column to 76.
* rfc1843.el (rfc1843-decode-article-body): Don't use * gnus-rfc1843.el (rfc1843-decode-article-body): Don't use
ignore-errors when calling mail-header-parse-content-type. ignore-errors when calling mail-header-parse-content-type.
* rfc2231.el (rfc2231-parse-string): Return at least type if * rfc2231.el (rfc2231-parse-string): Return at least type if
@ -20525,7 +20525,7 @@
* mml1991.el (mc-pgp-always-sign): * mml1991.el (mc-pgp-always-sign):
* mml2015.el (mc-pgp-always-sign): * mml2015.el (mc-pgp-always-sign):
* nnheader.el (nnmail-extra-headers): * nnheader.el (nnmail-extra-headers):
* rfc1843.el (gnus-decode-encoded-word-function) * gnus-rfc1843.el (gnus-decode-encoded-word-function)
(gnus-decode-header-function, gnus-newsgroup-name): (gnus-decode-header-function, gnus-newsgroup-name):
* spam-stat.el (gnus-original-article-buffer): Add defvars. * spam-stat.el (gnus-original-article-buffer): Add defvars.

View file

@ -13080,23 +13080,7 @@ to get the effect of a C-q.
;;; Generated autoloads from progmodes/flymake.el ;;; Generated autoloads from progmodes/flymake.el
(push (purecopy '(flymake 0 3)) package--builtin-versions) (push (purecopy '(flymake 0 3)) package--builtin-versions)
;;;*** (autoload 'flymake-mode "flymake" "\
;;;### (autoloads nil "flymake-proc" "progmodes/flymake-proc.el"
;;;;;; (0 0 0 0))
;;; Generated autoloads from progmodes/flymake-proc.el
(push (purecopy '(flymake-proc 0 3)) package--builtin-versions)
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "flymake-proc" '("flymake-")))
;;;***
;;;### (autoloads nil "flymake-ui" "progmodes/flymake-ui.el" (0 0
;;;;;; 0 0))
;;; Generated autoloads from progmodes/flymake-ui.el
(push (purecopy '(flymake-ui 0 3)) package--builtin-versions)
(autoload 'flymake-mode "flymake-ui" "\
Toggle Flymake mode on or off. Toggle Flymake mode on or off.
With a prefix argument ARG, enable Flymake mode if ARG is With a prefix argument ARG, enable Flymake mode if ARG is
positive, and disable it otherwise. If called from Lisp, enable positive, and disable it otherwise. If called from Lisp, enable
@ -13105,22 +13089,22 @@ the mode if ARG is omitted or nil, and toggle it if ARG is `toggle'.
\(fn &optional ARG)" t nil) \(fn &optional ARG)" t nil)
(autoload 'flymake-mode-on "flymake-ui" "\ (autoload 'flymake-mode-on "flymake" "\
Turn flymake mode on. Turn flymake mode on.
\(fn)" nil nil) \(fn)" nil nil)
(autoload 'flymake-mode-off "flymake-ui" "\ (autoload 'flymake-mode-off "flymake" "\
Turn flymake mode off. Turn flymake mode off.
\(fn)" nil nil) \(fn)" nil nil)
(autoload 'flymake-find-file-hook "flymake-ui" "\ (autoload 'flymake-find-file-hook "flymake" "\
\(fn)" nil nil) \(fn)" nil nil)
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "flymake-ui" '("flymake-"))) (if (fboundp 'register-definition-prefixes) (register-definition-prefixes "flymake" '("flymake-")))
;;;*** ;;;***
@ -33735,7 +33719,7 @@ Return a string giving the duration of the Emacs initialization.
\(fn)" t nil) \(fn)" t nil)
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "time" '("display-time-" "legacy-style-world-list" "zoneinfo-style-world-list"))) (if (fboundp 'register-definition-prefixes) (register-definition-prefixes "time" '("display-time-" "time--display-world-list" "legacy-style-world-list" "zoneinfo-style-world-list")))
;;;*** ;;;***
@ -34451,7 +34435,7 @@ Reenable Ange-FTP, when Tramp is unloaded.
;;;### (autoloads nil "trampver" "net/trampver.el" (0 0 0 0)) ;;;### (autoloads nil "trampver" "net/trampver.el" (0 0 0 0))
;;; Generated autoloads from net/trampver.el ;;; Generated autoloads from net/trampver.el
(push (purecopy '(tramp 2 3 3 -1)) package--builtin-versions) (push (purecopy '(tramp 2 3 3 26 1)) package--builtin-versions)
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "trampver" '("tramp-"))) (if (fboundp 'register-definition-prefixes) (register-definition-prefixes "trampver" '("tramp-")))
@ -38524,53 +38508,44 @@ Zone out, completely.
;;;;;; "eshell/em-term.el" "eshell/em-tramp.el" "eshell/em-unix.el" ;;;;;; "eshell/em-term.el" "eshell/em-tramp.el" "eshell/em-unix.el"
;;;;;; "eshell/em-xtra.el" "facemenu.el" "faces.el" "files.el" "font-core.el" ;;;;;; "eshell/em-xtra.el" "facemenu.el" "faces.el" "files.el" "font-core.el"
;;;;;; "font-lock.el" "format.el" "frame.el" "help.el" "hfy-cmap.el" ;;;;;; "font-lock.el" "format.el" "frame.el" "help.el" "hfy-cmap.el"
;;;;;; "ibuf-ext.el" "indent.el" "international/characters.el" "international/charprop.el" ;;;;;; "ibuf-ext.el" "indent.el" "international/characters.el" "international/charscript.el"
;;;;;; "international/charscript.el" "international/cp51932.el" ;;;;;; "international/cp51932.el" "international/eucjp-ms.el" "international/mule-cmds.el"
;;;;;; "international/eucjp-ms.el" "international/mule-cmds.el" ;;;;;; "international/mule-conf.el" "international/mule.el" "isearch.el"
;;;;;; "international/mule-conf.el" "international/mule.el" "international/uni-bidi.el" ;;;;;; "jit-lock.el" "jka-cmpr-hook.el" "language/burmese.el" "language/cham.el"
;;;;;; "international/uni-brackets.el" "international/uni-category.el" ;;;;;; "language/chinese.el" "language/cyrillic.el" "language/czech.el"
;;;;;; "international/uni-combining.el" "international/uni-comment.el" ;;;;;; "language/english.el" "language/ethiopic.el" "language/european.el"
;;;;;; "international/uni-decimal.el" "international/uni-decomposition.el" ;;;;;; "language/georgian.el" "language/greek.el" "language/hebrew.el"
;;;;;; "international/uni-digit.el" "international/uni-lowercase.el" ;;;;;; "language/indian.el" "language/japanese.el" "language/khmer.el"
;;;;;; "international/uni-mirrored.el" "international/uni-name.el" ;;;;;; "language/korean.el" "language/lao.el" "language/misc-lang.el"
;;;;;; "international/uni-numeric.el" "international/uni-old-name.el" ;;;;;; "language/romanian.el" "language/sinhala.el" "language/slovak.el"
;;;;;; "international/uni-titlecase.el" "international/uni-uppercase.el" ;;;;;; "language/tai-viet.el" "language/thai.el" "language/tibetan.el"
;;;;;; "isearch.el" "jit-lock.el" "jka-cmpr-hook.el" "language/burmese.el" ;;;;;; "language/utf-8-lang.el" "language/vietnamese.el" "ldefs-boot.el"
;;;;;; "language/cham.el" "language/chinese.el" "language/cyrillic.el" ;;;;;; "leim/ja-dic/ja-dic.el" "leim/leim-list.el" "leim/quail/4Corner.el"
;;;;;; "language/czech.el" "language/english.el" "language/ethiopic.el" ;;;;;; "leim/quail/ARRAY30.el" "leim/quail/CCDOSPY.el" "leim/quail/CTLau-b5.el"
;;;;;; "language/european.el" "language/georgian.el" "language/greek.el" ;;;;;; "leim/quail/CTLau.el" "leim/quail/ECDICT.el" "leim/quail/ETZY.el"
;;;;;; "language/hebrew.el" "language/indian.el" "language/japanese.el" ;;;;;; "leim/quail/PY-b5.el" "leim/quail/PY.el" "leim/quail/Punct-b5.el"
;;;;;; "language/khmer.el" "language/korean.el" "language/lao.el" ;;;;;; "leim/quail/Punct.el" "leim/quail/QJ-b5.el" "leim/quail/QJ.el"
;;;;;; "language/misc-lang.el" "language/romanian.el" "language/sinhala.el" ;;;;;; "leim/quail/SW.el" "leim/quail/TONEPY.el" "leim/quail/ZIRANMA.el"
;;;;;; "language/slovak.el" "language/tai-viet.el" "language/thai.el" ;;;;;; "leim/quail/ZOZY.el" "leim/quail/arabic.el" "leim/quail/croatian.el"
;;;;;; "language/tibetan.el" "language/utf-8-lang.el" "language/vietnamese.el" ;;;;;; "leim/quail/cyril-jis.el" "leim/quail/cyrillic.el" "leim/quail/czech.el"
;;;;;; "ldefs-boot.el" "leim/ja-dic/ja-dic.el" "leim/leim-list.el" ;;;;;; "leim/quail/georgian.el" "leim/quail/greek.el" "leim/quail/hanja-jis.el"
;;;;;; "leim/quail/4Corner.el" "leim/quail/ARRAY30.el" "leim/quail/CCDOSPY.el" ;;;;;; "leim/quail/hanja.el" "leim/quail/hanja3.el" "leim/quail/hebrew.el"
;;;;;; "leim/quail/CTLau-b5.el" "leim/quail/CTLau.el" "leim/quail/ECDICT.el" ;;;;;; "leim/quail/ipa-praat.el" "leim/quail/latin-alt.el" "leim/quail/latin-ltx.el"
;;;;;; "leim/quail/ETZY.el" "leim/quail/PY-b5.el" "leim/quail/PY.el" ;;;;;; "leim/quail/latin-post.el" "leim/quail/latin-pre.el" "leim/quail/persian.el"
;;;;;; "leim/quail/Punct-b5.el" "leim/quail/Punct.el" "leim/quail/QJ-b5.el" ;;;;;; "leim/quail/programmer-dvorak.el" "leim/quail/py-punct.el"
;;;;;; "leim/quail/QJ.el" "leim/quail/SW.el" "leim/quail/TONEPY.el" ;;;;;; "leim/quail/pypunct-b5.el" "leim/quail/quick-b5.el" "leim/quail/quick-cns.el"
;;;;;; "leim/quail/ZIRANMA.el" "leim/quail/ZOZY.el" "leim/quail/arabic.el" ;;;;;; "leim/quail/rfc1345.el" "leim/quail/sgml-input.el" "leim/quail/slovak.el"
;;;;;; "leim/quail/croatian.el" "leim/quail/cyril-jis.el" "leim/quail/cyrillic.el" ;;;;;; "leim/quail/symbol-ksc.el" "leim/quail/tamil-dvorak.el" "leim/quail/tsang-b5.el"
;;;;;; "leim/quail/czech.el" "leim/quail/georgian.el" "leim/quail/greek.el" ;;;;;; "leim/quail/tsang-cns.el" "leim/quail/vntelex.el" "leim/quail/vnvni.el"
;;;;;; "leim/quail/hanja-jis.el" "leim/quail/hanja.el" "leim/quail/hanja3.el" ;;;;;; "leim/quail/welsh.el" "loadup.el" "mail/blessmail.el" "mail/rmailedit.el"
;;;;;; "leim/quail/hebrew.el" "leim/quail/ipa-praat.el" "leim/quail/latin-alt.el" ;;;;;; "mail/rmailkwd.el" "mail/rmailmm.el" "mail/rmailmsc.el" "mail/rmailsort.el"
;;;;;; "leim/quail/latin-ltx.el" "leim/quail/latin-post.el" "leim/quail/latin-pre.el" ;;;;;; "mail/rmailsum.el" "mail/undigest.el" "menu-bar.el" "mh-e/mh-gnus.el"
;;;;;; "leim/quail/persian.el" "leim/quail/programmer-dvorak.el" ;;;;;; "mh-e/mh-loaddefs.el" "minibuffer.el" "mouse.el" "net/tramp-loaddefs.el"
;;;;;; "leim/quail/py-punct.el" "leim/quail/pypunct-b5.el" "leim/quail/quick-b5.el" ;;;;;; "newcomment.el" "obarray.el" "org/ob-core.el" "org/ob-keys.el"
;;;;;; "leim/quail/quick-cns.el" "leim/quail/rfc1345.el" "leim/quail/sgml-input.el" ;;;;;; "org/ob-lob.el" "org/ob-matlab.el" "org/ob-tangle.el" "org/ob.el"
;;;;;; "leim/quail/slovak.el" "leim/quail/symbol-ksc.el" "leim/quail/tamil-dvorak.el" ;;;;;; "org/org-archive.el" "org/org-attach.el" "org/org-bbdb.el"
;;;;;; "leim/quail/tsang-b5.el" "leim/quail/tsang-cns.el" "leim/quail/vntelex.el" ;;;;;; "org/org-clock.el" "org/org-datetree.el" "org/org-element.el"
;;;;;; "leim/quail/vnvni.el" "leim/quail/welsh.el" "loadup.el" "mail/blessmail.el" ;;;;;; "org/org-feed.el" "org/org-footnote.el" "org/org-id.el" "org/org-indent.el"
;;;;;; "mail/rmailedit.el" "mail/rmailkwd.el" "mail/rmailmm.el"
;;;;;; "mail/rmailmsc.el" "mail/rmailsort.el" "mail/rmailsum.el"
;;;;;; "mail/undigest.el" "menu-bar.el" "mh-e/mh-gnus.el" "mh-e/mh-loaddefs.el"
;;;;;; "minibuffer.el" "mouse.el" "net/tramp-loaddefs.el" "newcomment.el"
;;;;;; "obarray.el" "org/ob-core.el" "org/ob-keys.el" "org/ob-lob.el"
;;;;;; "org/ob-matlab.el" "org/ob-tangle.el" "org/ob.el" "org/org-archive.el"
;;;;;; "org/org-attach.el" "org/org-bbdb.el" "org/org-clock.el"
;;;;;; "org/org-datetree.el" "org/org-element.el" "org/org-feed.el"
;;;;;; "org/org-footnote.el" "org/org-id.el" "org/org-indent.el"
;;;;;; "org/org-install.el" "org/org-irc.el" "org/org-mobile.el" ;;;;;; "org/org-install.el" "org/org-irc.el" "org/org-mobile.el"
;;;;;; "org/org-plot.el" "org/org-table.el" "org/org-timer.el" "org/ox-ascii.el" ;;;;;; "org/org-plot.el" "org/org-table.el" "org/org-timer.el" "org/ox-ascii.el"
;;;;;; "org/ox-beamer.el" "org/ox-html.el" "org/ox-icalendar.el" ;;;;;; "org/ox-beamer.el" "org/ox-html.el" "org/ox-icalendar.el"

View file

@ -470,6 +470,18 @@ size, and full-buffer size."
(shr-insert sub) (shr-insert sub)
(shr-descend sub)))) (shr-descend sub))))
(defun shr-indirect-call (tag-name dom &rest args)
(let ((function (intern (concat "shr-tag-" (symbol-name tag-name)) obarray))
;; Allow other packages to override (or provide) rendering
;; of elements.
(external (cdr (assq tag-name shr-external-rendering-functions))))
(cond (external
(apply external dom args))
((fboundp function)
(apply function dom args))
(t
(apply 'shr-generic dom args)))))
(defun shr-descend (dom) (defun shr-descend (dom)
(let ((function (let ((function
(intern (concat "shr-tag-" (symbol-name (dom-tag dom))) obarray)) (intern (concat "shr-tag-" (symbol-name (dom-tag dom))) obarray))
@ -490,6 +502,11 @@ size, and full-buffer size."
(setq style nil))) (setq style nil)))
;; If we have a display:none, then just ignore this part of the DOM. ;; If we have a display:none, then just ignore this part of the DOM.
(unless (equal (cdr (assq 'display shr-stylesheet)) "none") (unless (equal (cdr (assq 'display shr-stylesheet)) "none")
;; We don't use shr-indirect-call here, since shr-descend is
;; the central bit of shr.el, and should be as fast as
;; possible. Having one more level of indirection with its
;; negative effect on performance is deemed unjustified in
;; this case.
(cond (external (cond (external
(funcall external dom)) (funcall external dom))
((fboundp function) ((fboundp function)
@ -1404,7 +1421,7 @@ ones, in case fg and bg are nil."
(when url (when url
(cond (cond
(image (image
(shr-tag-img dom url) (shr-indirect-call 'img dom url)
(setq dom nil)) (setq dom nil))
(multimedia (multimedia
(shr-insert " [multimedia] ") (shr-insert " [multimedia] ")
@ -1469,7 +1486,7 @@ The preference is a float determined from `shr-prefer-media-type'."
(unless url (unless url
(setq url (car (shr--extract-best-source dom)))) (setq url (car (shr--extract-best-source dom))))
(if (> (length image) 0) (if (> (length image) 0)
(shr-tag-img nil image) (shr-indirect-call 'img nil image)
(shr-insert " [video] ")) (shr-insert " [video] "))
(shr-urlify start (shr-expand-url url)))) (shr-urlify start (shr-expand-url url))))
@ -1964,9 +1981,9 @@ flags that control whether to collect or render objects."
do (setq tag (dom-tag child)) and do (setq tag (dom-tag child)) and
unless (memq tag '(comment style)) unless (memq tag '(comment style))
if (eq tag 'img) if (eq tag 'img)
do (shr-tag-img child) do (shr-indirect-call 'img child)
else if (eq tag 'object) else if (eq tag 'object)
do (shr-tag-object child) do (shr-indirect-call 'object child)
else else
do (setq recurse t) and do (setq recurse t) and
if (eq tag 'tr) if (eq tag 'tr)
@ -1980,7 +1997,7 @@ flags that control whether to collect or render objects."
do (setq flags nil) do (setq flags nil)
else if (car flags) else if (car flags)
do (setq recurse nil) do (setq recurse nil)
(shr-tag-table child) (shr-indirect-call 'table child)
end end end end end end end end end end end end end end end end end end end end
when recurse when recurse
append (shr-collect-extra-strings-in-table child flags))) append (shr-collect-extra-strings-in-table child flags)))

View file

@ -139,6 +139,7 @@ It is used for TCP/IP devices."
(file-remote-p . tramp-handle-file-remote-p) (file-remote-p . tramp-handle-file-remote-p)
(file-selinux-context . ignore) (file-selinux-context . ignore)
(file-symlink-p . tramp-handle-file-symlink-p) (file-symlink-p . tramp-handle-file-symlink-p)
(file-system-info . tramp-adb-handle-file-system-info)
(file-truename . tramp-adb-handle-file-truename) (file-truename . tramp-adb-handle-file-truename)
(file-writable-p . tramp-adb-handle-file-writable-p) (file-writable-p . tramp-adb-handle-file-writable-p)
(find-backup-file-name . tramp-handle-find-backup-file-name) (find-backup-file-name . tramp-handle-find-backup-file-name)
@ -255,6 +256,30 @@ pass to the OPERATION."
(file-attributes (file-truename filename))) (file-attributes (file-truename filename)))
t)) t))
(defun tramp-adb-handle-file-system-info (filename)
"Like `file-system-info' for Tramp files."
(ignore-errors
(with-parsed-tramp-file-name (expand-file-name filename) nil
(tramp-message v 5 "file system info: %s" localname)
(tramp-adb-send-command
v (format "df -k %s" (tramp-shell-quote-argument localname)))
(with-current-buffer (tramp-get-connection-buffer v)
(goto-char (point-min))
(forward-line)
(when (looking-at
(concat "[[:space:]]*[^[:space:]]+"
"[[:space:]]+\\([[:digit:]]+\\)"
"[[:space:]]+\\([[:digit:]]+\\)"
"[[:space:]]+\\([[:digit:]]+\\)"))
;; The values are given as 1k numbers, so we must change
;; them to number of bytes.
(list (* 1024 (string-to-number (concat (match-string 1) "e0")))
;; The second value is the used size. We need the
;; free size.
(* 1024 (- (string-to-number (concat (match-string 1) "e0"))
(string-to-number (concat (match-string 2) "e0"))))
(* 1024 (string-to-number (concat (match-string 3) "e0")))))))))
;; This is derived from `tramp-sh-handle-file-truename'. Maybe the ;; This is derived from `tramp-sh-handle-file-truename'. Maybe the
;; code could be shared? ;; code could be shared?
(defun tramp-adb-handle-file-truename (filename) (defun tramp-adb-handle-file-truename (filename)

View file

@ -448,6 +448,18 @@ Every entry is a list (NAME ADDRESS).")
":[[:blank:]]+\\(.*\\)$") ":[[:blank:]]+\\(.*\\)$")
"Regexp to parse GVFS file attributes with `gvfs-info'.") "Regexp to parse GVFS file attributes with `gvfs-info'.")
(defconst tramp-gvfs-file-system-attributes
'("filesystem::free"
"filesystem::size"
"filesystem::used")
"GVFS file system attributes.")
(defconst tramp-gvfs-file-system-attributes-regexp
(concat "^[[:blank:]]*"
(regexp-opt tramp-gvfs-file-system-attributes t)
":[[:blank:]]+\\(.*\\)$")
"Regexp to parse GVFS file system attributes with `gvfs-info'.")
;; New handlers should be added here. ;; New handlers should be added here.
;;;###tramp-autoload ;;;###tramp-autoload
@ -494,6 +506,7 @@ Every entry is a list (NAME ADDRESS).")
(file-remote-p . tramp-handle-file-remote-p) (file-remote-p . tramp-handle-file-remote-p)
(file-selinux-context . ignore) (file-selinux-context . ignore)
(file-symlink-p . tramp-handle-file-symlink-p) (file-symlink-p . tramp-handle-file-symlink-p)
(file-system-info . tramp-gvfs-handle-file-system-info)
(file-truename . tramp-handle-file-truename) (file-truename . tramp-handle-file-truename)
(file-writable-p . tramp-gvfs-handle-file-writable-p) (file-writable-p . tramp-gvfs-handle-file-writable-p)
(find-backup-file-name . tramp-handle-find-backup-file-name) (find-backup-file-name . tramp-handle-find-backup-file-name)
@ -825,7 +838,7 @@ file names."
(let ((last-coding-system-used last-coding-system-used) (let ((last-coding-system-used last-coding-system-used)
result) result)
(with-parsed-tramp-file-name directory nil (with-parsed-tramp-file-name directory nil
(with-tramp-file-property v localname "directory-gvfs-attributes" (with-tramp-file-property v localname "directory-attributes"
(tramp-message v 5 "directory gvfs attributes: %s" localname) (tramp-message v 5 "directory gvfs attributes: %s" localname)
;; Send command. ;; Send command.
(tramp-gvfs-send-command (tramp-gvfs-send-command
@ -860,23 +873,34 @@ file names."
(forward-line))) (forward-line)))
result))))) result)))))
(defun tramp-gvfs-get-root-attributes (filename) (defun tramp-gvfs-get-root-attributes (filename &optional file-system)
"Return GVFS attributes association list of FILENAME." "Return GVFS attributes association list of FILENAME.
If FILE-SYSTEM is non-nil, return file system attributes."
(ignore-errors (ignore-errors
;; Don't modify `last-coding-system-used' by accident. ;; Don't modify `last-coding-system-used' by accident.
(let ((last-coding-system-used last-coding-system-used) (let ((last-coding-system-used last-coding-system-used)
result) result)
(with-parsed-tramp-file-name filename nil (with-parsed-tramp-file-name filename nil
(with-tramp-file-property v localname "file-gvfs-attributes" (with-tramp-file-property
(tramp-message v 5 "file gvfs attributes: %s" localname) v localname
(if file-system "file-system-attributes" "file-attributes")
(tramp-message
v 5 "file%s gvfs attributes: %s"
(if file-system " system" "") localname)
;; Send command. ;; Send command.
(tramp-gvfs-send-command (if file-system
v "gvfs-info" (tramp-gvfs-url-file-name filename)) (tramp-gvfs-send-command
v "gvfs-info" "--filesystem" (tramp-gvfs-url-file-name filename))
(tramp-gvfs-send-command
v "gvfs-info" (tramp-gvfs-url-file-name filename)))
;; Parse output. ;; Parse output.
(with-current-buffer (tramp-get-connection-buffer v) (with-current-buffer (tramp-get-connection-buffer v)
(goto-char (point-min)) (goto-char (point-min))
(while (re-search-forward (while (re-search-forward
tramp-gvfs-file-attributes-with-gvfs-info-regexp nil t) (if file-system
tramp-gvfs-file-system-attributes-regexp
tramp-gvfs-file-attributes-with-gvfs-info-regexp)
nil t)
(push (cons (match-string 1) (match-string 2)) result)) (push (cons (match-string 1) (match-string 2)) result))
result)))))) result))))))
@ -1127,6 +1151,22 @@ file-notify events."
(with-tramp-file-property v localname "file-readable-p" (with-tramp-file-property v localname "file-readable-p"
(tramp-check-cached-permissions v ?r)))) (tramp-check-cached-permissions v ?r))))
(defun tramp-gvfs-handle-file-system-info (filename)
"Like `file-system-info' for Tramp files."
(setq filename (directory-file-name (expand-file-name filename)))
(with-parsed-tramp-file-name filename nil
;; We don't use cached values.
(tramp-set-file-property v localname "file-system-attributes" 'undef)
(let* ((attr (tramp-gvfs-get-root-attributes filename 'file-system))
(size (cdr (assoc "filesystem::size" attr)))
(used (cdr (assoc "filesystem::used" attr)))
(free (cdr (assoc "filesystem::free" attr))))
(when (and (stringp size) (stringp used) (stringp free))
(list (string-to-number (concat size "e0"))
(- (string-to-number (concat size "e0"))
(string-to-number (concat used "e0")))
(string-to-number (concat free "e0")))))))
(defun tramp-gvfs-handle-file-writable-p (filename) (defun tramp-gvfs-handle-file-writable-p (filename)
"Like `file-writable-p' for Tramp files." "Like `file-writable-p' for Tramp files."
(with-parsed-tramp-file-name filename nil (with-parsed-tramp-file-name filename nil

View file

@ -1020,6 +1020,7 @@ of command line.")
(file-remote-p . tramp-handle-file-remote-p) (file-remote-p . tramp-handle-file-remote-p)
(file-selinux-context . tramp-sh-handle-file-selinux-context) (file-selinux-context . tramp-sh-handle-file-selinux-context)
(file-symlink-p . tramp-handle-file-symlink-p) (file-symlink-p . tramp-handle-file-symlink-p)
(file-system-info . tramp-sh-handle-file-system-info)
(file-truename . tramp-sh-handle-file-truename) (file-truename . tramp-sh-handle-file-truename)
(file-writable-p . tramp-sh-handle-file-writable-p) (file-writable-p . tramp-sh-handle-file-writable-p)
(find-backup-file-name . tramp-handle-find-backup-file-name) (find-backup-file-name . tramp-handle-find-backup-file-name)
@ -2739,6 +2740,17 @@ The method used must be an out-of-band method."
beg 'noerror) beg 'noerror)
(replace-match (file-relative-name filename) t)) (replace-match (file-relative-name filename) t))
;; Try to insert the amount of free space.
(goto-char (point-min))
;; First find the line to put it on.
(when (re-search-forward "^\\([[:space:]]*total\\)" nil t)
(let ((available (get-free-disk-space ".")))
(when available
;; Replace "total" with "total used", to avoid confusion.
(replace-match "\\1 used in directory")
(end-of-line)
(insert " available " available))))
(goto-char (point-max))))))) (goto-char (point-max)))))))
;; Canonicalization of file names. ;; Canonicalization of file names.
@ -3701,6 +3713,30 @@ file-notify events."
'file-notify-handle-event 'file-notify-handle-event
`(file-notify ,object file-notify-callback))))))) `(file-notify ,object file-notify-callback)))))))
(defun tramp-sh-handle-file-system-info (filename)
"Like `file-system-info' for Tramp files."
(ignore-errors
(with-parsed-tramp-file-name (expand-file-name filename) nil
(when (tramp-get-remote-df v)
(tramp-message v 5 "file system info: %s" localname)
(tramp-send-command
v (format
"%s --block-size=1 --output=size,used,avail %s"
(tramp-get-remote-df v) (tramp-shell-quote-argument localname)))
(with-current-buffer (tramp-get-connection-buffer v)
(goto-char (point-min))
(forward-line)
(when (looking-at
(concat "[[:space:]]*\\([[:digit:]]+\\)"
"[[:space:]]+\\([[:digit:]]+\\)"
"[[:space:]]+\\([[:digit:]]+\\)"))
(list (string-to-number (concat (match-string 1) "e0"))
;; The second value is the used size. We need the
;; free size.
(- (string-to-number (concat (match-string 1) "e0"))
(string-to-number (concat (match-string 2) "e0")))
(string-to-number (concat (match-string 3) "e0")))))))))
;;; Internal Functions: ;;; Internal Functions:
(defun tramp-maybe-send-script (vec script name) (defun tramp-maybe-send-script (vec script name)
@ -5404,6 +5440,17 @@ This command is returned only if `delete-by-moving-to-trash' is non-nil."
(delete-file tmpfile)) (delete-file tmpfile))
result))) result)))
(defun tramp-get-remote-df (vec)
"Determine remote `df' command."
(with-tramp-connection-property vec "df"
(tramp-message vec 5 "Finding a suitable `df' command")
(let ((result (tramp-find-executable vec "df" (tramp-get-remote-path vec))))
(and
result
(tramp-send-command-and-check
vec (format "%s --block-size=1 --output=size,used,avail /" result))
result))))
(defun tramp-get-remote-gvfs-monitor-dir (vec) (defun tramp-get-remote-gvfs-monitor-dir (vec)
"Determine remote `gvfs-monitor-dir' command." "Determine remote `gvfs-monitor-dir' command."
(with-tramp-connection-property vec "gvfs-monitor-dir" (with-tramp-connection-property vec "gvfs-monitor-dir"

View file

@ -255,6 +255,7 @@ See `tramp-actions-before-shell' for more info.")
(file-remote-p . tramp-handle-file-remote-p) (file-remote-p . tramp-handle-file-remote-p)
;; `file-selinux-context' performed by default handler. ;; `file-selinux-context' performed by default handler.
(file-symlink-p . tramp-handle-file-symlink-p) (file-symlink-p . tramp-handle-file-symlink-p)
(file-system-info . tramp-smb-handle-file-system-info)
(file-truename . tramp-handle-file-truename) (file-truename . tramp-handle-file-truename)
(file-writable-p . tramp-smb-handle-file-writable-p) (file-writable-p . tramp-smb-handle-file-writable-p)
(find-backup-file-name . tramp-handle-find-backup-file-name) (find-backup-file-name . tramp-handle-find-backup-file-name)
@ -954,6 +955,38 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
(nth 0 x)))) (nth 0 x))))
(tramp-smb-get-file-entries directory)))))))) (tramp-smb-get-file-entries directory))))))))
(defun tramp-smb-handle-file-system-info (filename)
"Like `file-system-info' for Tramp files."
(ignore-errors
(unless (file-directory-p filename)
(setq filename (file-name-directory filename)))
(with-parsed-tramp-file-name (expand-file-name filename) nil
(tramp-message v 5 "file system info: %s" localname)
(tramp-smb-send-command v (format "du %s/*" (tramp-smb-get-localname v)))
(with-current-buffer (tramp-get-connection-buffer v)
(let (total avail blocksize)
(goto-char (point-min))
(forward-line)
(when (looking-at
(concat "[[:space:]]*\\([[:digit:]]+\\)"
" blocks of size \\([[:digit:]]+\\)"
"\\. \\([[:digit:]]+\\) blocks available"))
(setq blocksize (string-to-number (concat (match-string 2) "e0"))
total (* blocksize
(string-to-number (concat (match-string 1) "e0")))
avail (* blocksize
(string-to-number (concat (match-string 3) "e0")))))
(forward-line)
(when (looking-at "Total number of bytes: \\([[:digit:]]+\\)")
;; The used number of bytes is not part of the result. As
;; side effect, we store it as file property.
(tramp-set-file-property
v localname "used-bytes"
(string-to-number (concat (match-string 1) "e0"))))
;; Result.
(when (and total avail)
(list total (- total avail) avail)))))))
(defun tramp-smb-handle-file-writable-p (filename) (defun tramp-smb-handle-file-writable-p (filename)
"Like `file-writable-p' for Tramp files." "Like `file-writable-p' for Tramp files."
(if (file-exists-p filename) (if (file-exists-p filename)
@ -984,7 +1017,14 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
;; We should not destroy the cache entry. ;; We should not destroy the cache entry.
(entries (copy-sequence (entries (copy-sequence
(tramp-smb-get-file-entries (tramp-smb-get-file-entries
(file-name-directory filename))))) (file-name-directory filename))))
(avail (get-free-disk-space filename))
;; `get-free-disk-space' calls `file-system-info', which
;; sets file property "used-bytes" as side effect.
(used
(format
"%.0f"
(/ (tramp-get-file-property v localname "used-bytes" 0) 1024))))
(when wildcard (when wildcard
(string-match "\\." base) (string-match "\\." base)
@ -1032,6 +1072,12 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
(setcar x (concat (car x) "*")))))) (setcar x (concat (car x) "*"))))))
entries)) entries))
;; Insert size information.
(insert
(if avail
(format "total used in directory %s available %s\n" used avail)
(format "total %s\n" used)))
;; Print entries. ;; Print entries.
(mapc (mapc
(lambda (x) (lambda (x)

View file

@ -1269,14 +1269,14 @@ entry does not exist, return nil."
;;;###tramp-autoload ;;;###tramp-autoload
(defun tramp-tramp-file-p (name) (defun tramp-tramp-file-p (name)
"Return t if NAME is a string with Tramp file name syntax." "Return t if NAME is a string with Tramp file name syntax."
(save-match-data (and (stringp name)
(and (stringp name) ;; No "/:" and "/c:". This is not covered by `tramp-file-name-regexp'.
;; No "/:" and "/c:". This is not covered by `tramp-file-name-regexp'. (not (string-match-p
(not (string-match (if (memq system-type '(cygwin windows-nt))
(if (memq system-type '(cygwin windows-nt)) "^/[[:alpha:]]?:" "^/:")
"^/[[:alpha:]]?:" "^/:") name))
name)) (string-match-p tramp-file-name-regexp name)
(string-match tramp-file-name-regexp name)))) t))
(defun tramp-find-method (method user host) (defun tramp-find-method (method user host)
"Return the right method string to use. "Return the right method string to use.
@ -2079,7 +2079,9 @@ ARGS are the arguments OPERATION has been called with."
substitute-in-file-name unhandled-file-name-directory substitute-in-file-name unhandled-file-name-directory
vc-registered vc-registered
;; Emacs 26+ only. ;; Emacs 26+ only.
file-name-case-insensitive-p)) file-name-case-insensitive-p
;; Emacs 27+ only.
file-system-info))
(if (file-name-absolute-p (nth 0 args)) (if (file-name-absolute-p (nth 0 args))
(nth 0 args) (nth 0 args)
default-directory)) default-directory))

View file

@ -1,4 +1,4 @@
;; ob-ledger.el --- Babel Functions for hledger -*- lexical-binding: t; -*- ;; ob-hledger.el --- Babel Functions for hledger -*- lexical-binding: t; -*-
;; Copyright (C) 2010-2017 Free Software Foundation, Inc. ;; Copyright (C) 2010-2017 Free Software Foundation, Inc.

View file

@ -53,11 +53,15 @@ should not be inherited from a source block.")
(let* ((info (org-babel-get-src-block-info 'light)) (let* ((info (org-babel-get-src-block-info 'light))
(source-name (nth 4 info))) (source-name (nth 4 info)))
(when source-name (when source-name
(setq source-name (intern source-name) (setf (nth 1 info)
org-babel-library-of-babel (if (org-babel-noweb-p (nth 2 info) :eval)
(cons (cons source-name info) (org-babel-expand-noweb-references info)
(assq-delete-all source-name org-babel-library-of-babel)) (nth 1 info)))
lob-ingest-count (1+ lob-ingest-count))))) (let ((source (intern source-name)))
(setq org-babel-library-of-babel
(cons (cons source info)
(assq-delete-all source org-babel-library-of-babel))))
(cl-incf lob-ingest-count))))
(message "%d src block%s added to Library of Babel" (message "%d src block%s added to Library of Babel"
lob-ingest-count (if (> lob-ingest-count 1) "s" "")) lob-ingest-count (if (> lob-ingest-count 1) "s" ""))
lob-ingest-count)) lob-ingest-count))

View file

@ -2984,6 +2984,7 @@ The details of what will be saved are regulated by the variable
;; Local variables: ;; Local variables:
;; generated-autoload-file: "org-loaddefs.el" ;; generated-autoload-file: "org-loaddefs.el"
;; coding: utf-8
;; End: ;; End:
;;; org-clock.el ends here ;;; org-clock.el ends here

View file

@ -464,7 +464,8 @@ for the duration of the command.")
(kill-local-variable 'org-previous-header-line-format) (kill-local-variable 'org-previous-header-line-format)
(remove-hook 'post-command-hook 'org-columns-hscroll-title 'local)) (remove-hook 'post-command-hook 'org-columns-hscroll-title 'local))
(set-marker org-columns-begin-marker nil) (set-marker org-columns-begin-marker nil)
(set-marker org-columns-top-level-marker nil) (when (markerp org-columns-top-level-marker)
(set-marker org-columns-top-level-marker nil))
(org-with-silent-modifications (org-with-silent-modifications
(mapc #'delete-overlay org-columns-overlays) (mapc #'delete-overlay org-columns-overlays)
(setq org-columns-overlays nil) (setq org-columns-overlays nil)

View file

@ -1646,12 +1646,14 @@ In particular, this does handle wide and invisible characters."
(if (not (org-at-table-p)) (if (not (org-at-table-p))
(user-error "Not at a table")) (user-error "Not at a table"))
(let ((col (current-column)) (let ((col (current-column))
(dline (org-table-current-dline))) (dline (and (not (org-match-line org-table-hline-regexp))
(org-table-current-dline))))
(kill-region (point-at-bol) (min (1+ (point-at-eol)) (point-max))) (kill-region (point-at-bol) (min (1+ (point-at-eol)) (point-max)))
(if (not (org-at-table-p)) (beginning-of-line 0)) (if (not (org-at-table-p)) (beginning-of-line 0))
(org-move-to-column col) (org-move-to-column col)
(when (or (not org-table-fix-formulas-confirm) (when (and dline
(funcall org-table-fix-formulas-confirm "Fix formulas? ")) (or (not org-table-fix-formulas-confirm)
(funcall org-table-fix-formulas-confirm "Fix formulas? ")))
(org-table-fix-formulas "@" (list (cons (number-to-string dline) "INVALID")) (org-table-fix-formulas "@" (list (cons (number-to-string dline) "INVALID"))
dline -1 dline)))) dline -1 dline))))

View file

@ -5,13 +5,13 @@
(defun org-release () (defun org-release ()
"The release version of Org. "The release version of Org.
Inserted by installing Org mode or when a release is made." Inserted by installing Org mode or when a release is made."
(let ((org-release "9.1.1")) (let ((org-release "9.1.2"))
org-release)) org-release))
;;;###autoload ;;;###autoload
(defun org-git-version () (defun org-git-version ()
"The Git version of org-mode. "The Git version of org-mode.
Inserted by installing Org or when a release is made." Inserted by installing Org or when a release is made."
(let ((org-git-version "release_9.1.1-37-gb1e8b5")) (let ((org-git-version "release_9.1.2-40-g6ca906"))
org-git-version)) org-git-version))
(provide 'org-version) (provide 'org-version)

View file

@ -16071,7 +16071,9 @@ automatically performed, such drawers will be silently ignored."
(when (memq (org-element-type element) '(keyword node-property)) (when (memq (org-element-type element) '(keyword node-property))
(let ((value (org-element-property :value element)) (let ((value (org-element-property :value element))
(start 0)) (start 0))
(while (string-match "%[0-9]*\\(\\S-+\\)" value start) (while (string-match "%[0-9]*\\([[:alnum:]_-]+\\)\\(([^)]+)\\)?\
\\(?:{[^}]+}\\)?"
value start)
(setq start (match-end 0)) (setq start (match-end 0))
(let ((p (match-string-no-properties 1 value))) (let ((p (match-string-no-properties 1 value)))
(unless (member-ignore-case p org-special-properties) (unless (member-ignore-case p org-special-properties)
@ -19481,7 +19483,6 @@ COMMANDS is a list of alternating OLDDEF NEWDEF command names."
(org-defkey org-mode-map [(shift return)] 'org-table-copy-down) (org-defkey org-mode-map [(shift return)] 'org-table-copy-down)
(org-defkey org-mode-map [(meta shift return)] 'org-insert-todo-heading) (org-defkey org-mode-map [(meta shift return)] 'org-insert-todo-heading)
(org-defkey org-mode-map [(meta return)] 'org-meta-return)
(org-defkey org-mode-map (kbd "M-RET") #'org-meta-return) (org-defkey org-mode-map (kbd "M-RET") #'org-meta-return)
;; Cursor keys with modifiers ;; Cursor keys with modifiers
@ -24204,16 +24205,25 @@ convenience:
- On an affiliated keyword, jump to the first one. - On an affiliated keyword, jump to the first one.
- On a table or a property drawer, move to its beginning. - On a table or a property drawer, move to its beginning.
- On a verse or source block, stop before blank lines." - On comment, example, export, src and verse blocks, stop
before blank lines."
(interactive) (interactive)
(unless (bobp) (unless (bobp)
(let* ((deactivate-mark nil) (let* ((deactivate-mark nil)
(element (org-element-at-point)) (element (org-element-at-point))
(type (org-element-type element)) (type (org-element-type element))
(contents-begin (org-element-property :contents-begin element))
(contents-end (org-element-property :contents-end element)) (contents-end (org-element-property :contents-end element))
(post-affiliated (org-element-property :post-affiliated element)) (post-affiliated (org-element-property :post-affiliated element))
(begin (org-element-property :begin element))) (begin (org-element-property :begin element))
(special? ;blocks handled specially
(memq type '(comment-block example-block export-block src-block
verse-block)))
(contents-begin
(if special?
;; These types have no proper contents. Fake line
;; below the block opening line as contents beginning.
(save-excursion (goto-char begin) (line-beginning-position 2))
(org-element-property :contents-begin element))))
(cond (cond
((not element) (goto-char (point-min))) ((not element) (goto-char (point-min)))
((= (point) begin) ((= (point) begin)
@ -24224,11 +24234,8 @@ convenience:
(goto-char (org-element-property (goto-char (org-element-property
:post-affiliated (org-element-property :parent element)))) :post-affiliated (org-element-property :parent element))))
((memq type '(property-drawer table)) (goto-char begin)) ((memq type '(property-drawer table)) (goto-char begin))
((memq type '(src-block verse-block)) (special?
(when (eq type 'src-block) (if (<= (point) contents-begin) (goto-char post-affiliated)
(setq contents-begin
(save-excursion (goto-char begin) (forward-line) (point))))
(if (= (point) contents-begin) (goto-char post-affiliated)
;; Inside a verse block, see blank lines as paragraph ;; Inside a verse block, see blank lines as paragraph
;; separators. ;; separators.
(let ((origin (point))) (let ((origin (point)))
@ -24237,7 +24244,6 @@ convenience:
(skip-chars-forward " \r\t\n" origin) (skip-chars-forward " \r\t\n" origin)
(if (= (point) origin) (goto-char contents-begin) (if (= (point) origin) (goto-char contents-begin)
(beginning-of-line)))))) (beginning-of-line))))))
((not contents-begin) (goto-char (or post-affiliated begin)))
((eq type 'paragraph) ((eq type 'paragraph)
(goto-char contents-begin) (goto-char contents-begin)
;; When at first paragraph in an item or a footnote definition, ;; When at first paragraph in an item or a footnote definition,

View file

@ -174,7 +174,6 @@
(:html-klipsify-src nil nil org-html-klipsify-src) (:html-klipsify-src nil nil org-html-klipsify-src)
(:html-klipse-css nil nil org-html-klipse-css) (:html-klipse-css nil nil org-html-klipse-css)
(:html-klipse-js nil nil org-html-klipse-js) (:html-klipse-js nil nil org-html-klipse-js)
(:html-klipse-keep-old-src nil nil org-html-keep-old-src)
(:html-klipse-selection-script nil nil org-html-klipse-selection-script) (:html-klipse-selection-script nil nil org-html-klipse-selection-script)
(:infojs-opt "INFOJS_OPT" nil nil) (:infojs-opt "INFOJS_OPT" nil nil)
;; Redefine regular options. ;; Redefine regular options.
@ -1572,12 +1571,6 @@ https://developer.mozilla.org/en-US/docs/Mozilla/Mobile/Viewport_meta_tag"
:package-version '(Org . "9.1") :package-version '(Org . "9.1")
:type 'string) :type 'string)
(defcustom org-html-keep-old-src nil
"When non-nil, use <pre class=\"\"> instead of <pre><code class=\"\">."
:group 'org-export-html
:package-version '(Org . "9.1")
:type 'boolean)
;;;; Todos ;;;; Todos
@ -3402,12 +3395,16 @@ contextual information."
listing-number listing-number
(org-trim (org-export-data caption info)))))) (org-trim (org-export-data caption info))))))
;; Contents. ;; Contents.
(let ((open (if org-html-keep-old-src "<pre" "<pre><code")) (if klipsify
(close (if org-html-keep-old-src "</pre>" "</code></pre>"))) (format "<pre><code class=\"src src-%s\"%s%s>%s</code></pre>"
(format "%s class=\"src src-%s\"%s%s>%s%s" lang
open lang label (if (and klipsify (string= lang "html")) label
" data-editor-type=\"html\"" "") (if (string= lang "html")
code close))))))) " data-editor-type=\"html\""
"")
code)
(format "<pre class=\"src src-%s\"%s>%s</pre>"
lang label code)))))))
;;;; Statistics Cookie ;;;; Statistics Cookie

View file

@ -435,8 +435,8 @@ This splices all the components into the list."
(let* ((base-dir (file-name-as-directory (let* ((base-dir (file-name-as-directory
(org-publish-property :base-directory project))) (org-publish-property :base-directory project)))
(extension (or (org-publish-property :base-extension project) "org")) (extension (or (org-publish-property :base-extension project) "org"))
(match (and (not (eq extension 'any)) (match (if (eq extension 'any) ""
(concat "^[^\\.].*\\.\\(" extension "\\)$"))) (format "^[^\\.].*\\.\\(%s\\)$" extension)))
(base-files (base-files
(cl-remove-if #'file-directory-p (cl-remove-if #'file-directory-p
(if (org-publish-property :recursive project) (if (org-publish-property :recursive project)

View file

@ -132,7 +132,7 @@
;; ;;
;; 'c-not-decl ;; 'c-not-decl
;; Put on the brace which introduces a brace list and on the commas ;; Put on the brace which introduces a brace list and on the commas
;; which separate the element within it. ;; which separate the elements within it.
;; ;;
;; 'c-awk-NL-prop ;; 'c-awk-NL-prop
;; Used in AWK mode to mark the various kinds of newlines. See ;; Used in AWK mode to mark the various kinds of newlines. See
@ -5403,15 +5403,14 @@ comment at the start of cc-engine.el for more info."
(min c-bs-cache-limit pos))) (min c-bs-cache-limit pos)))
(defun c-update-brace-stack (stack from to) (defun c-update-brace-stack (stack from to)
;; Give a brace-stack which has the value STACK at position FROM, update it ;; Given a brace-stack which has the value STACK at position FROM, update it
;; to it's value at position TO, where TO is after (or equal to) FROM. ;; to its value at position TO, where TO is after (or equal to) FROM.
;; Return a cons of either TO (if it is outside a literal) and this new ;; Return a cons of either TO (if it is outside a literal) and this new
;; value, or of the next position after TO outside a literal and the new ;; value, or of the next position after TO outside a literal and the new
;; value. ;; value.
(let (match kwd-sym (prev-match-pos 1) (let (match kwd-sym (prev-match-pos 1)
(s (cdr stack)) (s (cdr stack))
(bound-<> (car stack)) (bound-<> (car stack)))
)
(save-excursion (save-excursion
(cond (cond
((and bound-<> (<= to bound-<>)) ((and bound-<> (<= to bound-<>))
@ -5472,6 +5471,9 @@ comment at the start of cc-engine.el for more info."
(setq s (cdr s)))) (setq s (cdr s))))
((c-keyword-member kwd-sym 'c-flat-decl-block-kwds) ((c-keyword-member kwd-sym 'c-flat-decl-block-kwds)
(push 0 s)))) (push 0 s))))
;; The failing `c-syntactic-re-search-forward' may have left us in the
;; middle of a token, which might be a significant token. Fix this!
(c-beginning-of-current-token)
(cons (point) (cons (point)
(cons bound-<> s))))) (cons bound-<> s)))))
@ -5647,11 +5649,13 @@ comment at the start of cc-engine.el for more info."
;; Call CFD-FUN for each possible spot for a declaration, cast or ;; Call CFD-FUN for each possible spot for a declaration, cast or
;; label from the point to CFD-LIMIT. ;; label from the point to CFD-LIMIT.
;; ;;
;; CFD-FUN is called with point at the start of the spot. It's passed two ;; CFD-FUN is called with point at the start of the spot. It's passed three
;; arguments: The first is the end position of the token preceding the spot, ;; arguments: The first is the end position of the token preceding the spot,
;; or 0 for the implicit match at bob. The second is a flag that is t when ;; or 0 for the implicit match at bob. The second is a flag that is t when
;; the match is inside a macro. Point should be moved forward by at least ;; the match is inside a macro. The third is a flag that is t when the
;; one token. ;; match is at "top level", i.e. outside any brace block, or directly inside
;; a class or namespace, etc. Point should be moved forward by at least one
;; token.
;; ;;
;; If CFD-FUN adds `c-decl-end' properties somewhere below the current spot, ;; If CFD-FUN adds `c-decl-end' properties somewhere below the current spot,
;; it should return non-nil to ensure that the next search will find them. ;; it should return non-nil to ensure that the next search will find them.
@ -6038,6 +6042,8 @@ comment at the start of cc-engine.el for more info."
(setq cfd-macro-end 0) (setq cfd-macro-end 0)
nil)))) ; end of when condition nil)))) ; end of when condition
(when (> cfd-macro-end 0)
(setq cfd-top-level nil)) ; In a macro is "never" at top level.
(c-debug-put-decl-spot-faces cfd-match-pos (point)) (c-debug-put-decl-spot-faces cfd-match-pos (point))
(if (funcall cfd-fun cfd-match-pos (/= cfd-macro-end 0) cfd-top-level) (if (funcall cfd-fun cfd-match-pos (/= cfd-macro-end 0) cfd-top-level)
(setq cfd-prop-match nil)) (setq cfd-prop-match nil))
@ -8575,7 +8581,13 @@ comment at the start of cc-engine.el for more info."
(looking-at c-noise-macro-with-parens-name-re)) (looking-at c-noise-macro-with-parens-name-re))
(c-forward-noise-clause)) (c-forward-noise-clause))
((looking-at c-type-decl-suffix-key) ((and (looking-at c-type-decl-suffix-key)
;; We avoid recognizing foo(bar) or foo() at top level as a
;; construct here in C, since we want to recognize this as a
;; typeless function declaration.
(not (and (c-major-mode-is 'c-mode)
(eq context 'top)
(eq (char-after) ?\)))))
(if (eq (char-after) ?\)) (if (eq (char-after) ?\))
(when (> paren-depth 0) (when (> paren-depth 0)
(setq paren-depth (1- paren-depth)) (setq paren-depth (1- paren-depth))
@ -8618,7 +8630,12 @@ comment at the start of cc-engine.el for more info."
(save-excursion (save-excursion
(goto-char after-paren-pos) (goto-char after-paren-pos)
(c-forward-syntactic-ws) (c-forward-syntactic-ws)
(c-forward-type))))) (or (c-forward-type)
;; Recognize a top-level typeless
;; function declaration in C.
(and (c-major-mode-is 'c-mode)
(eq context 'top)
(eq (char-after) ?\))))))))
(setq pos (c-up-list-forward (point))) (setq pos (c-up-list-forward (point)))
(eq (char-before pos) ?\))) (eq (char-before pos) ?\)))
(c-fdoc-shift-type-backward) (c-fdoc-shift-type-backward)
@ -9035,9 +9052,12 @@ comment at the start of cc-engine.el for more info."
;; (in at least C++) that anything that can be parsed as a declaration ;; (in at least C++) that anything that can be parsed as a declaration
;; is a declaration. Now we're being more defensive and prefer to ;; is a declaration. Now we're being more defensive and prefer to
;; highlight things like "foo (bar);" as a declaration only if we're ;; highlight things like "foo (bar);" as a declaration only if we're
;; inside an arglist that contains declarations. ;; inside an arglist that contains declarations. Update (2017-09): We
;; CASE 19 ;; now recognize a top-level "foo(bar);" as a declaration in C.
(eq context 'decl)))) ;; CASE 19
(or (eq context 'decl)
(and (c-major-mode-is 'c-mode)
(eq context 'top))))))
;; The point is now after the type decl expression. ;; The point is now after the type decl expression.
@ -9545,6 +9565,7 @@ Note that this function might do hidden buffer changes. See the
comment at the start of cc-engine.el for more info." comment at the start of cc-engine.el for more info."
;; Note to maintainers: this function consumes a great mass of CPU cycles. ;; Note to maintainers: this function consumes a great mass of CPU cycles.
;; Its use should thus be minimized as far as possible. ;; Its use should thus be minimized as far as possible.
;; Consider instead using `c-bs-at-toplevel-p'.
(let ((paren-state (c-parse-state))) (let ((paren-state (c-parse-state)))
(or (not (c-most-enclosing-brace paren-state)) (or (not (c-most-enclosing-brace paren-state))
(c-search-uplist-for-classkey paren-state)))) (c-search-uplist-for-classkey paren-state))))
@ -9574,8 +9595,15 @@ comment at the start of cc-engine.el for more info."
(not (and (c-major-mode-is 'objc-mode) (not (and (c-major-mode-is 'objc-mode)
(c-forward-objc-directive))) (c-forward-objc-directive)))
;; Don't confuse #if .... defined(foo) for a function arglist.
(not (and (looking-at c-cpp-expr-functions-key)
(save-excursion
(save-restriction
(widen)
(c-beginning-of-macro lim)))))
(setq id-start (setq id-start
(car-safe (c-forward-decl-or-cast-1 (c-point 'bosws) 'top nil))) (car-safe (c-forward-decl-or-cast-1 (c-point 'bosws) 'top nil)))
(numberp id-start)
(< id-start beg) (< id-start beg)
;; There should not be a '=' or ',' between beg and the ;; There should not be a '=' or ',' between beg and the

View file

@ -952,6 +952,11 @@ expression, or nil if there aren't any in the language."
'("defined")) '("defined"))
pike '("defined" "efun" "constant")) pike '("defined" "efun" "constant"))
(c-lang-defconst c-cpp-expr-functions-key
;; Matches a function in a cpp expression.
t (c-make-keywords-re t (c-lang-const c-cpp-expr-functions)))
(c-lang-defvar c-cpp-expr-functions-key (c-lang-const c-cpp-expr-functions-key))
(c-lang-defconst c-assignment-operators (c-lang-defconst c-assignment-operators
"List of all assignment operators." "List of all assignment operators."
t '("=" "*=" "/=" "%=" "+=" "-=" ">>=" "<<=" "&=" "^=" "|=") t '("=" "*=" "/=" "%=" "+=" "-=" ">>=" "<<=" "&=" "^=" "|=")

View file

@ -1571,6 +1571,8 @@ Note that this is a strict tail, so won't match, e.g. \"0x....\".")
(and (c-beginning-of-macro) (and (c-beginning-of-macro)
(progn (c-end-of-macro) (point)))))) (progn (c-end-of-macro) (point))))))
(when (and (c-forward-declarator lim) (when (and (c-forward-declarator lim)
(or (not (eq (char-after) ?\())
(c-go-list-forward nil lim))
(eq (c-forward-token-2 1 nil lim) 0)) (eq (c-forward-token-2 1 nil lim) 0))
(c-backward-syntactic-ws) (c-backward-syntactic-ws)
(point)))))) (point))))))
@ -1589,7 +1591,7 @@ Note that this is a strict tail, so won't match, e.g. \"0x....\".")
(or (c-fl-decl-start c-new-BEG) (c-point 'bol c-new-BEG)) (or (c-fl-decl-start c-new-BEG) (c-point 'bol c-new-BEG))
c-new-END c-new-END
(or (c-fl-decl-end c-new-END) (or (c-fl-decl-end c-new-END)
(c-point 'bonl (max (1- c-new-END) (point-min))))))) (c-point 'bonl c-new-END)))))
(defun c-context-expand-fl-region (beg end) (defun c-context-expand-fl-region (beg end)
;; Return a cons (NEW-BEG . NEW-END), where NEW-BEG is the beginning of a ;; Return a cons (NEW-BEG . NEW-END), where NEW-BEG is the beginning of a

View file

@ -243,7 +243,9 @@ Blank lines separate paragraphs. Semicolons start comments.
(add-hook 'xref-backend-functions #'elisp--xref-backend nil t) (add-hook 'xref-backend-functions #'elisp--xref-backend nil t)
(setq-local project-vc-external-roots-function #'elisp-load-path-roots) (setq-local project-vc-external-roots-function #'elisp-load-path-roots)
(add-hook 'completion-at-point-functions (add-hook 'completion-at-point-functions
#'elisp-completion-at-point nil 'local)) #'elisp-completion-at-point nil 'local)
(add-hook 'flymake-diagnostic-functions #'elisp-flymake-checkdoc nil t)
(add-hook 'flymake-diagnostic-functions #'elisp-flymake-byte-compile nil t))
;; Font-locking support. ;; Font-locking support.
@ -810,7 +812,7 @@ non-nil result supercedes the xrefs produced by
(apply #'nconc (apply #'nconc
(let (lst) (let (lst)
(dolist (sym (apropos-internal regexp)) (dolist (sym (apropos-internal regexp))
(push (elisp--xref-find-definitions sym) lst)) (push (elisp--xref-find-definitions sym) lst))
(nreverse lst)))) (nreverse lst))))
(defvar elisp--xref-identifier-completion-table (defvar elisp--xref-identifier-completion-table
@ -1109,7 +1111,7 @@ If CHAR is not a character, return nil."
;; interactive call would use it. ;; interactive call would use it.
;; FIXME: Is it really the right place for this? ;; FIXME: Is it really the right place for this?
(when (eq (car-safe expr) 'interactive) (when (eq (car-safe expr) 'interactive)
(setq expr (setq expr
`(call-interactively `(call-interactively
(lambda (&rest args) ,expr args)))) (lambda (&rest args) ,expr args))))
expr))))) expr)))))
@ -1174,7 +1176,7 @@ POS specifies the starting position where EXP was found and defaults to point."
(and (not (special-variable-p var)) (and (not (special-variable-p var))
(save-excursion (save-excursion
(zerop (car (syntax-ppss (match-beginning 0))))) (zerop (car (syntax-ppss (match-beginning 0)))))
(push var vars)))) (push var vars))))
`(progn ,@(mapcar (lambda (v) `(defvar ,v)) vars) ,exp))))) `(progn ,@(mapcar (lambda (v) `(defvar ,v)) vars) ,exp)))))
(defun eval-last-sexp (eval-last-sexp-arg-internal) (defun eval-last-sexp (eval-last-sexp-arg-internal)
@ -1379,7 +1381,7 @@ or elsewhere, return a 1-line docstring."
(t (help-function-arglist sym))))) (t (help-function-arglist sym)))))
;; Stringify, and store before highlighting, downcasing, etc. ;; Stringify, and store before highlighting, downcasing, etc.
(elisp--last-data-store sym (elisp-function-argstring args) (elisp--last-data-store sym (elisp-function-argstring args)
'function)))))) 'function))))))
;; Highlight, truncate. ;; Highlight, truncate.
(if argstring (if argstring
(elisp--highlight-function-argument (elisp--highlight-function-argument
@ -1588,5 +1590,164 @@ ARGLIST is either a string, or a list of strings or symbols."
(replace-match "(" t t str) (replace-match "(" t t str)
str))) str)))
;;; Flymake support
;; Don't require checkdoc, but forward declare these checkdoc special
;; variables. Autoloading them on `checkdoc-current-buffer' is too
;; late, they won't be bound dynamically.
(defvar checkdoc-create-error-function)
(defvar checkdoc-autofix-flag)
(defvar checkdoc-generate-compile-warnings-flag)
(defvar checkdoc-diagnostic-buffer)
(defun elisp-flymake--checkdoc-1 ()
"Do actual work for `elisp-flymake-checkdoc'."
(let (collected)
(let* ((checkdoc-create-error-function
(lambda (text start end &optional unfixable)
(push (list text start end unfixable) collected)
nil))
(checkdoc-autofix-flag nil)
(checkdoc-generate-compile-warnings-flag nil)
(buf (generate-new-buffer " *checkdoc-temp*"))
(checkdoc-diagnostic-buffer buf))
(unwind-protect
(save-excursion
(checkdoc-current-buffer t))
(kill-buffer buf)))
collected))
;;;###autoload
(defun elisp-flymake-checkdoc (report-fn &rest _args)
"A Flymake backend for `checkdoc'.
Calls REPORT-FN directly."
(unless (derived-mode-p 'emacs-lisp-mode)
(error "Can only work on `emacs-lisp-mode' buffers"))
(funcall report-fn
(cl-loop for (text start end _unfixable) in
(elisp-flymake--checkdoc-1)
collect
(flymake-make-diagnostic
(current-buffer)
start end :note text))))
(defun elisp-flymake--byte-compile-done (report-fn
origin-buffer
output-buffer
temp-file)
(unwind-protect
(with-current-buffer
origin-buffer
(save-excursion
(save-restriction
(widen)
(funcall
report-fn
(cl-loop with data =
(with-current-buffer output-buffer
(goto-char (point-min))
(search-forward ":elisp-flymake-output-start")
(read (point-marker)))
for (string pos _fill level) in data
do (goto-char pos)
for beg = (if (< (point) (point-max))
(point)
(line-beginning-position))
for end = (min
(line-end-position)
(or (cdr
(bounds-of-thing-at-point 'sexp))
(point-max)))
collect (flymake-make-diagnostic
(current-buffer)
(if (= beg end) (1- beg) beg)
end
level
string))))))
(kill-buffer output-buffer)
(ignore-errors (delete-file temp-file))))
(defvar-local elisp-flymake--byte-compile-process nil
"Buffer-local process started for byte-compiling the buffer.")
;;;###autoload
(defun elisp-flymake-byte-compile (report-fn &rest _args)
"A Flymake backend for elisp byte compilation.
Spawn an Emacs process that byte-compiles a file representing the
current buffer state and calls REPORT-FN when done."
(interactive (list (lambda (stuff)
(message "aha %s" stuff))))
(unless (derived-mode-p 'emacs-lisp-mode)
(error "Can only work on `emacs-lisp-mode' buffers"))
(when elisp-flymake--byte-compile-process
(process-put elisp-flymake--byte-compile-process 'elisp-flymake--obsolete t)
(when (process-live-p elisp-flymake--byte-compile-process)
(kill-process elisp-flymake--byte-compile-process)))
(let ((temp-file (make-temp-file "elisp-flymake-byte-compile"))
(origin-buffer (current-buffer)))
(save-restriction
(widen)
(write-region (point-min) (point-max) temp-file nil 'nomessage))
(let* ((output-buffer (generate-new-buffer " *elisp-flymake-byte-compile*")))
(setq
elisp-flymake--byte-compile-process
(make-process
:name "elisp-flymake-byte-compile"
:buffer output-buffer
:command (list (expand-file-name invocation-name invocation-directory)
"-Q"
"--batch"
;; "--eval" "(setq load-prefer-newer t)" ; for testing
"-L" default-directory
"-f" "elisp-flymake--batch-compile-for-flymake"
temp-file)
:connection-type 'pipe
:sentinel
(lambda (proc _event)
(unless (process-live-p proc)
(unwind-protect
(cond
((zerop (process-exit-status proc))
(elisp-flymake--byte-compile-done report-fn
origin-buffer
output-buffer
temp-file))
((process-get proc 'elisp-flymake--obsolete)
(flymake-log :warning "byte-compile process %s obsolete" proc))
(t
(funcall report-fn
:panic
:explanation
(format "byte-compile process %s died" proc)))))))))
:stderr null-device
:noquery t)))
(defun elisp-flymake--batch-compile-for-flymake (&optional file)
"Helper for `elisp-flymake-byte-compile'.
Runs in a batch-mode Emacs. Interactively use variable
`buffer-file-name' for FILE."
(interactive (list buffer-file-name))
(let* ((file (or file
(car command-line-args-left)))
(dummy-elc-file)
(byte-compile-log-buffer
(generate-new-buffer " *dummy-byte-compile-log-buffer*"))
(byte-compile-dest-file-function
(lambda (source)
(setq dummy-elc-file (make-temp-file (file-name-nondirectory source)))))
(collected)
(byte-compile-log-warning-function
(lambda (string &optional position fill level)
(push (list string position fill level)
collected)
t)))
(unwind-protect
(byte-compile-file file)
(ignore-errors
(delete-file dummy-elc-file)
(kill-buffer byte-compile-log-buffer)))
(prin1 :elisp-flymake-output-start)
(terpri)
(pp collected)))
(provide 'elisp-mode) (provide 'elisp-mode)
;;; elisp-mode.el ends here ;;; elisp-mode.el ends here

File diff suppressed because it is too large Load diff

View file

@ -1,634 +0,0 @@
;;; flymake-ui.el --- A universal on-the-fly syntax checker -*- lexical-binding: t; -*-
;; Copyright (C) 2003-2017 Free Software Foundation, Inc.
;; Author: Pavel Kobyakov <pk_at_work@yahoo.com>
;; Maintainer: Leo Liu <sdl.web@gmail.com>
;; Version: 0.3
;; Keywords: c languages tools
;; This file is part of GNU Emacs.
;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
;;
;; Flymake is a minor Emacs mode performing on-the-fly syntax checks.xo
;;
;; This file contains the UI for displaying and interacting with the
;; results of such checks, as well as entry points for backends to
;; hook on to. Backends are sources of diagnostic info.
;;
;;; Code:
(eval-when-compile (require 'cl-lib))
(defgroup flymake nil
"Universal on-the-fly syntax checker."
:version "23.1"
:link '(custom-manual "(flymake) Top")
:group 'tools)
(defcustom flymake-error-bitmap '(exclamation-mark error)
"Bitmap (a symbol) used in the fringe for indicating errors.
The value may also be a list of two elements where the second
element specifies the face for the bitmap. For possible bitmap
symbols, see `fringe-bitmaps'. See also `flymake-warning-bitmap'.
The option `flymake-fringe-indicator-position' controls how and where
this is used."
:group 'flymake
:version "24.3"
:type '(choice (symbol :tag "Bitmap")
(list :tag "Bitmap and face"
(symbol :tag "Bitmap")
(face :tag "Face"))))
(defcustom flymake-warning-bitmap 'question-mark
"Bitmap (a symbol) used in the fringe for indicating warnings.
The value may also be a list of two elements where the second
element specifies the face for the bitmap. For possible bitmap
symbols, see `fringe-bitmaps'. See also `flymake-error-bitmap'.
The option `flymake-fringe-indicator-position' controls how and where
this is used."
:group 'flymake
:version "24.3"
:type '(choice (symbol :tag "Bitmap")
(list :tag "Bitmap and face"
(symbol :tag "Bitmap")
(face :tag "Face"))))
(defcustom flymake-fringe-indicator-position 'left-fringe
"The position to put flymake fringe indicator.
The value can be nil (do not use indicators), `left-fringe' or `right-fringe'.
See `flymake-error-bitmap' and `flymake-warning-bitmap'."
:group 'flymake
:version "24.3"
:type '(choice (const left-fringe)
(const right-fringe)
(const :tag "No fringe indicators" nil)))
(defcustom flymake-start-syntax-check-on-newline t
"Start syntax check if newline char was added/removed from the buffer."
:group 'flymake
:type 'boolean)
(defcustom flymake-no-changes-timeout 0.5
"Time to wait after last change before starting compilation."
:group 'flymake
:type 'number)
(defcustom flymake-gui-warnings-enabled t
"Enables/disables GUI warnings."
:group 'flymake
:type 'boolean)
(make-obsolete-variable 'flymake-gui-warnings-enabled
"it no longer has any effect." "26.1")
(defcustom flymake-start-syntax-check-on-find-file t
"Start syntax check on find file."
:group 'flymake
:type 'boolean)
(defcustom flymake-log-level -1
"Logging level, only messages with level lower or equal will be logged.
-1 = NONE, 0 = ERROR, 1 = WARNING, 2 = INFO, 3 = DEBUG"
:group 'flymake
:type 'integer)
(defcustom flymake-backends '()
"Ordered list of backends providing syntax check information for a buffer.
Value is an alist of conses (PREDICATE . CHECKER). Both PREDICATE
and CHECKER are functions called with a single argument, the
buffer in which `flymake-mode' was enabled. PREDICATE is expected
to (quickly) return t or nil if the buffer can be syntax checked
by CHECKER, which in can performs more morose operations,
possibly asynchronously."
:group 'flymake
:type 'alist)
(defvar-local flymake-timer nil
"Timer for starting syntax check.")
(defvar-local flymake-last-change-time nil
"Time of last buffer change.")
(defvar-local flymake-check-start-time nil
"Time at which syntax check was started.")
(defvar-local flymake-check-was-interrupted nil
"Non-nil if syntax check was killed by `flymake-compile'.")
(defvar-local flymake-err-info nil
"Sorted list of line numbers and lists of err info in the form (file, err-text).")
(defvar-local flymake-new-err-info nil
"Same as `flymake-err-info', effective when a syntax check is in progress.")
(defun flymake-log (level text &rest args)
"Log a message at level LEVEL.
If LEVEL is higher than `flymake-log-level', the message is
ignored. Otherwise, it is printed using `message'.
TEXT is a format control string, and the remaining arguments ARGS
are the string substitutions (see the function `format')."
(if (<= level flymake-log-level)
(let* ((msg (apply #'format-message text args)))
(message "%s" msg))))
(defun flymake-ins-after (list pos val)
"Insert VAL into LIST after position POS.
POS counts from zero."
(let ((tmp (copy-sequence list)))
(setcdr (nthcdr pos tmp) (cons val (nthcdr (1+ pos) tmp)))
tmp))
(defun flymake-set-at (list pos val)
"Set VAL at position POS in LIST.
POS counts from zero."
(let ((tmp (copy-sequence list)))
(setcar (nthcdr pos tmp) val)
tmp))
(defun flymake-er-make-er (line-no line-err-info-list)
(list line-no line-err-info-list))
(defun flymake-er-get-line (err-info)
(nth 0 err-info))
(defun flymake-er-get-line-err-info-list (err-info)
(nth 1 err-info))
(cl-defstruct (flymake-ler
(:constructor nil)
(:constructor flymake-ler-make-ler (file line type text &optional full-file)))
file line type text full-file)
(defun flymake-ler-set-file (line-err-info file)
(flymake-ler-make-ler file
(flymake-ler-line line-err-info)
(flymake-ler-type line-err-info)
(flymake-ler-text line-err-info)
(flymake-ler-full-file line-err-info)))
(defun flymake-ler-set-full-file (line-err-info full-file)
(flymake-ler-make-ler (flymake-ler-file line-err-info)
(flymake-ler-line line-err-info)
(flymake-ler-type line-err-info)
(flymake-ler-text line-err-info)
full-file))
(defun flymake-ler-set-line (line-err-info line)
(flymake-ler-make-ler (flymake-ler-file line-err-info)
line
(flymake-ler-type line-err-info)
(flymake-ler-text line-err-info)
(flymake-ler-full-file line-err-info)))
(defun flymake-get-line-err-count (line-err-info-list type)
"Return number of errors of specified TYPE.
Value of TYPE is either \"e\" or \"w\"."
(let* ((idx 0)
(count (length line-err-info-list))
(err-count 0))
(while (< idx count)
(when (equal type (flymake-ler-type (nth idx line-err-info-list)))
(setq err-count (1+ err-count)))
(setq idx (1+ idx)))
err-count))
(defun flymake-get-err-count (err-info-list type)
"Return number of errors of specified TYPE for ERR-INFO-LIST."
(let* ((idx 0)
(count (length err-info-list))
(err-count 0))
(while (< idx count)
(setq err-count (+ err-count (flymake-get-line-err-count (nth 1 (nth idx err-info-list)) type)))
(setq idx (1+ idx)))
err-count))
(defun flymake-highlight-err-lines (err-info-list)
"Highlight error lines in BUFFER using info from ERR-INFO-LIST."
(save-excursion
(dolist (err err-info-list)
(flymake-highlight-line (car err) (nth 1 err)))))
(defun flymake-overlay-p (ov)
"Determine whether overlay OV was created by flymake."
(and (overlayp ov) (overlay-get ov 'flymake-overlay)))
(defun flymake-make-overlay (beg end tooltip-text face bitmap)
"Allocate a flymake overlay in range BEG and END."
(when (not (flymake-region-has-flymake-overlays beg end))
(let ((ov (make-overlay beg end nil t))
(fringe (and flymake-fringe-indicator-position
(propertize "!" 'display
(cons flymake-fringe-indicator-position
(if (listp bitmap)
bitmap
(list bitmap)))))))
(overlay-put ov 'face face)
(overlay-put ov 'help-echo tooltip-text)
(overlay-put ov 'flymake-overlay t)
(overlay-put ov 'priority 100)
(overlay-put ov 'evaporate t)
(overlay-put ov 'before-string fringe)
;;+(flymake-log 3 "created overlay %s" ov)
ov)
(flymake-log 3 "created an overlay at (%d-%d)" beg end)))
(defun flymake-delete-own-overlays ()
"Delete all flymake overlays in BUFFER."
(dolist (ol (overlays-in (point-min) (point-max)))
(when (flymake-overlay-p ol)
(delete-overlay ol)
;;+(flymake-log 3 "deleted overlay %s" ol)
)))
(defun flymake-region-has-flymake-overlays (beg end)
"Check if region specified by BEG and END has overlay.
Return t if it has at least one flymake overlay, nil if no overlay."
(let ((ov (overlays-in beg end))
(has-flymake-overlays nil))
(while (consp ov)
(when (flymake-overlay-p (car ov))
(setq has-flymake-overlays t))
(setq ov (cdr ov)))
has-flymake-overlays))
(defface flymake-errline
'((((supports :underline (:style wave)))
:underline (:style wave :color "Red1"))
(t
:inherit error))
"Face used for marking error lines."
:version "24.4"
:group 'flymake)
(defface flymake-warnline
'((((supports :underline (:style wave)))
:underline (:style wave :color "DarkOrange"))
(t
:inherit warning))
"Face used for marking warning lines."
:version "24.4"
:group 'flymake)
(defun flymake-highlight-line (line-no line-err-info-list)
"Highlight line LINE-NO in current buffer.
Perhaps use text from LINE-ERR-INFO-LIST to enhance highlighting."
(goto-char (point-min))
(forward-line (1- line-no))
(pcase-let* ((beg (progn (back-to-indentation) (point)))
(end (progn
(end-of-line)
(skip-chars-backward " \t\f\t\n" beg)
(if (eq (point) beg)
(line-beginning-position 2)
(point))))
(tooltip-text (mapconcat #'flymake-ler-text line-err-info-list "\n"))
(`(,face ,bitmap)
(if (> (flymake-get-line-err-count line-err-info-list "e") 0)
(list 'flymake-errline flymake-error-bitmap)
(list 'flymake-warnline flymake-warning-bitmap))))
(flymake-make-overlay beg end tooltip-text face bitmap)))
(defun flymake-find-err-info (err-info-list line-no)
"Find (line-err-info-list pos) for specified LINE-NO."
(if err-info-list
(let* ((line-err-info-list nil)
(pos 0)
(count (length err-info-list)))
(while (and (< pos count) (< (car (nth pos err-info-list)) line-no))
(setq pos (1+ pos)))
(when (and (< pos count) (equal (car (nth pos err-info-list)) line-no))
(setq line-err-info-list (flymake-er-get-line-err-info-list (nth pos err-info-list))))
(list line-err-info-list pos))
'(nil 0)))
(defun flymake-line-err-info-is-less-or-equal (line-one line-two)
(or (string< (flymake-ler-type line-one) (flymake-ler-type line-two))
(and (string= (flymake-ler-type line-one) (flymake-ler-type line-two))
(not (flymake-ler-file line-one)) (flymake-ler-file line-two))
(and (string= (flymake-ler-type line-one) (flymake-ler-type line-two))
(or (and (flymake-ler-file line-one) (flymake-ler-file line-two))
(and (not (flymake-ler-file line-one)) (not (flymake-ler-file line-two)))))))
(defun flymake-add-line-err-info (line-err-info-list line-err-info)
"Update LINE-ERR-INFO-LIST with the error LINE-ERR-INFO.
For the format of LINE-ERR-INFO, see `flymake-ler-make-ler'.
The new element is inserted in the proper position, according to
the predicate `flymake-line-err-info-is-less-or-equal'.
The updated value of LINE-ERR-INFO-LIST is returned."
(if (not line-err-info-list)
(list line-err-info)
(let* ((count (length line-err-info-list))
(idx 0))
(while (and (< idx count) (flymake-line-err-info-is-less-or-equal (nth idx line-err-info-list) line-err-info))
(setq idx (1+ idx)))
(cond ((equal 0 idx) (setq line-err-info-list (cons line-err-info line-err-info-list)))
(t (setq line-err-info-list (flymake-ins-after line-err-info-list (1- idx) line-err-info))))
line-err-info-list)))
(defun flymake-add-err-info (err-info-list line-err-info)
"Update ERR-INFO-LIST with the error LINE-ERR-INFO, preserving sort order.
Returns the updated value of ERR-INFO-LIST.
For the format of ERR-INFO-LIST, see `flymake-err-info'.
For the format of LINE-ERR-INFO, see `flymake-ler-make-ler'."
(let* ((line-no (if (flymake-ler-file line-err-info) 1 (flymake-ler-line line-err-info)))
(info-and-pos (flymake-find-err-info err-info-list line-no))
(exists (car info-and-pos))
(pos (nth 1 info-and-pos))
(line-err-info-list nil)
(err-info nil))
(if exists
(setq line-err-info-list (flymake-er-get-line-err-info-list (car (nthcdr pos err-info-list)))))
(setq line-err-info-list (flymake-add-line-err-info line-err-info-list line-err-info))
(setq err-info (flymake-er-make-er line-no line-err-info-list))
(cond (exists (setq err-info-list (flymake-set-at err-info-list pos err-info)))
((equal 0 pos) (setq err-info-list (cons err-info err-info-list)))
(t (setq err-info-list (flymake-ins-after err-info-list (1- pos) err-info))))
err-info-list))
(defvar-local flymake-is-running nil
"If t, flymake syntax check process is running for the current buffer.")
(defun flymake-on-timer-event (buffer)
"Start a syntax check for buffer BUFFER if necessary."
(when (buffer-live-p buffer)
(with-current-buffer buffer
(when (and (not flymake-is-running)
flymake-last-change-time
(> (- (float-time) flymake-last-change-time)
flymake-no-changes-timeout))
(setq flymake-last-change-time nil)
(flymake-log 3 "starting syntax check as more than 1 second passed since last change")
(flymake--start-syntax-check)))))
(define-obsolete-function-alias 'flymake-display-err-menu-for-current-line
'flymake-popup-current-error-menu "24.4")
(defun flymake-popup-current-error-menu (&optional event)
"Pop up a menu with errors/warnings for current line."
(interactive (list last-nonmenu-event))
(let* ((line-no (line-number-at-pos))
(errors (or (car (flymake-find-err-info flymake-err-info line-no))
(user-error "No errors for current line")))
(menu (mapcar (lambda (x)
(if (flymake-ler-file x)
(cons (format "%s - %s(%d)"
(flymake-ler-text x)
(flymake-ler-file x)
(flymake-ler-line x))
x)
(list (flymake-ler-text x))))
errors))
(event (if (mouse-event-p event)
event
(list 'mouse-1 (posn-at-point))))
(title (format "Line %d: %d error(s), %d warning(s)"
line-no
(flymake-get-line-err-count errors "e")
(flymake-get-line-err-count errors "w")))
(choice (x-popup-menu event (list title (cons "" menu)))))
(flymake-log 3 "choice=%s" choice)
(when choice
(flymake-goto-file-and-line (flymake-ler-full-file choice)
(flymake-ler-line choice)))))
(defun flymake-goto-file-and-line (file line)
"Try to get buffer for FILE and goto line LINE in it."
(if (not (file-exists-p file))
(flymake-log 1 "File %s does not exist" file)
(find-file file)
(goto-char (point-min))
(forward-line (1- line))))
;; flymake minor mode declarations
(defvar-local flymake-mode-line nil)
(defvar-local flymake-mode-line-e-w nil)
(defvar-local flymake-mode-line-status nil)
(defun flymake-report-status (e-w &optional status)
"Show status in mode line."
(when e-w
(setq flymake-mode-line-e-w e-w))
(when status
(setq flymake-mode-line-status status))
(let* ((mode-line " Flymake"))
(when (> (length flymake-mode-line-e-w) 0)
(setq mode-line (concat mode-line ":" flymake-mode-line-e-w)))
(setq mode-line (concat mode-line flymake-mode-line-status))
(setq flymake-mode-line mode-line)
(force-mode-line-update)))
;; Nothing in flymake uses this at all any more, so this is just for
;; third-party compatibility.
(define-obsolete-function-alias 'flymake-display-warning 'message-box "26.1")
(defun flymake-report-fatal-status (status warning)
"Display a warning and switch flymake mode off."
;; This first message was always shown by default, and flymake-log
;; does nothing by default, hence the use of message.
;; Another option is display-warning.
(if (< flymake-log-level 0)
(message "Flymake: %s. Flymake will be switched OFF" warning))
(flymake-mode 0)
(flymake-log 0 "switched OFF Flymake mode for buffer %s due to fatal status %s, warning %s"
(buffer-name) status warning))
(defvar-local flymake--backend nil
"The currently active backend selected by `flymake-mode'")
(defun flymake--can-syntax-check-buffer (buffer)
(let ((all flymake-backends)
(candidate))
(catch 'done
(while (setq candidate (pop all))
(when (with-current-buffer buffer (funcall (car candidate)))
(throw 'done (cdr candidate)))))))
(defun flymake--start-syntax-check ()
(funcall flymake--backend))
;;;###autoload
(define-minor-mode flymake-mode nil
:group 'flymake :lighter flymake-mode-line
(cond
;; Turning the mode ON.
(flymake-mode
(let* ((backend (flymake--can-syntax-check-buffer (current-buffer))))
(cond
((not backend)
(flymake-log 2 "flymake cannot check syntax in buffer %s" (buffer-name)))
(t
(setq flymake--backend backend)
(add-hook 'after-change-functions 'flymake-after-change-function nil t)
(add-hook 'after-save-hook 'flymake-after-save-hook nil t)
(add-hook 'kill-buffer-hook 'flymake-kill-buffer-hook nil t)
;;+(add-hook 'find-file-hook 'flymake-find-file-hook)
(flymake-report-status "" "")
(setq flymake-timer
(run-at-time nil 1 'flymake-on-timer-event (current-buffer)))
(when (and flymake-start-syntax-check-on-find-file
;; Since we write temp files in current dir, there's no point
;; trying if the directory is read-only (bug#8954).
(file-writable-p (file-name-directory buffer-file-name)))
(with-demoted-errors
(flymake--start-syntax-check)))))
)
)
;; Turning the mode OFF.
(t
(setq flymake--backend nil)
(remove-hook 'after-change-functions 'flymake-after-change-function t)
(remove-hook 'after-save-hook 'flymake-after-save-hook t)
(remove-hook 'kill-buffer-hook 'flymake-kill-buffer-hook t)
;;+(remove-hook 'find-file-hook (function flymake-find-file-hook) t)
(flymake-delete-own-overlays)
(when flymake-timer
(cancel-timer flymake-timer)
(setq flymake-timer nil))
(setq flymake-is-running nil))))
;; disabling flymake-mode is safe, enabling - not necessarily so
(put 'flymake-mode 'safe-local-variable 'null)
;;;###autoload
(defun flymake-mode-on ()
"Turn flymake mode on."
(flymake-mode 1)
(flymake-log 1 "flymake mode turned ON for buffer %s" (buffer-name)))
;;;###autoload
(defun flymake-mode-off ()
"Turn flymake mode off."
(flymake-mode 0)
(flymake-log 1 "flymake mode turned OFF for buffer %s" (buffer-name)))
(defun flymake-after-change-function (start stop _len)
"Start syntax check for current buffer if it isn't already running."
;;+(flymake-log 0 "setting change time to %s" (float-time))
(let((new-text (buffer-substring start stop)))
(when (and flymake-start-syntax-check-on-newline (equal new-text "\n"))
(flymake-log 3 "starting syntax check as new-line has been seen")
(flymake--start-syntax-check))
(setq flymake-last-change-time (float-time))))
(defun flymake-after-save-hook ()
(if (local-variable-p 'flymake-mode (current-buffer)) ; (???) other way to determine whether flymake is active in buffer being saved?
(progn
(flymake-log 3 "starting syntax check as buffer was saved")
(flymake--start-syntax-check)))) ; no more mode 3. cannot start check if mode 3 (to temp copies) is active - (???)
(defun flymake-kill-buffer-hook ()
(when flymake-timer
(cancel-timer flymake-timer)
(setq flymake-timer nil)))
;;;###autoload
(defun flymake-find-file-hook ()
;;+(when flymake-start-syntax-check-on-find-file
;;+ (flymake-log 3 "starting syntax check on file open")
;;+ (flymake--start-syntax-check)
;;+)
(when (and (not (local-variable-p 'flymake-mode (current-buffer)))
(flymake--can-syntax-check-buffer (current-buffer)))
(flymake-mode)
(flymake-log 3 "automatically turned ON flymake mode")))
(defun flymake-get-first-err-line-no (err-info-list)
"Return first line with error."
(when err-info-list
(flymake-er-get-line (car err-info-list))))
(defun flymake-get-last-err-line-no (err-info-list)
"Return last line with error."
(when err-info-list
(flymake-er-get-line (nth (1- (length err-info-list)) err-info-list))))
(defun flymake-get-next-err-line-no (err-info-list line-no)
"Return next line with error."
(when err-info-list
(let* ((count (length err-info-list))
(idx 0))
(while (and (< idx count) (>= line-no (flymake-er-get-line (nth idx err-info-list))))
(setq idx (1+ idx)))
(if (< idx count)
(flymake-er-get-line (nth idx err-info-list))))))
(defun flymake-get-prev-err-line-no (err-info-list line-no)
"Return previous line with error."
(when err-info-list
(let* ((count (length err-info-list)))
(while (and (> count 0) (<= line-no (flymake-er-get-line (nth (1- count) err-info-list))))
(setq count (1- count)))
(if (> count 0)
(flymake-er-get-line (nth (1- count) err-info-list))))))
(defun flymake-skip-whitespace ()
"Move forward until non-whitespace is reached."
(while (looking-at "[ \t]")
(forward-char)))
(defun flymake-goto-line (line-no)
"Go to line LINE-NO, then skip whitespace."
(goto-char (point-min))
(forward-line (1- line-no))
(flymake-skip-whitespace))
(defun flymake-goto-next-error ()
"Go to next error in err ring."
(interactive)
(let ((line-no (flymake-get-next-err-line-no flymake-err-info (line-number-at-pos))))
(when (not line-no)
(setq line-no (flymake-get-first-err-line-no flymake-err-info))
(flymake-log 1 "passed end of file"))
(if line-no
(flymake-goto-line line-no)
(flymake-log 1 "no errors in current buffer"))))
(defun flymake-goto-prev-error ()
"Go to previous error in err ring."
(interactive)
(let ((line-no (flymake-get-prev-err-line-no flymake-err-info (line-number-at-pos))))
(when (not line-no)
(setq line-no (flymake-get-last-err-line-no flymake-err-info))
(flymake-log 1 "passed beginning of file"))
(if line-no
(flymake-goto-line line-no)
(flymake-log 1 "no errors in current buffer"))))
(defun flymake-patch-err-text (string)
(if (string-match "^[\n\t :0-9]*\\(.*\\)$" string)
(match-string 1 string)
string))
(provide 'flymake-ui)
;;; flymake-ui.el ends here

View file

@ -1,4 +1,4 @@
;;; flymake.el --- a universal on-the-fly syntax checker -*- lexical-binding: t; -*- ;;; flymake.el --- A universal on-the-fly syntax checker -*- lexical-binding: t; -*-
;; Copyright (C) 2003-2017 Free Software Foundation, Inc. ;; Copyright (C) 2003-2017 Free Software Foundation, Inc.
@ -20,22 +20,964 @@
;; GNU General Public License for more details. ;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License ;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary: ;;; Commentary:
;; ;;
;; Flymake is a minor Emacs mode performing on-the-fly syntax checks. ;; Flymake is a minor Emacs mode performing on-the-fly syntax checks.
;; ;;
;; It collects diagnostic information for multiple sources and ;; Flymake collects diagnostic information for multiple sources,
;; visually annotates the relevant lines in the buffer. ;; called backends, and visually annotates the relevant portions in
;; the buffer.
;;
;; This file contains the UI for displaying and interacting with the
;; results produced by these backends, as well as entry points for
;; backends to hook on to.
;;
;; The main entry points are `flymake-mode' and `flymake-start'
;;
;; The docstrings of these variables are relevant to understanding how
;; Flymake works for both the user and the backend programmer:
;;
;; * `flymake-diagnostic-functions'
;; * `flymake-diagnostic-types-alist'
;; ;;
;; This file is just a stub for that loads the UI and backends, which
;; could also be loaded separately.
;;; Code: ;;; Code:
(require 'flymake-ui) (require 'cl-lib)
(require 'flymake-proc) (require 'thingatpt) ; end-of-thing
(require 'warnings) ; warning-numeric-level, display-warning
(require 'compile) ; for some faces
(require 'subr-x) ; when-let*, if-let*, hash-table-keys, hash-table-values
(defgroup flymake nil
"Universal on-the-fly syntax checker."
:version "23.1"
:link '(custom-manual "(flymake) Top")
:group 'tools)
(defcustom flymake-error-bitmap '(flymake-double-exclamation-mark
compilation-error)
"Bitmap (a symbol) used in the fringe for indicating errors.
The value may also be a list of two elements where the second
element specifies the face for the bitmap. For possible bitmap
symbols, see `fringe-bitmaps'. See also `flymake-warning-bitmap'.
The option `flymake-fringe-indicator-position' controls how and where
this is used."
:version "24.3"
:type '(choice (symbol :tag "Bitmap")
(list :tag "Bitmap and face"
(symbol :tag "Bitmap")
(face :tag "Face"))))
(defcustom flymake-warning-bitmap '(exclamation-mark compilation-warning)
"Bitmap (a symbol) used in the fringe for indicating warnings.
The value may also be a list of two elements where the second
element specifies the face for the bitmap. For possible bitmap
symbols, see `fringe-bitmaps'. See also `flymake-error-bitmap'.
The option `flymake-fringe-indicator-position' controls how and where
this is used."
:version "24.3"
:type '(choice (symbol :tag "Bitmap")
(list :tag "Bitmap and face"
(symbol :tag "Bitmap")
(face :tag "Face"))))
(defcustom flymake-note-bitmap '(exclamation-mark compilation-info)
"Bitmap (a symbol) used in the fringe for indicating info notes.
The value may also be a list of two elements where the second
element specifies the face for the bitmap. For possible bitmap
symbols, see `fringe-bitmaps'. See also `flymake-error-bitmap'.
The option `flymake-fringe-indicator-position' controls how and where
this is used."
:version "26.1"
:type '(choice (symbol :tag "Bitmap")
(list :tag "Bitmap and face"
(symbol :tag "Bitmap")
(face :tag "Face"))))
(defcustom flymake-fringe-indicator-position 'left-fringe
"The position to put Flymake fringe indicator.
The value can be nil (do not use indicators), `left-fringe' or `right-fringe'.
See `flymake-error-bitmap' and `flymake-warning-bitmap'."
:version "24.3"
:type '(choice (const left-fringe)
(const right-fringe)
(const :tag "No fringe indicators" nil)))
(defcustom flymake-start-syntax-check-on-newline t
"Start syntax check if newline char was added/removed from the buffer."
:type 'boolean)
(defcustom flymake-no-changes-timeout 0.5
"Time to wait after last change before automatically checking buffer.
If nil, never start checking buffer automatically like this."
:type 'number)
(defcustom flymake-gui-warnings-enabled t
"Enables/disables GUI warnings."
:type 'boolean)
(make-obsolete-variable 'flymake-gui-warnings-enabled
"it no longer has any effect." "26.1")
(defcustom flymake-start-syntax-check-on-find-file t
"Start syntax check on find file."
:type 'boolean)
(defcustom flymake-log-level -1
"Obsolete and ignored variable."
:type 'integer)
(make-obsolete-variable 'flymake-log-level
"it is superseded by `warning-minimum-log-level.'"
"26.1")
(defcustom flymake-wrap-around t
"If non-nil, moving to errors wraps around buffer boundaries."
:type 'boolean)
(define-fringe-bitmap 'flymake-double-exclamation-mark
(vector #b00000000
#b00000000
#b00000000
#b00000000
#b01100110
#b01100110
#b01100110
#b01100110
#b01100110
#b01100110
#b01100110
#b01100110
#b00000000
#b01100110
#b00000000
#b00000000
#b00000000))
(defvar-local flymake-timer nil
"Timer for starting syntax check.")
(defvar-local flymake-check-start-time nil
"Time at which syntax check was started.")
(defun flymake--log-1 (level sublog msg &rest args)
"Do actual work for `flymake-log'."
(let (;; never popup the log buffer
(warning-minimum-level :emergency)
(warning-type-format
(format " [%s %s]"
(or sublog 'flymake)
(current-buffer))))
(display-warning (list 'flymake sublog)
(apply #'format-message msg args)
(if (numberp level)
(or (nth level
'(:emergency :error :warning :debug :debug) )
:error)
level)
"*Flymake log*")))
(defun flymake-switch-to-log-buffer ()
"Go to the *Flymake log* buffer."
(interactive)
(switch-to-buffer "*Flymake log*"))
;;;###autoload
(defmacro flymake-log (level msg &rest args)
"Log, at level LEVEL, the message MSG formatted with ARGS.
LEVEL is passed to `display-warning', which is used to display
the warning. If this form is included in a byte-compiled file,
the generated warning contains an indication of the file that
generated it."
(let* ((compile-file (and (boundp 'byte-compile-current-file)
(symbol-value 'byte-compile-current-file)))
(sublog (if (and
compile-file
(not load-file-name))
(intern
(file-name-nondirectory
(file-name-sans-extension compile-file))))))
`(flymake--log-1 ,level ',sublog ,msg ,@args)))
(defun flymake-error (text &rest args)
"Format TEXT with ARGS and signal an error for Flymake."
(let ((msg (apply #'format-message text args)))
(flymake-log :error msg)
(error (concat "[Flymake] " msg))))
(cl-defstruct (flymake--diag
(:constructor flymake--diag-make))
buffer beg end type text backend)
;;;###autoload
(defun flymake-make-diagnostic (buffer
beg
end
type
text)
"Make a Flymake diagnostic for BUFFER's region from BEG to END.
TYPE is a key to `flymake-diagnostic-types-alist' and TEXT is a
description of the problem detected in this region."
(flymake--diag-make :buffer buffer :beg beg :end end :type type :text text))
(cl-defun flymake--overlays (&key beg end filter compare key)
"Get flymake-related overlays.
If BEG is non-nil and END is nil, consider only `overlays-at'
BEG. Otherwise consider `overlays-in' the region comprised by BEG
and END, defaulting to the whole buffer. Remove all that do not
verify FILTER, a function, and sort them by COMPARE (using KEY)."
(save-restriction
(widen)
(let ((ovs (cl-remove-if-not
(lambda (ov)
(and (overlay-get ov 'flymake)
(or (not filter)
(funcall filter ov))))
(if (and beg (null end))
(overlays-at beg t)
(overlays-in (or beg (point-min))
(or end (point-max)))))))
(if compare
(cl-sort ovs compare :key (or key
#'identity))
ovs))))
(defun flymake-delete-own-overlays (&optional filter)
"Delete all Flymake overlays in BUFFER."
(mapc #'delete-overlay (flymake--overlays :filter filter)))
(defface flymake-error
'((((supports :underline (:style wave)))
:underline (:style wave :color "Red1"))
(t
:inherit error))
"Face used for marking error regions."
:version "24.4")
(defface flymake-warning
'((((supports :underline (:style wave)))
:underline (:style wave :color "deep sky blue"))
(t
:inherit warning))
"Face used for marking warning regions."
:version "24.4")
(defface flymake-note
'((((supports :underline (:style wave)))
:underline (:style wave :color "yellow green"))
(t
:inherit warning))
"Face used for marking note regions."
:version "26.1")
(define-obsolete-face-alias 'flymake-warnline 'flymake-warning "26.1")
(define-obsolete-face-alias 'flymake-errline 'flymake-error "26.1")
;;;###autoload
(defun flymake-diag-region (buffer line &optional col)
"Compute BUFFER's region (BEG . END) corresponding to LINE and COL.
If COL is nil, return a region just for LINE. Return nil if the
region is invalid."
(condition-case-unless-debug _err
(with-current-buffer buffer
(let ((line (min (max line 1)
(line-number-at-pos (point-max) 'absolute))))
(save-excursion
(goto-char (point-min))
(forward-line (1- line))
(cl-flet ((fallback-bol
() (progn (back-to-indentation) (point)))
(fallback-eol
(beg)
(progn
(end-of-line)
(skip-chars-backward " \t\f\t\n" beg)
(if (eq (point) beg)
(line-beginning-position 2)
(point)))))
(if (and col (cl-plusp col))
(let* ((beg (progn (forward-char (1- col))
(point)))
(sexp-end (ignore-errors (end-of-thing 'sexp)))
(end (or (and sexp-end
(not (= sexp-end beg))
sexp-end)
(ignore-errors (goto-char (1+ beg)))))
(safe-end (or end
(fallback-eol beg))))
(cons (if end beg (fallback-bol))
safe-end))
(let* ((beg (fallback-bol))
(end (fallback-eol beg)))
(cons beg end)))))))
(error (flymake-error "Invalid region line=%s col=%s" line col))))
(defvar flymake-diagnostic-functions nil
"Special hook of Flymake backends that check a buffer.
The functions in this hook diagnose problems in a buffers
contents and provide information to the Flymake user interface
about where and how to annotate problems diagnosed in a buffer.
Whenever Flymake or the user decides to re-check the buffer, each
function is called with an arbitrary number of arguments:
* the first argument is always REPORT-FN, a callback function
detailed below;
* the remaining arguments are keyword-value pairs in the
form (:KEY VALUE :KEY2 VALUE2...). Currently, Flymake provides
no such arguments, but backend functions must be prepared to
accept and possibly ignore any number of them.
Backend functions are expected to initiate the buffer check, but
aren't required to complete it check before exiting: if the
computation involved is expensive, especially for large buffers,
that task can be scheduled for the future using asynchronous
processes or other asynchronous mechanisms.
In any case, backend functions are expected to return quickly or
signal an error, in which case the backend is disabled. Flymake
will not try disabled backends again for any future checks of
this buffer. Certain commands, like turning `flymake-mode' off
and on again, reset the list of disabled backends.
If the function returns, Flymake considers the backend to be
\"running\". If it has not done so already, the backend is
expected to call the function REPORT-FN with a single argument
REPORT-ACTION also followed by an optional list of keyword-value
pairs in the form (:REPORT-KEY VALUE :REPORT-KEY2 VALUE2...).
Currently accepted values for REPORT-ACTION are:
* A (possibly empty) list of diagnostic objects created with
`flymake-make-diagnostic', causing Flymake to annotate the
buffer with this information.
A backend may call REPORT-FN repeatedly in this manner, but
only until Flymake considers that the most recently requested
buffer check is now obsolete because, say, buffer contents have
changed in the meantime. The backend is only given notice of
this via a renewed call to the backend function. Thus, to
prevent making obsolete reports and wasting resources, backend
functions should first cancel any ongoing processing from
previous calls.
* The symbol `:panic', signaling that the backend has encountered
an exceptional situation and should be disabled.
Currently accepted REPORT-KEY arguments are:
* :explanation: value should give user-readable details of
the situation encountered, if any.
* :force: value should be a boolean suggesting that Flymake
consider the report even if it was somehow unexpected.")
(defvar flymake-diagnostic-types-alist
`((:error
. ((flymake-category . flymake-error)))
(:warning
. ((flymake-category . flymake-warning)))
(:note
. ((flymake-category . flymake-note))))
"Alist ((KEY . PROPS)*) of properties of Flymake diagnostic types.
KEY designates a kind of diagnostic can be anything passed as
`:type' to `flymake-make-diagnostic'.
PROPS is an alist of properties that are applied, in order, to
the diagnostics of the type designated by KEY. The recognized
properties are:
* Every property pertaining to overlays, except `category' and
`evaporate' (see Info Node `(elisp)Overlay Properties'), used
to affect the appearance of Flymake annotations.
* `bitmap', an image displayed in the fringe according to
`flymake-fringe-indicator-position'. The value actually
follows the syntax of `flymake-error-bitmap' (which see). It
is overridden by any `before-string' overlay property.
* `severity', a non-negative integer specifying the diagnostic's
severity. The higher, the more serious. If the overlay
priority `priority' is not specified, `severity' is used to set
it and help sort overlapping overlays.
* `flymake-category', a symbol whose property list is considered
as a default for missing values of any other properties. This
is useful to backend authors when creating new diagnostic types
that differ from an existing type by only a few properties.")
(put 'flymake-error 'face 'flymake-error)
(put 'flymake-error 'bitmap 'flymake-error-bitmap)
(put 'flymake-error 'severity (warning-numeric-level :error))
(put 'flymake-error 'mode-line-face 'compilation-error)
(put 'flymake-warning 'face 'flymake-warning)
(put 'flymake-warning 'bitmap 'flymake-warning-bitmap)
(put 'flymake-warning 'severity (warning-numeric-level :warning))
(put 'flymake-warning 'mode-line-face 'compilation-warning)
(put 'flymake-note 'face 'flymake-note)
(put 'flymake-note 'bitmap 'flymake-note-bitmap)
(put 'flymake-note 'severity (warning-numeric-level :debug))
(put 'flymake-note 'mode-line-face 'compilation-info)
(defun flymake--lookup-type-property (type prop &optional default)
"Look up PROP for TYPE in `flymake-diagnostic-types-alist'.
If TYPE doesn't declare PROP in either
`flymake-diagnostic-types-alist' or in the symbol of its
associated `flymake-category' return DEFAULT."
(let ((alist-probe (assoc type flymake-diagnostic-types-alist)))
(cond (alist-probe
(let* ((alist (cdr alist-probe))
(prop-probe (assoc prop alist)))
(if prop-probe
(cdr prop-probe)
(if-let* ((cat (assoc-default 'flymake-category alist))
(plist (and (symbolp cat)
(symbol-plist cat)))
(cat-probe (plist-member plist prop)))
(cadr cat-probe)
default))))
(t
default))))
(defun flymake--fringe-overlay-spec (bitmap &optional recursed)
(if (and (symbolp bitmap)
(boundp bitmap)
(not recursed))
(flymake--fringe-overlay-spec
(symbol-value bitmap) t)
(and flymake-fringe-indicator-position
bitmap
(propertize "!" 'display
(cons flymake-fringe-indicator-position
(if (listp bitmap)
bitmap
(list bitmap)))))))
(defun flymake--highlight-line (diagnostic)
"Highlight buffer with info in DIAGNOSTIC."
(when-let* ((ov (make-overlay
(flymake--diag-beg diagnostic)
(flymake--diag-end diagnostic))))
;; First set `category' in the overlay, then copy over every other
;; property.
;;
(let ((alist (assoc-default (flymake--diag-type diagnostic)
flymake-diagnostic-types-alist)))
(overlay-put ov 'category (assoc-default 'flymake-category alist))
(cl-loop for (k . v) in alist
unless (eq k 'category)
do (overlay-put ov k v)))
;; Now ensure some essential defaults are set
;;
(cl-flet ((default-maybe
(prop value)
(unless (or (plist-member (overlay-properties ov) prop)
(let ((cat (overlay-get ov
'flymake-category)))
(and cat
(plist-member (symbol-plist cat) prop))))
(overlay-put ov prop value))))
(default-maybe 'bitmap 'flymake-error-bitmap)
(default-maybe 'face 'flymake-error)
(default-maybe 'before-string
(flymake--fringe-overlay-spec
(overlay-get ov 'bitmap)))
(default-maybe 'help-echo
(lambda (_window _ov pos)
(mapconcat
(lambda (ov)
(let ((diag (overlay-get ov 'flymake--diagnostic)))
(flymake--diag-text diag)))
(flymake--overlays :beg pos)
"\n")))
(default-maybe 'severity (warning-numeric-level :error))
(default-maybe 'priority (+ 100 (overlay-get ov 'severity))))
;; Some properties can't be overridden.
;;
(overlay-put ov 'evaporate t)
(overlay-put ov 'flymake t)
(overlay-put ov 'flymake--diagnostic diagnostic)))
;; Nothing in Flymake uses this at all any more, so this is just for
;; third-party compatibility.
(define-obsolete-function-alias 'flymake-display-warning 'message-box "26.1")
(defvar-local flymake--backend-state nil
"Buffer-local hash table of a Flymake backend's state.
The keys to this hash table are functions as found in
`flymake-diagnostic-functions'. The values are structures
of the type `flymake--backend-state', with these slots:
`running', a symbol to keep track of a backend's replies via its
REPORT-FN argument. A backend is running if this key is
present. If nil, Flymake isn't expecting any replies from the
backend.
`diags', a (possibly empty) list of recent diagnostic objects
created by the backend with `flymake-make-diagnostic'.
`reported-p', a boolean indicating if the backend has replied
since it last was contacted.
`disabled', a string with the explanation for a previous
exceptional situation reported by the backend, nil if the
backend is operating normally.")
(cl-defstruct (flymake--backend-state
(:constructor flymake--make-backend-state))
running reported-p disabled diags)
(defmacro flymake--with-backend-state (backend state-var &rest body)
"Bind BACKEND's STATE-VAR to its state, run BODY."
(declare (indent 2) (debug (sexp sexp &rest form)))
(let ((b (make-symbol "b")))
`(let* ((,b ,backend)
(,state-var
(or (gethash ,b flymake--backend-state)
(puthash ,b (flymake--make-backend-state)
flymake--backend-state))))
,@body)))
(defun flymake-is-running ()
"Tell if Flymake has running backends in this buffer"
(flymake-running-backends))
(cl-defun flymake--handle-report (backend token report-action
&key explanation force
&allow-other-keys)
"Handle reports from BACKEND identified by TOKEN.
BACKEND, REPORT-ACTION and EXPLANATION, and FORCE conform to the calling
convention described in `flymake-diagnostic-functions' (which
see). Optional FORCE says to handle a report even if TOKEN was
not expected."
(let* ((state (gethash backend flymake--backend-state))
(first-report (not (flymake--backend-state-reported-p state))))
(setf (flymake--backend-state-reported-p state) t)
(let (expected-token
new-diags)
(cond
((null state)
(flymake-error
"Unexpected report from unknown backend %s" backend))
((flymake--backend-state-disabled state)
(flymake-error
"Unexpected report from disabled backend %s" backend))
((progn
(setq expected-token (flymake--backend-state-running state))
(null expected-token))
;; should never happen
(flymake-error "Unexpected report from stopped backend %s" backend))
((and (not (eq expected-token token))
(not force))
(flymake-error "Obsolete report from backend %s with explanation %s"
backend explanation))
((eq :panic report-action)
(flymake--disable-backend backend explanation))
((not (listp report-action))
(flymake--disable-backend backend
(format "Unknown action %S" report-action))
(flymake-error "Expected report, but got unknown key %s" report-action))
(t
(setq new-diags report-action)
(save-restriction
(widen)
;; only delete overlays if this is the first report
(when first-report
(flymake-delete-own-overlays
(lambda (ov)
(eq backend
(flymake--diag-backend
(overlay-get ov 'flymake--diagnostic))))))
(mapc (lambda (diag)
(flymake--highlight-line diag)
(setf (flymake--diag-backend diag) backend))
new-diags)
(setf (flymake--backend-state-diags state)
(append new-diags (flymake--backend-state-diags state)))
(when flymake-check-start-time
(flymake-log :debug "backend %s reported %d diagnostics in %.2f second(s)"
backend
(length new-diags)
(- (float-time) flymake-check-start-time)))))))))
(defun flymake-make-report-fn (backend &optional token)
"Make a suitable anonymous report function for BACKEND.
BACKEND is used to help Flymake distinguish different diagnostic
sources. If provided, TOKEN helps Flymake distinguish between
different runs of the same backend."
(let ((buffer (current-buffer)))
(lambda (&rest args)
(when (buffer-live-p buffer)
(with-current-buffer buffer
(apply #'flymake--handle-report backend token args))))))
(defun flymake--collect (fn)
(let (retval)
(maphash (lambda (backend state)
(when (funcall fn state) (push backend retval)))
flymake--backend-state)
retval))
(defun flymake-running-backends ()
"Compute running Flymake backends in current buffer."
(flymake--collect #'flymake--backend-state-running))
(defun flymake-disabled-backends ()
"Compute disabled Flymake backends in current buffer."
(flymake--collect #'flymake--backend-state-disabled))
(defun flymake-reporting-backends ()
"Compute reporting Flymake backends in current buffer."
(flymake--collect #'flymake--backend-state-reported-p))
(defun flymake--disable-backend (backend &optional explanation)
"Disable BACKEND because EXPLANATION.
If it is running also stop it."
(flymake-log :warning "Disabling backend %s because %s" backend explanation)
(flymake--with-backend-state backend state
(setf (flymake--backend-state-running state) nil
(flymake--backend-state-disabled state) explanation
(flymake--backend-state-reported-p state) t)))
(defun flymake--run-backend (backend)
"Run the backend BACKEND, reenabling if necessary."
(flymake-log :debug "Running backend %s" backend)
(let ((run-token (cl-gensym "backend-token")))
(flymake--with-backend-state backend state
(setf (flymake--backend-state-running state) run-token
(flymake--backend-state-disabled state) nil
(flymake--backend-state-diags state) nil
(flymake--backend-state-reported-p state) nil))
;; FIXME: Should use `condition-case-unless-debug' here, but don't
;; for two reasons: (1) that won't let me catch errors from inside
;; `ert-deftest' where `debug-on-error' appears to be always
;; t. (2) In cases where the user is debugging elisp somewhere
;; else, and using flymake, the presence of a frequently
;; misbehaving backend in the global hook (most likely the legacy
;; backend) will trigger an annoying backtrace.
;;
(condition-case err
(funcall backend
(flymake-make-report-fn backend run-token))
(error
(flymake--disable-backend backend err)))))
(defun flymake-start (&optional deferred force)
"Start a syntax check.
Start it immediately, or after current command if DEFERRED is
non-nil. With optional FORCE run even disabled backends.
Interactively, with a prefix arg, FORCE is t."
(interactive (list nil current-prefix-arg))
(cl-labels
((start
()
(remove-hook 'post-command-hook #'start 'local)
(setq flymake-check-start-time (float-time))
(run-hook-wrapped
'flymake-diagnostic-functions
(lambda (backend)
(cond
((and (not force)
(flymake--with-backend-state backend state
(flymake--backend-state-disabled state)))
(flymake-log :debug "Backend %s is disabled, not starting"
backend))
(t
(flymake--run-backend backend)))
nil))))
(if (and deferred
this-command)
(add-hook 'post-command-hook #'start 'append 'local)
(start))))
(defvar flymake-mode-map
(let ((map (make-sparse-keymap))) map)
"Keymap for `flymake-mode'")
;;;###autoload
(define-minor-mode flymake-mode nil
:group 'flymake :lighter flymake--mode-line-format :keymap flymake-mode-map
(cond
;; Turning the mode ON.
(flymake-mode
(add-hook 'after-change-functions 'flymake-after-change-function nil t)
(add-hook 'after-save-hook 'flymake-after-save-hook nil t)
(add-hook 'kill-buffer-hook 'flymake-kill-buffer-hook nil t)
(setq flymake--backend-state (make-hash-table))
(when flymake-start-syntax-check-on-find-file
(flymake-start)))
;; Turning the mode OFF.
(t
(remove-hook 'after-change-functions 'flymake-after-change-function t)
(remove-hook 'after-save-hook 'flymake-after-save-hook t)
(remove-hook 'kill-buffer-hook 'flymake-kill-buffer-hook t)
;;+(remove-hook 'find-file-hook (function flymake-find-file-hook) t)
(flymake-delete-own-overlays)
(when flymake-timer
(cancel-timer flymake-timer)
(setq flymake-timer nil)))))
(defun flymake--schedule-timer-maybe ()
"(Re)schedule an idle timer for checking the buffer.
Do it only if `flymake-no-changes-timeout' is non-nil."
(when flymake-timer (cancel-timer flymake-timer))
(when flymake-no-changes-timeout
(setq
flymake-timer
(run-with-idle-timer
(seconds-to-time flymake-no-changes-timeout)
nil
(lambda (buffer)
(when (buffer-live-p buffer)
(with-current-buffer buffer
(when (and flymake-mode
flymake-no-changes-timeout)
(flymake-log
:debug "starting syntax check after idle for %s seconds"
flymake-no-changes-timeout)
(flymake-start))
(setq flymake-timer nil))))
(current-buffer)))))
;;;###autoload
(defun flymake-mode-on ()
"Turn Flymake mode on."
(flymake-mode 1))
;;;###autoload
(defun flymake-mode-off ()
"Turn Flymake mode off."
(flymake-mode 0))
(make-obsolete 'flymake-mode-on 'flymake-mode "26.1")
(make-obsolete 'flymake-mode-off 'flymake-mode "26.1")
(defun flymake-after-change-function (start stop _len)
"Start syntax check for current buffer if it isn't already running."
(let((new-text (buffer-substring start stop)))
(when (and flymake-start-syntax-check-on-newline (equal new-text "\n"))
(flymake-log :debug "starting syntax check as new-line has been seen")
(flymake-start 'deferred))
(flymake--schedule-timer-maybe)))
(defun flymake-after-save-hook ()
(when flymake-mode
(flymake-log :debug "starting syntax check as buffer was saved")
(flymake-start)))
(defun flymake-kill-buffer-hook ()
(when flymake-timer
(cancel-timer flymake-timer)
(setq flymake-timer nil)))
(defun flymake-find-file-hook ()
(unless (or flymake-mode
(null flymake-diagnostic-functions))
(flymake-mode)
(flymake-log :warning "Turned on in `flymake-find-file-hook'")))
(defun flymake-goto-next-error (&optional n filter interactive)
"Go to Nth next Flymake error in buffer matching FILTER.
Interactively, always move to the next error. With a prefix arg,
skip any diagnostics with a severity less than :warning.
If flymake-wrap-around is non-nil and no more next errors,
resumes search from top
FILTER is a list of diagnostic types found in
`flymake-diagnostic-types-alist', or nil, if no filter is to be
applied."
;; TODO: let filter be a number, a severity below which diags are
;; skipped.
(interactive (list 1
(if current-prefix-arg
'(:error :warning))
t))
(let* ((n (or n 1))
(ovs (flymake--overlays :filter
(lambda (ov)
(let ((diag (overlay-get
ov
'flymake--diagnostic)))
(and diag
(or (not filter)
(memq (flymake--diag-type diag)
filter)))))
:compare (if (cl-plusp n) #'< #'>)
:key #'overlay-start))
(tail (cl-member-if (lambda (ov)
(if (cl-plusp n)
(> (overlay-start ov)
(point))
(< (overlay-start ov)
(point))))
ovs))
(chain (if flymake-wrap-around
(if tail
(progn (setcdr (last tail) ovs) tail)
(and ovs (setcdr (last ovs) ovs)))
tail))
(target (nth (1- n) chain)))
(cond (target
(goto-char (overlay-start target))
(when interactive
(message
(funcall (overlay-get target 'help-echo)
nil nil (point)))))
(interactive
(user-error "No more Flymake errors%s"
(if filter
(format " of types %s" filter)
""))))))
(defun flymake-goto-prev-error (&optional n filter interactive)
"Go to Nth previous Flymake error in buffer matching FILTER.
Interactively, always move to the previous error. With a prefix
arg, skip any diagnostics with a severity less than :warning.
If flymake-wrap-around is non-nil and no more previous errors,
resumes search from bottom.
FILTER is a list of diagnostic types found in
`flymake-diagnostic-types-alist', or nil, if no filter is to be
applied."
(interactive (list 1 (if current-prefix-arg
'(:error :warning))
t))
(flymake-goto-next-error (- (or n 1)) filter interactive))
;;; Mode-line and menu
;;;
(easy-menu-define flymake-menu flymake-mode-map "Flymake"
`("Flymake"
[ "Go to next error" flymake-goto-next-error t ]
[ "Go to previous error" flymake-goto-prev-error t ]
[ "Check now" flymake-start t ]
[ "Go to log buffer" flymake-switch-to-log-buffer t ]
"--"
[ "Turn off Flymake" flymake-mode t ]))
(defvar flymake--mode-line-format `(:eval (flymake--mode-line-format)))
(put 'flymake--mode-line-format 'risky-local-variable t)
(defun flymake--mode-line-format ()
"Produce a pretty minor mode indicator."
(let* ((known (hash-table-keys flymake--backend-state))
(running (flymake-running-backends))
(disabled (flymake-disabled-backends))
(reported (flymake-reporting-backends))
(diags-by-type (make-hash-table))
(all-disabled (and disabled (null running)))
(some-waiting (cl-set-difference running reported)))
(maphash (lambda (_b state)
(mapc (lambda (diag)
(push diag
(gethash (flymake--diag-type diag)
diags-by-type)))
(flymake--backend-state-diags state)))
flymake--backend-state)
`((:propertize " Flymake"
mouse-face mode-line-highlight
help-echo
,(concat (format "%s known backends\n" (length known))
(format "%s running\n" (length running))
(format "%s disabled\n" (length disabled))
"mouse-1: go to log buffer ")
keymap
,(let ((map (make-sparse-keymap)))
(define-key map [mode-line down-mouse-1]
flymake-menu)
map))
,@(pcase-let ((`(,ind ,face ,explain)
(cond ((null known)
`("?" mode-line "No known backends"))
(some-waiting
`("Wait" compilation-mode-line-run
,(format "Waiting for %s running backend(s)"
(length some-waiting))))
(all-disabled
`("!" compilation-mode-line-run
"All backends disabled"))
(t
`(nil nil nil)))))
(when ind
`((":"
(:propertize ,ind
face ,face
help-echo ,explain
keymap
,(let ((map (make-sparse-keymap)))
(define-key map [mode-line mouse-1]
'flymake-switch-to-log-buffer)
map))))))
,@(unless (or all-disabled
(null known))
(cl-loop
for (type . severity)
in (cl-sort (mapcar (lambda (type)
(cons type (flymake--lookup-type-property
type
'severity
(warning-numeric-level :error))))
(cl-union (hash-table-keys diags-by-type)
'(:error :warning)))
#'>
:key #'cdr)
for diags = (gethash type diags-by-type)
for face = (flymake--lookup-type-property type
'mode-line-face
'compilation-error)
when (or diags
(>= severity (warning-numeric-level :warning)))
collect `(:propertize
,(format "%d" (length diags))
face ,face
mouse-face mode-line-highlight
keymap
,(let ((map (make-sparse-keymap))
(type type))
(define-key map [mode-line mouse-4]
(lambda (_event)
(interactive "e")
(flymake-goto-prev-error 1 (list type) t)))
(define-key map [mode-line mouse-5]
(lambda (_event)
(interactive "e")
(flymake-goto-next-error 1 (list type) t)))
map)
help-echo
,(concat (format "%s diagnostics of type %s\n"
(propertize (format "%d"
(length diags))
'face face)
(propertize (format "%s" type)
'face face))
"mouse-4/mouse-5: previous/next of this type\n"))
into forms
finally return
`((:propertize "[")
,@(cl-loop for (a . rest) on forms by #'cdr
collect a when rest collect
'(:propertize " "))
(:propertize "]")))))))
(provide 'flymake) (provide 'flymake)
(require 'flymake-proc)
;;; flymake.el ends here ;;; flymake.el ends here

View file

@ -3442,6 +3442,8 @@ def __PYTHON_EL_native_completion_setup():
instance.rlcomplete = new_completer instance.rlcomplete = new_completer
if readline.__doc__ and 'libedit' in readline.__doc__: if readline.__doc__ and 'libedit' in readline.__doc__:
raise Exception('''libedit based readline is known not to work,
see etc/PROBLEMS under \"In Inferior Python mode, input is echoed\".''')
readline.parse_and_bind('bind ^I rl_complete') readline.parse_and_bind('bind ^I rl_complete')
else: else:
readline.parse_and_bind('tab: complete') readline.parse_and_bind('tab: complete')
@ -3450,7 +3452,9 @@ def __PYTHON_EL_native_completion_setup():
print ('python.el: native completion setup loaded') print ('python.el: native completion setup loaded')
except: except:
print ('python.el: native completion setup failed') import sys
print ('python.el: native completion setup failed, %s: %s'
% sys.exc_info()[:2])
__PYTHON_EL_native_completion_setup()" process) __PYTHON_EL_native_completion_setup()" process)
(when (and (when (and

View file

@ -1254,8 +1254,7 @@ preceding cell has spilled over."
((< len width) ((< len width)
;; Fill field to length with spaces. ;; Fill field to length with spaces.
(setq len (make-string (- width len) ?\s) (setq len (make-string (- width len) ?\s)
text (if (or (stringp value) text (if (eq ses-call-printer-return t)
(eq ses-call-printer-return t))
(concat text len) (concat text len)
(concat len text)))) (concat len text))))
((> len width) ((> len width)

View file

@ -160,24 +160,33 @@ LABEL is a string to display as the label of that TIMEZONE's time."
:type '(repeat (list string string)) :type '(repeat (list string string))
:version "23.1") :version "23.1")
(defcustom display-time-world-list (defcustom display-time-world-list t
;; Determine if zoneinfo style timezones are supported by testing that
;; America/New York and Europe/London return different timezones.
(let ((nyt (format-time-string "%z" nil "America/New_York"))
(gmt (format-time-string "%z" nil "Europe/London")))
(if (string-equal nyt gmt)
legacy-style-world-list
zoneinfo-style-world-list))
"Alist of time zones and places for `display-time-world' to display. "Alist of time zones and places for `display-time-world' to display.
Each element has the form (TIMEZONE LABEL). Each element has the form (TIMEZONE LABEL).
TIMEZONE should be in a format supported by your system. See the TIMEZONE should be in a format supported by your system. See the
documentation of `zoneinfo-style-world-list' and documentation of `zoneinfo-style-world-list' and
`legacy-style-world-list' for two widely used formats. LABEL is `legacy-style-world-list' for two widely used formats. LABEL is
a string to display as the label of that TIMEZONE's time." a string to display as the label of that TIMEZONE's time.
If the value is t instead of an alist, use the value of
`zoneinfo-style-world-list' if it works on this platform, and of
`legacy-style-world-list' otherwise."
:group 'display-time :group 'display-time
:type '(repeat (list string string)) :type '(repeat (list string string))
:version "23.1") :version "23.1")
(defun time--display-world-list ()
(if (listp display-time-world-list)
display-time-world-list
;; Determine if zoneinfo style timezones are supported by testing that
;; America/New York and Europe/London return different timezones.
(let ((nyt (format-time-string "%z" nil "America/New_York"))
(gmt (format-time-string "%z" nil "Europe/London")))
(if (string-equal nyt gmt)
legacy-style-world-list
zoneinfo-style-world-list))))
(defcustom display-time-world-time-format "%A %d %B %R %Z" (defcustom display-time-world-time-format "%A %d %B %R %Z"
"Format of the time displayed, see `format-time-string'." "Format of the time displayed, see `format-time-string'."
:group 'display-time :group 'display-time
@ -548,7 +557,7 @@ To turn off the world time display, go to that window and type `q'."
(not (get-buffer display-time-world-buffer-name))) (not (get-buffer display-time-world-buffer-name)))
(run-at-time t display-time-world-timer-second 'display-time-world-timer)) (run-at-time t display-time-world-timer-second 'display-time-world-timer))
(with-current-buffer (get-buffer-create display-time-world-buffer-name) (with-current-buffer (get-buffer-create display-time-world-buffer-name)
(display-time-world-display display-time-world-list) (display-time-world-display (time--display-world-list))
(display-buffer display-time-world-buffer-name (display-buffer display-time-world-buffer-name
(cons nil '((window-height . fit-window-to-buffer)))) (cons nil '((window-height . fit-window-to-buffer))))
(display-time-world-mode))) (display-time-world-mode)))
@ -556,7 +565,7 @@ To turn off the world time display, go to that window and type `q'."
(defun display-time-world-timer () (defun display-time-world-timer ()
(if (get-buffer display-time-world-buffer-name) (if (get-buffer display-time-world-buffer-name)
(with-current-buffer (get-buffer display-time-world-buffer-name) (with-current-buffer (get-buffer display-time-world-buffer-name)
(display-time-world-display display-time-world-list)) (display-time-world-display (time--display-world-list)))
;; cancel timer ;; cancel timer
(let ((list timer-list)) (let ((list timer-list))
(while list (while list

View file

@ -288,8 +288,10 @@ which is the \"1006\" extension implemented in Xterm >= 277."
(string-match "down-" last-name) (string-match "down-" last-name)
(equal name (replace-match "" t t last-name))) (equal name (replace-match "" t t last-name)))
(xterm-mouse--set-click-count event click-count))) (xterm-mouse--set-click-count event click-count)))
((not last-time) nil) ((and last-time
((and (> double-click-time (* 1000 (- this-time last-time))) double-click-time
(or (eq double-click-time t)
(> double-click-time (* 1000 (- this-time last-time))))
(equal last-name (replace-match "" t t name))) (equal last-name (replace-match "" t t name)))
(setq click-count (1+ click-count)) (setq click-count (1+ click-count))
(xterm-mouse--set-click-count event click-count)) (xterm-mouse--set-click-count event click-count))

View file

@ -272,7 +272,7 @@ invoke it. If KEYS is omitted or nil, the return value of
{ {
/* `args' will contain the array of arguments to pass to the function. /* `args' will contain the array of arguments to pass to the function.
`visargs' will contain the same list but in a nicer form, so that if we `visargs' will contain the same list but in a nicer form, so that if we
pass it to styled_format it will be understandable to a human. */ pass it to Fformat_message it will be understandable to a human. */
Lisp_Object *args, *visargs; Lisp_Object *args, *visargs;
Lisp_Object specs; Lisp_Object specs;
Lisp_Object filter_specs; Lisp_Object filter_specs;
@ -502,7 +502,7 @@ invoke it. If KEYS is omitted or nil, the return value of
for (i = 2; *tem; i++) for (i = 2; *tem; i++)
{ {
visargs[1] = make_string (tem + 1, strcspn (tem + 1, "\n")); visargs[1] = make_string (tem + 1, strcspn (tem + 1, "\n"));
callint_message = styled_format (i - 1, visargs + 1, true, false); callint_message = Fformat_message (i - 1, visargs + 1);
switch (*tem) switch (*tem)
{ {

View file

@ -237,8 +237,7 @@ static char *
XD_OBJECT_TO_STRING (Lisp_Object object) XD_OBJECT_TO_STRING (Lisp_Object object)
{ {
AUTO_STRING (format, "%s"); AUTO_STRING (format, "%s");
Lisp_Object args[] = { format, object }; return SSDATA (CALLN (Fformat, format, object));
return SSDATA (styled_format (ARRAYELTS (args), args, false, false));
} }
#define XD_DBUS_VALIDATE_BUS_ADDRESS(bus) \ #define XD_DBUS_VALIDATE_BUS_ADDRESS(bus) \

View file

@ -74,6 +74,7 @@ static Lisp_Object format_time_string (char const *, ptrdiff_t, struct timespec,
static long int tm_gmtoff (struct tm *); static long int tm_gmtoff (struct tm *);
static int tm_diff (struct tm *, struct tm *); static int tm_diff (struct tm *, struct tm *);
static void update_buffer_properties (ptrdiff_t, ptrdiff_t); static void update_buffer_properties (ptrdiff_t, ptrdiff_t);
static Lisp_Object styled_format (ptrdiff_t, Lisp_Object *, bool);
#ifndef HAVE_TM_GMTOFF #ifndef HAVE_TM_GMTOFF
# define HAVE_TM_GMTOFF false # define HAVE_TM_GMTOFF false
@ -3958,7 +3959,7 @@ usage: (message FORMAT-STRING &rest ARGS) */)
} }
else else
{ {
Lisp_Object val = styled_format (nargs, args, true, false); Lisp_Object val = Fformat_message (nargs, args);
message3 (val); message3 (val);
return val; return val;
} }
@ -3984,7 +3985,7 @@ usage: (message-box FORMAT-STRING &rest ARGS) */)
} }
else else
{ {
Lisp_Object val = styled_format (nargs, args, true, false); Lisp_Object val = Fformat_message (nargs, args);
Lisp_Object pane, menu; Lisp_Object pane, menu;
pane = list1 (Fcons (build_string ("OK"), Qt)); pane = list1 (Fcons (build_string ("OK"), Qt));
@ -4140,7 +4141,7 @@ produced text.
usage: (format STRING &rest OBJECTS) */) usage: (format STRING &rest OBJECTS) */)
(ptrdiff_t nargs, Lisp_Object *args) (ptrdiff_t nargs, Lisp_Object *args)
{ {
return styled_format (nargs, args, false, true); return styled_format (nargs, args, false);
} }
DEFUN ("format-message", Fformat_message, Sformat_message, 1, MANY, 0, DEFUN ("format-message", Fformat_message, Sformat_message, 1, MANY, 0,
@ -4156,16 +4157,13 @@ and right quote replacement characters are specified by
usage: (format-message STRING &rest OBJECTS) */) usage: (format-message STRING &rest OBJECTS) */)
(ptrdiff_t nargs, Lisp_Object *args) (ptrdiff_t nargs, Lisp_Object *args)
{ {
return styled_format (nargs, args, true, true); return styled_format (nargs, args, true);
} }
/* Implement format-message if MESSAGE is true, format otherwise. /* Implement format-message if MESSAGE is true, format otherwise. */
If NEW_RESULT, the result is a new string; otherwise, the result
may be one of the arguments. */
Lisp_Object static Lisp_Object
styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message, styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
bool new_result)
{ {
ptrdiff_t n; /* The number of the next arg to substitute. */ ptrdiff_t n; /* The number of the next arg to substitute. */
char initial_buffer[4000]; char initial_buffer[4000];
@ -4195,9 +4193,6 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message,
/* The start and end bytepos in the output string. */ /* The start and end bytepos in the output string. */
ptrdiff_t start, end; ptrdiff_t start, end;
/* Whether the argument is a newly created string. */
bool_bf new_string : 1;
/* Whether the argument is a string with intervals. */ /* Whether the argument is a string with intervals. */
bool_bf intervals : 1; bool_bf intervals : 1;
} *info; } *info;
@ -4241,6 +4236,9 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message,
ptrdiff_t ispec; ptrdiff_t ispec;
ptrdiff_t nspec = 0; ptrdiff_t nspec = 0;
/* True if a string needs to be allocated to hold the result. */
bool new_result = false;
/* If we start out planning a unibyte result, /* If we start out planning a unibyte result,
then discover it has to be multibyte, we jump back to retry. */ then discover it has to be multibyte, we jump back to retry. */
retry: retry:
@ -4360,7 +4358,6 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message,
if (nspec < ispec) if (nspec < ispec)
{ {
spec->argument = args[n]; spec->argument = args[n];
spec->new_string = false;
spec->intervals = false; spec->intervals = false;
nspec = ispec; nspec = ispec;
} }
@ -4378,7 +4375,6 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message,
{ {
Lisp_Object noescape = conversion == 'S' ? Qnil : Qt; Lisp_Object noescape = conversion == 'S' ? Qnil : Qt;
spec->argument = arg = Fprin1_to_string (arg, noescape); spec->argument = arg = Fprin1_to_string (arg, noescape);
spec->new_string = true;
if (STRING_MULTIBYTE (arg) && ! multibyte) if (STRING_MULTIBYTE (arg) && ! multibyte)
{ {
multibyte = true; multibyte = true;
@ -4397,7 +4393,6 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message,
goto retry; goto retry;
} }
spec->argument = arg = Fchar_to_string (arg); spec->argument = arg = Fchar_to_string (arg);
spec->new_string = true;
} }
if (!EQ (arg, args[n])) if (!EQ (arg, args[n]))
@ -4421,7 +4416,6 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message,
if (conversion == 's') if (conversion == 's')
{ {
if (format == end && format - format_start == 2 if (format == end && format - format_start == 2
&& (!new_result || spec->new_string)
&& ! string_intervals (args[0])) && ! string_intervals (args[0]))
return arg; return arg;

View file

@ -2542,6 +2542,7 @@ for how to proceed. */)
(Lisp_Object frame) (Lisp_Object frame)
{ {
struct frame *f = decode_live_frame (frame); struct frame *f = decode_live_frame (frame);
#ifdef HAVE_WINDOW_SYSTEM
Lisp_Object parent = f->parent_frame; Lisp_Object parent = f->parent_frame;
if (!NILP (parent)) if (!NILP (parent))
@ -2562,6 +2563,7 @@ for how to proceed. */)
return Qnil; return Qnil;
} }
} }
#endif /* HAVE_WINDOW_SYSTEM */
/* Don't allow minibuf_window to remain on an iconified frame. */ /* Don't allow minibuf_window to remain on an iconified frame. */
check_minibuf_window (frame, EQ (minibuf_window, selected_window)); check_minibuf_window (frame, EQ (minibuf_window, selected_window));

View file

@ -577,11 +577,18 @@ xg_check_special_colors (struct frame *f,
if (get_fg) if (get_fg)
gtk_style_context_get_color (gsty, state, &col); gtk_style_context_get_color (gsty, state, &col);
else else
/* FIXME: gtk_style_context_get_background_color is deprecated {
in GTK+ 3.16. New versions of GTK+ dont use the concept of GdkRGBA *c;
a single background color any more, so we shouldnt query for /* FIXME: Retrieving the background color is deprecated in
it. */ GTK+ 3.16. New versions of GTK+ dont use the concept of a
gtk_style_context_get_background_color (gsty, state, &col); single background color any more, so we shouldnt query for
it. */
gtk_style_context_get (gsty, state,
GTK_STYLE_PROPERTY_BACKGROUND_COLOR, &c,
NULL);
col = *c;
gdk_rgba_free (c);
}
unsigned short unsigned short
r = col.red * 65535, r = col.red * 65535,

View file

@ -145,10 +145,6 @@ static Lisp_Object recover_top_level_message;
/* Message normally displayed by Vtop_level. */ /* Message normally displayed by Vtop_level. */
static Lisp_Object regular_top_level_message; static Lisp_Object regular_top_level_message;
/* For longjmp to where kbd input is being done. */
static sys_jmp_buf getcjmp;
/* True while displaying for echoing. Delays C-g throwing. */ /* True while displaying for echoing. Delays C-g throwing. */
static bool echoing; static bool echoing;
@ -2570,9 +2566,6 @@ read_char (int commandflag, Lisp_Object map,
so restore it now. */ so restore it now. */
restore_getcjmp (save_jump); restore_getcjmp (save_jump);
pthread_sigmask (SIG_SETMASK, &empty_mask, 0); pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
#if THREADS_ENABLED
maybe_reacquire_global_lock ();
#endif
unbind_to (jmpcount, Qnil); unbind_to (jmpcount, Qnil);
XSETINT (c, quit_char); XSETINT (c, quit_char);
internal_last_event_frame = selected_frame; internal_last_event_frame = selected_frame;
@ -10508,6 +10501,13 @@ handle_interrupt (bool in_signal_handler)
outside of polling since we don't get SIGIO like X and we don't have a outside of polling since we don't get SIGIO like X and we don't have a
separate event loop thread like W32. */ separate event loop thread like W32. */
#ifndef HAVE_NS #ifndef HAVE_NS
#ifdef THREADS_ENABLED
/* If we were called from a signal handler, we must be in the main
thread, see deliver_process_signal. So we must make sure the
main thread holds the global lock. */
if (in_signal_handler)
maybe_reacquire_global_lock ();
#endif
if (waiting_for_input && !echoing) if (waiting_for_input && !echoing)
quit_throw_to_read_char (in_signal_handler); quit_throw_to_read_char (in_signal_handler);
#endif #endif

View file

@ -1865,6 +1865,26 @@ verify (offsetof (struct Lisp_Sub_Char_Table, contents)
== (offsetof (struct Lisp_Vector, contents) == (offsetof (struct Lisp_Vector, contents)
+ SUB_CHAR_TABLE_OFFSET * sizeof (Lisp_Object))); + SUB_CHAR_TABLE_OFFSET * sizeof (Lisp_Object)));
/* Save and restore the instruction and environment pointers,
without affecting the signal mask. */
#ifdef HAVE__SETJMP
typedef jmp_buf sys_jmp_buf;
# define sys_setjmp(j) _setjmp (j)
# define sys_longjmp(j, v) _longjmp (j, v)
#elif defined HAVE_SIGSETJMP
typedef sigjmp_buf sys_jmp_buf;
# define sys_setjmp(j) sigsetjmp (j, 0)
# define sys_longjmp(j, v) siglongjmp (j, v)
#else
/* A platform that uses neither _longjmp nor siglongjmp; assume
longjmp does not affect the sigmask. */
typedef jmp_buf sys_jmp_buf;
# define sys_setjmp(j) setjmp (j)
# define sys_longjmp(j, v) longjmp (j, v)
#endif
#include "thread.h" #include "thread.h"
/*********************************************************************** /***********************************************************************
@ -3003,25 +3023,6 @@ extern void defvar_kboard (struct Lisp_Kboard_Objfwd *, const char *, int);
static struct Lisp_Kboard_Objfwd ko_fwd; \ static struct Lisp_Kboard_Objfwd ko_fwd; \
defvar_kboard (&ko_fwd, lname, offsetof (KBOARD, vname ## _)); \ defvar_kboard (&ko_fwd, lname, offsetof (KBOARD, vname ## _)); \
} while (false) } while (false)
/* Save and restore the instruction and environment pointers,
without affecting the signal mask. */
#ifdef HAVE__SETJMP
typedef jmp_buf sys_jmp_buf;
# define sys_setjmp(j) _setjmp (j)
# define sys_longjmp(j, v) _longjmp (j, v)
#elif defined HAVE_SIGSETJMP
typedef sigjmp_buf sys_jmp_buf;
# define sys_setjmp(j) sigsetjmp (j, 0)
# define sys_longjmp(j, v) siglongjmp (j, v)
#else
/* A platform that uses neither _longjmp nor siglongjmp; assume
longjmp does not affect the sigmask. */
typedef jmp_buf sys_jmp_buf;
# define sys_setjmp(j) setjmp (j)
# define sys_longjmp(j, v) longjmp (j, v)
#endif
/* Elisp uses several stacks: /* Elisp uses several stacks:
@ -3969,7 +3970,6 @@ extern _Noreturn void time_overflow (void);
extern Lisp_Object make_buffer_string (ptrdiff_t, ptrdiff_t, bool); extern Lisp_Object make_buffer_string (ptrdiff_t, ptrdiff_t, bool);
extern Lisp_Object make_buffer_string_both (ptrdiff_t, ptrdiff_t, ptrdiff_t, extern Lisp_Object make_buffer_string_both (ptrdiff_t, ptrdiff_t, ptrdiff_t,
ptrdiff_t, bool); ptrdiff_t, bool);
extern Lisp_Object styled_format (ptrdiff_t, Lisp_Object *, bool, bool);
extern void init_editfns (bool); extern void init_editfns (bool);
extern void syms_of_editfns (void); extern void syms_of_editfns (void);

View file

@ -232,7 +232,18 @@ emacs_get_current_dir_name (void)
bool use_libc = true; bool use_libc = true;
# endif # endif
if (use_libc) if (use_libc)
return get_current_dir_name (); {
/* GNU/Linux get_current_dir_name can return a string starting
with "(unreachable)" (Bug#27871). */
char *wd = get_current_dir_name ();
if (wd && ! (IS_DIRECTORY_SEP (*wd) || (*wd && IS_DEVICE_SEP (wd[1]))))
{
free (wd);
errno = ENOENT;
return NULL;
}
return wd;
}
# endif # endif
char *buf; char *buf;

View file

@ -101,14 +101,20 @@ acquire_global_lock (struct thread_state *self)
post_acquire_global_lock (self); post_acquire_global_lock (self);
} }
/* This is called from keyboard.c when it detects that SIGINT /* This is called from keyboard.c when it detects that SIGINT was
interrupted thread_select before the current thread could acquire delivered to the main thread and interrupted thread_select before
the lock. We must acquire the lock to prevent a thread from the main thread could acquire the lock. We must acquire the lock
running without holding the global lock, and to avoid repeated to prevent a thread from running without holding the global lock,
calls to sys_mutex_unlock, which invokes undefined behavior. */ and to avoid repeated calls to sys_mutex_unlock, which invokes
undefined behavior. */
void void
maybe_reacquire_global_lock (void) maybe_reacquire_global_lock (void)
{ {
/* SIGINT handler is always run on the main thread, see
deliver_process_signal, so reflect that in our thread-tracking
variables. */
current_thread = &main_thread;
if (current_thread->not_holding_lock) if (current_thread->not_holding_lock)
{ {
struct thread_state *self = current_thread; struct thread_state *self = current_thread;

View file

@ -158,6 +158,13 @@ struct thread_state
bool m_waiting_for_input; bool m_waiting_for_input;
#define waiting_for_input (current_thread->m_waiting_for_input) #define waiting_for_input (current_thread->m_waiting_for_input)
/* For longjmp to where kbd input is being done. This is per-thread
so that if more than one thread calls read_char, they don't
clobber each other's getcjmp, which will cause
quit_throw_to_read_char crash due to using a wrong stack. */
sys_jmp_buf m_getcjmp;
#define getcjmp (current_thread->m_getcjmp)
/* The OS identifier for this thread. */ /* The OS identifier for this thread. */
sys_thread_t thread_id; sys_thread_t thread_id;

View file

@ -10194,7 +10194,7 @@ vadd_to_log (char const *format, va_list ap)
for (ptrdiff_t i = 1; i <= nargs; i++) for (ptrdiff_t i = 1; i <= nargs; i++)
args[i] = va_arg (ap, Lisp_Object); args[i] = va_arg (ap, Lisp_Object);
Lisp_Object msg = Qnil; Lisp_Object msg = Qnil;
msg = styled_format (nargs, args, true, false); msg = Fformat_message (nargs, args);
ptrdiff_t len = SBYTES (msg) + 1; ptrdiff_t len = SBYTES (msg) + 1;
USE_SAFE_ALLOCA; USE_SAFE_ALLOCA;
@ -19525,7 +19525,7 @@ DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
usage: (trace-to-stderr STRING &rest OBJECTS) */) usage: (trace-to-stderr STRING &rest OBJECTS) */)
(ptrdiff_t nargs, Lisp_Object *args) (ptrdiff_t nargs, Lisp_Object *args)
{ {
Lisp_Object s = styled_format (nargs, args, false, false); Lisp_Object s = Fformat (nargs, args);
fwrite (SDATA (s), 1, SBYTES (s), stderr); fwrite (SDATA (s), 1, SBYTES (s), stderr);
return Qnil; return Qnil;
} }

View file

@ -345,6 +345,7 @@ get_user_db (Display *display)
db = XrmGetStringDatabase (xdefs); db = XrmGetStringDatabase (xdefs);
else else
{ {
/* Use ~/.Xdefaults. */
char *home = gethomedir (); char *home = gethomedir ();
ptrdiff_t homelen = strlen (home); ptrdiff_t homelen = strlen (home);
char *filename = xrealloc (home, homelen + sizeof xdefaults); char *filename = xrealloc (home, homelen + sizeof xdefaults);
@ -375,13 +376,15 @@ get_environ_db (void)
if (!p) if (!p)
{ {
/* Use ~/.Xdefaults-HOSTNAME. */
char *home = gethomedir (); char *home = gethomedir ();
ptrdiff_t homelen = strlen (home); ptrdiff_t homelen = strlen (home);
Lisp_Object system_name = Fsystem_name (); Lisp_Object system_name = Fsystem_name ();
ptrdiff_t filenamesize = (homelen + sizeof xdefaults ptrdiff_t filenamesize = (homelen + sizeof xdefaults
+ SBYTES (system_name)); + 1 + SBYTES (system_name));
p = filename = xrealloc (home, filenamesize); p = filename = xrealloc (home, filenamesize);
lispstpcpy (stpcpy (filename + homelen, xdefaults), system_name); lispstpcpy (stpcpy (stpcpy (filename + homelen, xdefaults), "-"),
system_name);
} }
db = XrmGetFileDatabase (p); db = XrmGetFileDatabase (p);

View file

@ -282,3 +282,13 @@ identical output.
(ert-deftest cps-test-declarations-preserved () (ert-deftest cps-test-declarations-preserved ()
(should (equal (documentation 'generator-with-docstring) "Documentation!")) (should (equal (documentation 'generator-with-docstring) "Documentation!"))
(should (equal (get 'generator-with-docstring 'lisp-indent-function) 5))) (should (equal (get 'generator-with-docstring 'lisp-indent-function) 5)))
(ert-deftest cps-iter-lambda-with-dynamic-binding ()
"`iter-lambda' with dynamic binding produces correct result (bug#25965)."
(should (= 1
(iter-next
(funcall (iter-lambda ()
(let* ((fill-column 10) ;;any special variable will do
(i 0)
(j (setq i (1+ i))))
(iter-yield i))))))))

View file

@ -3438,7 +3438,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(fboundp 'connection-local-set-profiles))) (fboundp 'connection-local-set-profiles)))
;; `connection-local-set-profile-variables' and ;; `connection-local-set-profile-variables' and
;; `connection-local-set-profiles' exists since Emacs 26. We don't ;; `connection-local-set-profiles' exist since Emacs 26. We don't
;; want to see compiler warnings for older Emacsen. ;; want to see compiler warnings for older Emacsen.
(let ((default-directory tramp-test-temporary-file-directory) (let ((default-directory tramp-test-temporary-file-directory)
explicit-shell-file-name kill-buffer-query-functions) explicit-shell-file-name kill-buffer-query-functions)
@ -4108,12 +4108,29 @@ Use the `ls' command."
tramp-connection-properties))) tramp-connection-properties)))
(tramp--test-utf8))) (tramp--test-utf8)))
(ert-deftest tramp-test37-file-system-info ()
"Check that `file-system-info' returns proper values."
(skip-unless (tramp--test-enabled))
;; Since Emacs 27.1.
(skip-unless (fboundp 'file-system-info))
;; `file-system-info' exists since Emacs 27. We don't
;; want to see compiler warnings for older Emacsen.
(let ((fsi (with-no-warnings
(file-system-info tramp-test-temporary-file-directory))))
(skip-unless fsi)
(should (and (consp fsi)
(= (length fsi) 3)
(numberp (nth 0 fsi))
(numberp (nth 1 fsi))
(numberp (nth 2 fsi))))))
(defun tramp--test-timeout-handler () (defun tramp--test-timeout-handler ()
(interactive) (interactive)
(ert-fail (format "`%s' timed out" (ert-test-name (ert-running-test))))) (ert-fail (format "`%s' timed out" (ert-test-name (ert-running-test)))))
;; This test is inspired by Bug#16928. ;; This test is inspired by Bug#16928.
(ert-deftest tramp-test37-asynchronous-requests () (ert-deftest tramp-test38-asynchronous-requests ()
"Check parallel asynchronous requests. "Check parallel asynchronous requests.
Such requests could arrive from timers, process filters and Such requests could arrive from timers, process filters and
process sentinels. They shall not disturb each other." process sentinels. They shall not disturb each other."
@ -4270,7 +4287,7 @@ process sentinels. They shall not disturb each other."
(ignore-errors (cancel-timer timer)) (ignore-errors (cancel-timer timer))
(ignore-errors (delete-directory tmp-name 'recursive))))))) (ignore-errors (delete-directory tmp-name 'recursive)))))))
(ert-deftest tramp-test38-recursive-load () (ert-deftest tramp-test39-recursive-load ()
"Check that Tramp does not fail due to recursive load." "Check that Tramp does not fail due to recursive load."
(skip-unless (tramp--test-enabled)) (skip-unless (tramp--test-enabled))
@ -4293,7 +4310,7 @@ process sentinels. They shall not disturb each other."
(mapconcat 'shell-quote-argument load-path " -L ") (mapconcat 'shell-quote-argument load-path " -L ")
(shell-quote-argument code)))))))) (shell-quote-argument code))))))))
(ert-deftest tramp-test39-remote-load-path () (ert-deftest tramp-test40-remote-load-path ()
"Check that Tramp autoloads its packages with remote `load-path'." "Check that Tramp autoloads its packages with remote `load-path'."
;; `tramp-cleanup-all-connections' is autoloaded from tramp-cmds.el. ;; `tramp-cleanup-all-connections' is autoloaded from tramp-cmds.el.
;; It shall still work, when a remote file name is in the ;; It shall still work, when a remote file name is in the
@ -4316,7 +4333,7 @@ process sentinels. They shall not disturb each other."
(mapconcat 'shell-quote-argument load-path " -L ") (mapconcat 'shell-quote-argument load-path " -L ")
(shell-quote-argument code))))))) (shell-quote-argument code)))))))
(ert-deftest tramp-test40-unload () (ert-deftest tramp-test41-unload ()
"Check that Tramp and its subpackages unload completely. "Check that Tramp and its subpackages unload completely.
Since it unloads Tramp, it shall be the last test to run." Since it unloads Tramp, it shall be the last test to run."
:tags '(:expensive-test) :tags '(:expensive-test)
@ -4374,7 +4391,7 @@ Since it unloads Tramp, it shall be the last test to run."
;; * Fix `tramp-test05-expand-file-name-relative' in `expand-file-name'. ;; * Fix `tramp-test05-expand-file-name-relative' in `expand-file-name'.
;; * Fix `tramp-test06-directory-file-name' for `ftp'. ;; * Fix `tramp-test06-directory-file-name' for `ftp'.
;; * Fix `tramp-test27-start-file-process' on MS Windows (`process-send-eof'?). ;; * Fix `tramp-test27-start-file-process' on MS Windows (`process-send-eof'?).
;; * Fix Bug#16928 in `tramp-test37-asynchronous-requests'. ;; * Fix Bug#16928 in `tramp-test38-asynchronous-requests'.
(defun tramp-test-all (&optional interactive) (defun tramp-test-all (&optional interactive)
"Run all tests for \\[tramp]." "Run all tests for \\[tramp]."

View file

@ -1,6 +1,6 @@
# Makefile for flymake tests # Makefile for flymake tests
CC_OPTS = -Wall CC_OPTS = -Wall -Wextra
## Recent gcc (e.g. 4.8.2 on RHEL7) can automatically colorize their output, ## Recent gcc (e.g. 4.8.2 on RHEL7) can automatically colorize their output,
## which can confuse flymake. Set GCC_COLORS to disable that. ## which can confuse flymake. Set GCC_COLORS to disable that.
@ -8,6 +8,6 @@ CC_OPTS = -Wall
## normally use flymake, so it seems like just avoiding the issue ## normally use flymake, so it seems like just avoiding the issue
## in this test is fine. Set flymake-log-level to 3 to investigate. ## in this test is fine. Set flymake-log-level to 3 to investigate.
check-syntax: check-syntax:
GCC_COLORS= $(CC) $(CC_OPTS) ${CHK_SOURCES} GCC_COLORS= $(CC) $(CC_OPTS) ${CHK_SOURCES} || true
# eof # eof

View file

@ -0,0 +1,13 @@
/* Flymake should notice an error on the next line, since
that file has at least one warning.*/
#include "some-problems.h"
/* But not this one */
#include "no-problems.h"
int main()
{
char c = 1000; /* a note and a warning */
int bla;
char c; if (bla == (void*)3); /* an error, and two warnings */
return c;
}

View file

@ -0,0 +1 @@
typedef int no_problems;

View file

@ -0,0 +1,5 @@
#include <stdio.h>
strange;
sint main();

View file

@ -1,4 +1,4 @@
;;; flymake-tests.el --- Test suite for flymake ;;; flymake-tests.el --- Test suite for flymake -*- lexical-binding: t -*-
;; Copyright (C) 2011-2017 Free Software Foundation, Inc. ;; Copyright (C) 2011-2017 Free Software Foundation, Inc.
@ -26,54 +26,295 @@
(require 'flymake) (require 'flymake)
(defvar flymake-tests-data-directory (defvar flymake-tests-data-directory
(expand-file-name "lisp/progmodes/flymake-resources" (getenv "EMACS_TEST_DIRECTORY")) (expand-file-name "lisp/progmodes/flymake-resources"
(or (getenv "EMACS_TEST_DIRECTORY")
(expand-file-name "../../.."
(or load-file-name
buffer-file-name))))
"Directory containing flymake test data.") "Directory containing flymake test data.")
;; Warning predicate ;;
(defun flymake-tests--current-face (file predicate) ;;
(let ((buffer (find-file-noselect (defun flymake-tests--wait-for-backends ()
(expand-file-name file flymake-tests-data-directory))) ;; Weirdness here... http://debbugs.gnu.org/17647#25
(process-environment (cons "LC_ALL=C" process-environment)) ;; ... meaning `sleep-for', and even
(i 0)) ;; `accept-process-output', won't suffice as ways to get
;; process filters and sentinels to run, though they do work
;; fine in a non-interactive batch session. The only thing
;; that will indeed unblock pending process output is
;; reading an input event, so, as a workaround, use a dummy
;; `read-event' with a very short timeout.
(unless noninteractive (read-event "" nil 0.1))
(cl-loop repeat 5
for notdone = (cl-set-difference (flymake-running-backends)
(flymake-reporting-backends))
while notdone
unless noninteractive do (read-event "" nil 0.1)
do (sleep-for (+ 0.5 flymake-no-changes-timeout))
finally (when notdone (ert-fail
(format "Some backends not reporting yet %s"
notdone)))))
(cl-defun flymake-tests--call-with-fixture (fn file
&key (severity-predicate
nil sev-pred-supplied-p))
"Call FN after flymake setup in FILE, using `flymake-proc`.
SEVERITY-PREDICATE is used to setup
`flymake-proc-diagnostic-type-pred'"
(let* ((file (expand-file-name file flymake-tests-data-directory))
(visiting (find-buffer-visiting file))
(buffer (or visiting (find-file-noselect file)))
(process-environment (cons "LC_ALL=C" process-environment))
(warning-minimum-log-level :error))
(unwind-protect (unwind-protect
(with-current-buffer buffer (with-current-buffer buffer
(setq-local flymake-warning-predicate predicate) (save-excursion
(goto-char (point-min)) (when sev-pred-supplied-p
(flymake-mode 1) (setq-local flymake-proc-diagnostic-type-pred severity-predicate))
;; Weirdness here... https://debbugs.gnu.org/17647#25 (goto-char (point-min))
(while (and flymake-is-running (< (setq i (1+ i)) 10)) (unless flymake-mode (flymake-mode 1))
(sleep-for (+ 0.5 flymake-no-changes-timeout))) (flymake-tests--wait-for-backends)
(flymake-goto-next-error) (funcall fn)))
(face-at-point)) (and buffer
(and buffer (let (kill-buffer-query-functions) (kill-buffer buffer)))))) (not visiting)
(let (kill-buffer-query-functions) (kill-buffer buffer))))))
(cl-defmacro flymake-tests--with-flymake ((file &rest args)
&body body)
(declare (indent 1)
(debug (sexp &rest form)))
`(flymake-tests--call-with-fixture (lambda () ,@body) ,file ,@args))
(ert-deftest warning-predicate-rx-gcc () (ert-deftest warning-predicate-rx-gcc ()
"Test GCC warning via regexp predicate." "Test GCC warning via regexp predicate."
(skip-unless (and (executable-find "gcc") (executable-find "make"))) (skip-unless (and (executable-find "gcc") (executable-find "make")))
(should (eq 'flymake-warnline (flymake-tests--with-flymake
(flymake-tests--current-face "test.c" "^[Ww]arning")))) ("test.c" :severity-predicate "^[Ww]arning")
(flymake-goto-next-error)
(should (eq 'flymake-warning
(face-at-point)))))
(ert-deftest warning-predicate-function-gcc () (ert-deftest warning-predicate-function-gcc ()
"Test GCC warning via function predicate." "Test GCC warning via function predicate."
(skip-unless (and (executable-find "gcc") (executable-find "make"))) (skip-unless (and (executable-find "gcc") (executable-find "make")))
(should (eq 'flymake-warnline (flymake-tests--with-flymake
(flymake-tests--current-face "test.c" ("test.c" :severity-predicate
(lambda (msg) (string-match "^[Ww]arning" msg)))))) (lambda (msg) (string-match "^[Ww]arning" msg)))
(flymake-goto-next-error)
(should (eq 'flymake-warning
(face-at-point)))))
(ert-deftest warning-predicate-rx-perl () (ert-deftest warning-predicate-rx-perl ()
"Test perl warning via regular expression predicate." "Test perl warning via regular expression predicate."
(skip-unless (executable-find "perl")) (skip-unless (executable-find "perl"))
(should (eq 'flymake-warnline (flymake-tests--with-flymake
(flymake-tests--current-face "test.pl" "^Scalar value")))) ("test.pl" :severity-predicate "^Scalar value")
(flymake-goto-next-error)
(should (eq 'flymake-warning
(face-at-point)))))
(ert-deftest warning-predicate-function-perl () (ert-deftest warning-predicate-function-perl ()
"Test perl warning via function predicate." "Test perl warning via function predicate."
(skip-unless (executable-find "perl")) (skip-unless (executable-find "perl"))
(should (eq 'flymake-warnline (flymake-tests--with-flymake
(flymake-tests--current-face ("test.pl" :severity-predicate
"test.pl" (lambda (msg) (string-match "^Scalar value" msg)))
(lambda (msg) (string-match "^Scalar value" msg)))))) (flymake-goto-next-error)
(should (eq 'flymake-warning
(face-at-point)))))
(ert-deftest different-diagnostic-types ()
"Test GCC warning via function predicate."
(skip-unless (and (executable-find "gcc") (executable-find "make")))
(let ((flymake-wrap-around nil))
(flymake-tests--with-flymake
("errors-and-warnings.c")
(flymake-goto-next-error)
(should (eq 'flymake-error (face-at-point)))
(flymake-goto-next-error)
(should (eq 'flymake-note (face-at-point)))
(flymake-goto-next-error)
(should (eq 'flymake-warning (face-at-point)))
(flymake-goto-next-error)
(should (eq 'flymake-error (face-at-point)))
(flymake-goto-next-error)
(should (eq 'flymake-warning (face-at-point)))
(flymake-goto-next-error)
(should (eq 'flymake-warning (face-at-point)))
(should-error (flymake-goto-next-error nil nil t)))))
(ert-deftest included-c-header-files ()
"Test inclusion of .h header files."
(skip-unless (and (executable-find "gcc") (executable-find "make")))
(let ((flymake-wrap-around nil))
(flymake-tests--with-flymake
("some-problems.h")
(flymake-goto-next-error)
(should (eq 'flymake-warning (face-at-point)))
(flymake-goto-next-error)
(should (eq 'flymake-error (face-at-point)))
(should-error (flymake-goto-next-error nil nil t)))
(flymake-tests--with-flymake
("no-problems.h")
(should-error (flymake-goto-next-error nil nil t)))))
(defmacro flymake-tests--assert-set (set
should
should-not)
(declare (indent 1))
`(progn
,@(cl-loop
for s in should
collect `(should (memq (quote ,s) ,set)))
,@(cl-loop
for s in should-not
collect `(should-not (memq (quote ,s) ,set)))))
(defun flymake-tests--diagnose-words
(report-fn type words)
"Helper. Call REPORT-FN with diagnostics for WORDS in buffer."
(funcall report-fn
(cl-loop
for word in words
append
(save-excursion
(goto-char (point-min))
(cl-loop while (word-search-forward word nil t)
collect (flymake-make-diagnostic
(current-buffer)
(match-beginning 0)
(match-end 0)
type
(concat word " is wrong")))))))
(ert-deftest dummy-backends ()
"Test many different kinds of backends."
(with-temp-buffer
(cl-letf
(((symbol-function 'error-backend)
(lambda (report-fn)
(run-with-timer
0.5 nil
#'flymake-tests--diagnose-words report-fn :error '("manha" "prognata"))))
((symbol-function 'warning-backend)
(lambda (report-fn)
(run-with-timer
0.5 nil
#'flymake-tests--diagnose-words report-fn :warning '("ut" "dolor"))))
((symbol-function 'sync-backend)
(lambda (report-fn)
(flymake-tests--diagnose-words report-fn :note '("quis" "commodo"))))
((symbol-function 'panicking-backend)
(lambda (report-fn)
(run-with-timer
0.5 nil
report-fn :panic :explanation "The spanish inquisition!")))
((symbol-function 'crashing-backend)
(lambda (_report-fn)
;; HACK: Shoosh log during tests
(setq-local warning-minimum-log-level :emergency)
(error "crashed"))))
(insert "Lorem ipsum dolor sit amet, consectetur adipiscing
elit, sed do eiusmod tempor incididunt ut labore et dolore
manha aliqua. Ut enim ad minim veniam, quis nostrud
exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in
voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non prognata
sunt in culpa qui officia deserunt mollit anim id est
laborum.")
(let ((flymake-diagnostic-functions
(list 'error-backend 'warning-backend 'sync-backend
'panicking-backend
'crashing-backend
))
(flymake-wrap-around nil))
(flymake-mode)
(flymake-tests--assert-set (flymake-running-backends)
(error-backend warning-backend panicking-backend)
(crashing-backend))
(flymake-tests--assert-set (flymake-disabled-backends)
(crashing-backend)
(error-backend warning-backend sync-backend
panicking-backend))
(flymake-tests--wait-for-backends)
(flymake-tests--assert-set (flymake-disabled-backends)
(crashing-backend panicking-backend)
(error-backend warning-backend sync-backend))
(goto-char (point-min))
(flymake-goto-next-error)
(should (eq 'flymake-warning (face-at-point))) ; dolor
(flymake-goto-next-error)
(should (eq 'flymake-warning (face-at-point))) ; ut
(flymake-goto-next-error)
(should (eq 'flymake-error (face-at-point))) ; manha
(flymake-goto-next-error)
(should (eq 'flymake-warning (face-at-point))) ; Ut
(flymake-goto-next-error)
(should (eq 'flymake-note (face-at-point))) ; quis
(flymake-goto-next-error)
(should (eq 'flymake-warning (face-at-point))) ; ut
(flymake-goto-next-error)
(should (eq 'flymake-note (face-at-point))) ; commodo
(flymake-goto-next-error)
(should (eq 'flymake-warning (face-at-point))) ; dolor
(flymake-goto-next-error)
(should (eq 'flymake-error (face-at-point))) ; prognata
(should-error (flymake-goto-next-error nil nil t))))))
(ert-deftest recurrent-backend ()
"Test a backend that calls REPORT-FN multiple times"
(with-temp-buffer
(let (tick)
(cl-letf
(((symbol-function 'eager-backend)
(lambda (report-fn)
(funcall report-fn nil :explanation "very eager but no diagnostics")
(display-buffer (current-buffer))
(run-with-timer
0.5 nil
(lambda ()
(flymake-tests--diagnose-words report-fn :warning '("consectetur"))
(setq tick t)
(run-with-timer
0.5 nil
(lambda ()
(flymake-tests--diagnose-words report-fn :error '("fugiat"))
(setq tick t))))))))
(insert "Lorem ipsum dolor sit amet, consectetur adipiscing
elit, sed do eiusmod tempor incididunt ut labore et dolore
manha aliqua. Ut enim ad minim veniam, quis nostrud
exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in
voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non prognata
sunt in culpa qui officia deserunt mollit anim id est
laborum.")
(let ((flymake-diagnostic-functions
(list 'eager-backend))
(flymake-wrap-around nil))
(flymake-mode)
(flymake-tests--assert-set (flymake-running-backends)
(eager-backend) ())
(cl-loop until tick repeat 4 do (sleep-for 0.2))
(setq tick nil)
(goto-char (point-max))
(flymake-goto-prev-error)
(should (eq 'flymake-warning (face-at-point))) ; consectetur
(should-error (flymake-goto-prev-error nil nil t))
(cl-loop until tick repeat 4 do (sleep-for 0.2))
(flymake-goto-next-error)
(should (eq 'flymake-error (face-at-point))) ; fugiat
(flymake-goto-prev-error)
(should (eq 'flymake-warning (face-at-point))) ; back at consectetur
(should-error (flymake-goto-prev-error nil nil t))
)))))
(provide 'flymake-tests) (provide 'flymake-tests)