Subject: bug#76373: 31.0.50; Extend autoconf-mode macro support

From: "Basil L. Contovounesios" <[email-masked]>
Date: Mon, 17 Feb 2025 22:05:48 +0100

The attached patch extends autoconf-mode to:

- also fontify AU_, AX_, and gl_ macro calls as keywords;

- also recognise AH_, AS_, AU_, AX_, LT_, and gl_ macro calls as targets
  for beginning-of-defun, but not an opening square bracket in column 0;

- fontify the first argument of AC_DEFINE, AC_DEFINE_UNQUOTED, AC_SUBST,
  and AH_TEMPLATE with font-lock-variable-name-face instead of
  font-lock-function-name-face;

- also fontify the first argument of AH_VERBATIM, AM_CONDITIONAL, and
  AM_MISSING_PROG as a variable;

- fontify the first argument of AC_DEFUN, AC_DEFUN_ONCE, AU_ALIAS,
  AU_DEFUN, and function-like AC_DEFINE as a function;

- support backslashes, variable substitutions, and command substitutions
  with backticks in the first argument of AC_DEFINE_UNQUOTED; and

- fontify changequote only when it stands freely, not when it is part of
  m4_changequote (where either the whole macro name should be fontified,
  or no part of it).

WDYT?

Also, a question: should defun-prompt-regexp really allow for leading
indentation?  In Autoconf scripts of the form:

if ...

  ...
  AC_MSG_...
  ...
  AC_MSG_...
  ...

fi

it means that beginning-of-defun stops at every indented AC_ or AM_
macro call (and with the attached patch, at any macro call with a known
namespace).

Is this a feature (which allows jumping to the Autoconf parts in a sea
of shell code), or does it break from expected beginning-of-defun
semantics?

Thanks,
-- 
Basil

>From 584df731dc453f63bdc95ef08c8476bf6d973d60 Mon Sep 17 00:00:00 2001
From: "Basil L. Contovounesios" <[email-masked]>
Date: Wed, 29 Jan 2025 14:05:39 +0100
Subject: [PATCH] Improve autoconf-mode macro detection

* doc/lispref/modes.texi (Search-based Fontification): Fix
indentation of (MATCHER . FACESPEC) example.
* doc/misc/cc-mode.texi (Performance Issues): Index
defun-prompt-regexp under variables, not functions.

* lisp/progmodes/autoconf.el (autoconf--symbol, autoconf--macro):
New rx definitions.
(autoconf-definition-regexp): Use an optional second capture group
to indicate a function rather than variable definition.  Detect
AC_DEFINE defining a function-like CPP macro.  Skip more shell
syntax such as variable ${} expansion and command `` substitution in
AC_DEFINE_UNQUOTED variable.  Match AH_VERBATIM, AM_CONDITIONAL, and
AM_MISSING_PROG as defining variables, and AC_DEFUN, AC_DEFUN_ONCE,
AU_ALIAS, and AU_DEFUN as defining functions.  Document first
capture group in docstring.
(autoconf-font-lock-keywords): Use autoconf--macro to match more
Autoconf macros, such as those defined in the Autoconf Archive and
Gnulib.  Reserve font-lock-function-name-face for function
definitions as determined by autoconf-definition-regexp, and use
font-lock-variable-name-face for the rest instead.  Use Font Lock
face symbols directly in place of their corresponding variable.
Fontify M4 changequote primitive only as a standalone symbol.
(autoconf-imenu-generic-expression): Add commentary mentioning new
submenu possibility.
(autoconf-current-defun-function): Update docstring accuracy.
Replace line-end-position with pos-eol since there are no fields.
(autoconf-mode): Define defun-prompt-regexp in terms of
autoconf--macro to support more toplevel macros, such as those
defined in Autoheader, M4sh, etc.  Set
open-paren-in-column-0-is-defun-start to nil to avoid false
positives when an Autoconf quote character is in column zero.

* test/lisp/progmodes/autoconf-resources/configure.ac: New file.
* test/lisp/progmodes/autoconf-tests.el
(autoconf-tests-current-defun-function-define)
(autoconf-tests-current-defun-function-subst): Replace character
motion with search.
(autoconf-tests-autoconf-mode-comment-syntax): Ditto.  Test both dnl
and # comments.  Use syntax-ppss-context.
(autoconf-tests-font-lock): New test.
---
 doc/lispref/modes.texi                        |   2 +-
 doc/misc/cc-mode.texi                         |   2 +-
 lisp/progmodes/autoconf.el                    |  65 ++++++-
 .../progmodes/autoconf-resources/configure.ac | 172 ++++++++++++++++++
 test/lisp/progmodes/autoconf-tests.el         |  32 ++--
 5 files changed, 249 insertions(+), 24 deletions(-)
 create mode 100644 test/lisp/progmodes/autoconf-resources/configure.ac

diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi
index 6e2a9d8221e..04a2e2ce059 100644
--- a/doc/lispref/modes.texi
+++ b/doc/lispref/modes.texi
@@ -3420,7 +3420,7 @@ Search-based Fontification
 
 @example
 (@var{subexp}
-(face @var{face} @var{prop1} @var{val1} @var{prop2} @var{val2}@dots{}))
+ (face @var{face} @var{prop1} @var{val1} @var{prop2} @var{val2}@dots{}))
 @end example
 
 @noindent
diff --git a/doc/misc/cc-mode.texi b/doc/misc/cc-mode.texi
index b8a68f054f2..d443fddd3f8 100644
--- a/doc/misc/cc-mode.texi
+++ b/doc/misc/cc-mode.texi
@@ -7531,7 +7531,7 @@ Performance Issues
 searching for such a brace when it's not in column 0 is minimal,
 except perhaps when you've just moved a long way inside the file.
 
-@findex defun-prompt-regexp
+@vindex defun-prompt-regexp
 @vindex c-Java-defun-prompt-regexp
 @vindex Java-defun-prompt-regexp @r{(c-)}
 A special note about @code{defun-prompt-regexp} in Java mode: The common
diff --git a/lisp/progmodes/autoconf.el b/lisp/progmodes/autoconf.el
index 8cee38cf033..c5b076bfacc 100644
--- a/lisp/progmodes/autoconf.el
+++ b/lisp/progmodes/autoconf.el
@@ -40,16 +40,58 @@ autoconf-mode-map
 (defvar autoconf-mode-hook nil
   "Hook run by `autoconf-mode'.")
 
+(rx-define autoconf--symbol (+ (| (syntax word) (syntax symbol))))
+
+;; Any Autoconf macro name.
+(rx-define autoconf--macro
+  (: (| "AC"  ;; Autoconf.
+        "AH"  ;; Autoheader.
+        "AM"  ;; Automake.
+        "AS"  ;; M4sh.
+        "AU"  ;; Autoupdate.
+        "AX"  ;; Autoconf Archive.
+        "LT"  ;; Libtool.
+        "gl") ;; Gnulib.
+     ?_ autoconf--symbol))
+
 (defconst autoconf-definition-regexp
-  "A\\(?:H_TEMPLATE\\|C_\\(?:SUBST\\|DEFINE\\(?:_UNQUOTED\\)?\\)\\)(\\[*\\(\\(?:\\sw\\|\\s_\\)+\\)\\]*")
+  ;; Historically this `defconst' defined only group #1.
+  ;; For internal Font Lock use, the presence of an optional group #2
+  ;; identifies a function rather than variable definition.
+  (rx-let ((argbeg (: ?\( (* ?\[)))
+           (argend (in "]),"))
+           (plaindef (: argbeg (group-n 1 autoconf--symbol))))
+    (rx symbol-start
+        (| (: "AC_DEFINE"
+              ;; AC_DEFINE and AC_DEFINE_UNQUOTED can define object- and
+              ;; function-like CPP macros.  An open-paren is easy to
+              ;; detect in the case of AC_DEFINE.  Doing the same for
+              ;; AC_DEFINE_UNQUOTED in the general case requires
+              ;; knowledge of shell syntax, so don't bother for now.
+              (| (: plaindef (? (group-n 2 ?\()))
+                 (: "_UNQUOTED" argbeg (group-n 1 (+ (not argend))))))
+           (: (| "AC_SUBST"
+                 "AH_TEMPLATE"
+                 "AH_VERBATIM"
+                 "AM_CONDITIONAL"
+                 "AM_MISSING_PROG"
+                 (group-n 2 (| "AC_DEFUN"
+                               "AC_DEFUN_ONCE"
+                               "AU_ALIAS"
+                               "AU_DEFUN")))
+              plaindef))))
+  "Matches Autoconf macro calls that define something.
+The thing being defined is captured in the first subexpression group.")
 
 (defvar autoconf-font-lock-keywords
-  `(("\\_<\\(?:A[CHMS]\\|LT\\)_\\(?:\\sw\\|\\s_\\)+" . font-lock-keyword-face)
+  `(,(rx symbol-start autoconf--macro)
     (,autoconf-definition-regexp
-     1 font-lock-function-name-face)
+     1 (if (match-beginning 2)
+           'font-lock-function-name-face
+         'font-lock-variable-name-face))
     ;; Are any other M4 keywords really appropriate for configure.ac,
     ;; given that we do `dnl'?
-    ("changequote" . font-lock-keyword-face)))
+    "\\_<changequote\\_>"))
 
 (defvar autoconf-mode-syntax-table
   (let ((table (make-syntax-table)))
@@ -59,15 +101,17 @@ autoconf-mode-syntax-table
     table))
 
 (defvar autoconf-imenu-generic-expression
+  ;; This lists both variable-like and function-like definitions in a
+  ;; flat list, but they could be distinguished if desired.
   (list (list nil autoconf-definition-regexp 1)))
 
 ;; It's not clear how best to implement this.
 (defun autoconf-current-defun-function ()
   "Function to use for `add-log-current-defun-function' in Autoconf mode.
-This version looks back for an AC_DEFINE or AC_SUBST.  It will stop
-searching backwards at another AC_... command."
+This version looks back for a definition such as by AC_DEFINE or
+AC_SUBST.  It stops searching when it encounters other Autoconf macros."
   (save-excursion
-    (skip-syntax-forward "w_" (line-end-position))
+    (skip-syntax-forward "w_" (pos-eol))
     (if (re-search-backward autoconf-definition-regexp
                             (save-excursion (beginning-of-defun) (point))
                             t)
@@ -77,14 +121,15 @@ autoconf-current-defun-function
 (define-derived-mode autoconf-mode prog-mode "Autoconf"
   "Major mode for editing Autoconf configure.ac files."
   (setq-local parens-require-spaces nil) ; for M4 arg lists
-  (setq-local defun-prompt-regexp "^[ \t]*A[CM]_\\(\\sw\\|\\s_\\)+")
+  ;; FIXME: Should indented macro calls really count as defuns?
+  (setq-local defun-prompt-regexp (rx bol (* (in "\t ")) autoconf--macro))
+  (setq-local open-paren-in-column-0-is-defun-start nil)
   (setq-local comment-start "dnl ")
   ;; We want to avoid matching "dnl" in other text.
   (setq-local comment-start-skip "\\(?:\\(\\W\\|^\\)dnl\\|#\\) +")
   (setq-local syntax-propertize-function
 	      (syntax-propertize-rules ("\\<dnl\\>" (0 "<"))))
-  (setq-local font-lock-defaults
-	      '(autoconf-font-lock-keywords nil nil))
+  (setq-local font-lock-defaults '(autoconf-font-lock-keywords))
   (setq-local imenu-generic-expression autoconf-imenu-generic-expression)
   (setq-local indent-line-function #'indent-relative)
   (setq-local add-log-current-defun-function
diff --git a/test/lisp/progmodes/autoconf-resources/configure.ac b/test/lisp/progmodes/autoconf-resources/configure.ac
new file mode 100644
index 00000000000..b05c556f029
--- /dev/null
+++ b/test/lisp/progmodes/autoconf-resources/configure.ac
@@ -0,0 +1,172 @@
+# Indentation.
+
+AC_PROG_CC
+dnl <- font-lock-keyword-face
+ AC_PROG_CC
+ dnl <- font-lock-keyword-face
+  AC_PROG_CC
+  dnl <- font-lock-keyword-face
+
+# Quoting.
+
+   [AC_PROG_CC] [[AC_PREREQ([2.70])]]
+dnl ^^^^^^^^^^    ^^^^^^^^^ font-lock-keyword-face
+
+# Nesting.
+
+AS_VAR_IF([foo], [bar], [AC_MSG_FAILURE([baz])])
+dnl <- font-lock-keyword-face
+dnl                      ^^^^^^^^^^^^^^ font-lock-keyword-face
+AS_VAR_IF([foo], [bar],
+dnl <- font-lock-keyword-face
+   [AC_MSG_FAILURE([baz])])
+dnl ^^^^^^^^^^^^^^ font-lock-keyword-face
+
+# Autoconf.
+
+AC_PROG_CC AC_PREREQ(2.70) AC_PREREQ([2.70])
+dnl <- font-lock-keyword-face
+dnl        ^^^^^^^^^       ^^^^^^^^^ font-lock-keyword-face
+
+# Autoheader.
+
+AH_HEADER AH_TOP(foo) AH_TOP([foo])
+dnl <- font-lock-keyword-face
+dnl       ^^^^^^      ^^^^^^ font-lock-keyword-face
+
+# Automake.
+
+AM_PATH_LISPDIR AM_SILENT_RULES(yes) AM_SILENT_RULES([yes])
+dnl <- font-lock-keyword-face
+dnl             ^^^^^^^^^^^^^^^      ^^^^^^^^^^^^^^^ font-lock-keyword-face
+
+# M4sh.
+
+AS_INIT AS_ECHO(foo) AS_ECHO([foo])
+dnl <- font-lock-keyword-face
+dnl     ^^^^^^^      ^^^^^^^ font-lock-keyword-face
+
+# Autoconf Archive.
+
+AX_ADD_FORTIFY_SOURCE AX_SAVE_FLAGS(foo) AX_SAVE_FLAGS([foo])
+dnl <- font-lock-keyword-face
+dnl                   ^^^^^^^^^^^^^      ^^^^^^^^^^^^^ font-lock-keyword-face
+
+# Libtool.
+
+LT_OUTPUT LT_PREREQ(2.4.6) LT_PREREQ([2.4.6])
+dnl <- font-lock-keyword-face
+dnl       ^^^^^^^^^        ^^^^^^^^^ font-lock-keyword-face
+
+# Gnulib.
+
+gl_EARLY gl_WARN_ADD(foo) gl_WARN_ADD([foo])
+dnl <- font-lock-keyword-face
+dnl      ^^^^^^^^^^^      ^^^^^^^^^^^ font-lock-keyword-face
+
+# M4.
+
+changequote(<<, >>) m4_changequote(<<, >>)
+dnl <- font-lock-keyword-face
+dnl                 ^^^^^^^^^^^^^^ !font-lock-keyword-face
+changequote([, ]) m4_changequote([, ])
+dnl <- font-lock-keyword-face
+dnl               ^^^^^^^^^^^^^^ !font-lock-keyword-face
+
+# AC_DEFINE object-like macro.
+
+AC_DEFINE(a) AC_DEFINE(a, d)
+dnl <- font-lock-keyword-face
+dnl          ^^^^^^^^^ font-lock-keyword-face
+dnl       ^            ^ font-lock-variable-name-face
+AC_DEFINE([a]) AC_DEFINE([a], d)
+dnl        ^              ^ font-lock-variable-name-face
+AC_DEFINE([[a]]) AC_DEFINE([[a]], d)
+dnl         ^                ^ font-lock-variable-name-face
+AC_DEFINE(bc) AC_DEFINE(bc, d)
+dnl       ^^            ^^ font-lock-variable-name-face
+AC_DEFINE([bc]) AC_DEFINE([bc], d)
+dnl        ^^              ^^ font-lock-variable-name-face
+AC_DEFINE([[bc]]) AC_DEFINE([[bc]], d)
+dnl         ^^                ^^ font-lock-variable-name-face
+
+# AC_DEFINE function-like macro.
+
+AC_DEFINE(a()) AC_DEFINE(a(), d)
+dnl <- font-lock-keyword-face
+dnl            ^^^^^^^^^ font-lock-keyword-face
+dnl       ^              ^ font-lock-function-name-face
+AC_DEFINE([a()]) AC_DEFINE([a()], d)
+dnl        ^                ^ font-lock-function-name-face
+AC_DEFINE([[a()]]) AC_DEFINE([[a()]], d)
+dnl         ^                  ^ font-lock-function-name-face
+AC_DEFINE(a(x)) AC_DEFINE(a(x), d)
+dnl       ^               ^ font-lock-function-name-face
+AC_DEFINE([a(x)]) AC_DEFINE([a(x)], d)
+dnl        ^                 ^ font-lock-function-name-face
+AC_DEFINE([[a(x)]]) AC_DEFINE([[a(x)]], d)
+dnl         ^                   ^ font-lock-function-name-face
+AC_DEFINE(a(x, y)) AC_DEFINE(a(x, y), d)
+dnl       ^                  ^ font-lock-function-name-face
+AC_DEFINE([a(x, y)]) AC_DEFINE([a(x, y)], d)
+dnl        ^                    ^ font-lock-function-name-face
+AC_DEFINE([[a(x, y)]]) AC_DEFINE([[a(x, y)]], d)
+dnl         ^                      ^ font-lock-function-name-face
+
+# AC_DEFINE_UNQUOTED object-like macro.
+
+AC_DEFINE_UNQUOTED(a) AC_DEFINE_UNQUOTED(a, d)
+dnl <- font-lock-keyword-face
+dnl                   ^^^^^^^^^^^^^^^^^^ font-lock-keyword-face
+dnl                ^                     ^ font-lock-variable-name-face
+AC_DEFINE_UNQUOTED([a]) AC_DEFINE_UNQUOTED([a], d)
+dnl                 ^                       ^ font-lock-variable-name-face
+AC_DEFINE_UNQUOTED([[a]]) AC_DEFINE_UNQUOTED([[a]], d)
+dnl                  ^                         ^ font-lock-variable-name-face
+AC_DEFINE_UNQUOTED(bc) AC_DEFINE_UNQUOTED(bc, d)
+dnl                ^^                     ^^ font-lock-variable-name-face
+AC_DEFINE_UNQUOTED([bc]) AC_DEFINE_UNQUOTED([bc], d)
+dnl                 ^^                       ^^ font-lock-variable-name-face
+AC_DEFINE_UNQUOTED([[bc]]) AC_DEFINE_UNQUOTED([[bc]], d)
+dnl                  ^^                         ^^ font-lock-variable-name-face
+AC_DEFINE_UNQUOTED(\a`b`$c${d})
+dnl                ^^^^^^^^^^^ font-lock-variable-name-face
+AC_DEFINE_UNQUOTED([\a`b`$c${d}])
+dnl                 ^^^^^^^^^^^ font-lock-variable-name-face
+AC_DEFINE_UNQUOTED([[\a`b`$c${d}]])
+dnl                  ^^^^^^^^^^^ font-lock-variable-name-face
+AC_DEFINE_UNQUOTED(\a`b`$c${d}, e)
+dnl                ^^^^^^^^^^^ font-lock-variable-name-face
+AC_DEFINE_UNQUOTED([\a`b`$c${d}], e)
+dnl                 ^^^^^^^^^^^ font-lock-variable-name-face
+AC_DEFINE_UNQUOTED([[\a`b`$c${d}]], e)
+dnl                  ^^^^^^^^^^^ font-lock-variable-name-face
+
+# Variable definition.
+
+AC_SUBST(a) AC_SUBST(a, b)
+dnl <- font-lock-keyword-face
+dnl         ^^^^^^^^ font-lock-keyword-face
+dnl      ^           ^ font-lock-variable-name-face
+AH_TEMPLATE(a, b) AH_VERBATIM(a, b)
+dnl <- font-lock-keyword-face
+dnl               ^^^^^^^^^^^ font-lock-keyword-face
+dnl         ^                 ^font-lock-variable-name-face
+AM_CONDITIONAL(a, b) AM_MISSING_PROG(a, b)
+dnl <- font-lock-keyword-face
+dnl                  ^^^^^^^^^^^^^^^ font-lock-keyword-face
+dnl            ^                     ^ font-lock-variable-name-face
+
+# Function definition.
+
+AC_DEFUN(a) AC_DEFUN(a, b)
+dnl <- font-lock-keyword-face
+dnl         ^^^^^^^^ font-lock-keyword-face
+dnl      ^           ^ font-lock-function-name-face
+AC_DEFUN_ONCE(a, b)
+dnl <- font-lock-keyword-face
+dnl           ^ font-lock-function-name-face
+AU_ALIAS(a, b) AU_DEFUN(a, b)
+dnl <- font-lock-keyword-face
+dnl            ^^^^^^^^ font-lock-keyword-face
+dnl      ^              ^ font-lock-function-name-face
diff --git a/test/lisp/progmodes/autoconf-tests.el b/test/lisp/progmodes/autoconf-tests.el
index d4c99218fa0..df20986fc52 100644
--- a/test/lisp/progmodes/autoconf-tests.el
+++ b/test/lisp/progmodes/autoconf-tests.el
@@ -20,36 +20,44 @@
 ;; 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:
-
-;;
-
 ;;; Code:
 
 (require 'autoconf)
 (require 'ert)
+(require 'ert-font-lock)
 
 (ert-deftest autoconf-tests-current-defun-function-define ()
   (with-temp-buffer
+    (autoconf-mode)
     (insert "AC_DEFINE([HAVE_RSVG], [1], [Define to 1 if using librsvg.])")
+    (let ((def "HAVE_RSVG"))
+      (search-backward def)
+      (should (equal (autoconf-current-defun-function) def)))
     (goto-char (point-min))
-    (should-not (autoconf-current-defun-function))
-    (forward-char 11)
-    (should (equal (autoconf-current-defun-function) "HAVE_RSVG"))))
+    (should-not (autoconf-current-defun-function))))
 
 (ert-deftest autoconf-tests-current-defun-function-subst ()
   (with-temp-buffer
+    (autoconf-mode)
     (insert "AC_SUBST([srcdir])")
+    (let ((def "srcdir"))
+      (search-backward def)
+      (should (equal (autoconf-current-defun-function) "srcdir")))
     (goto-char (point-min))
-    (should-not (autoconf-current-defun-function))
-    (forward-char 10)
-    (should (equal (autoconf-current-defun-function) "srcdir"))))
+    (should-not (autoconf-current-defun-function))))
 
 (ert-deftest autoconf-tests-autoconf-mode-comment-syntax ()
   (with-temp-buffer
     (autoconf-mode)
-    (insert "dnl  Autoconf script for GNU Emacs")
-    (should (nth 4 (syntax-ppss)))))
+    (dolist (start '("dnl" "#"))
+      (insert start "  Autoconf script for GNU Emacs")
+      (should (eq (syntax-ppss-context (syntax-ppss)) 'comment))
+      (insert "\n")
+      (should-not (syntax-ppss-context (syntax-ppss))))))
+
+(ert-font-lock-deftest-file autoconf-tests-font-lock
+  "Test `autoconf-mode' font lock."
+  autoconf-mode "configure.ac")
 
 (provide 'autoconf-tests)
 ;;; autoconf-tests.el ends here
-- 
2.47.2

In GNU Emacs 31.0.50 (build 1, x86_64-pc-linux-gnu, X toolkit, cairo
 version 1.18.2, Xaw3d scroll bars) of 2025-02-16 built on tais
Repository revision: fc189cb83cf7284344a737e75b3ee56487b1c386
Repository branch: master
Windowing system distributor 'The X.Org Foundation', version 11.0.12101015
System Description: Debian GNU/Linux trixie/sid

Configured using:
 'configure 'CFLAGS=-Og -ggdb3' -C --prefix=/home/blc/.local
 --enable-checking=structs --without-native-compilation
 --with-file-notification --with-x-toolkit=lucid --with-x'

Configured features:
ACL CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GPM GSETTINGS HARFBUZZ JPEG
LCMS2 LIBOTF LIBSELINUX LIBSYSTEMD LIBXML2 M17N_FLT MODULES NOTIFY
INOTIFY PDUMPER PNG RSVG SECCOMP SOUND SQLITE3 THREADS TIFF
TOOLKIT_SCROLL_BARS TREE_SITTER WEBP X11 XAW3D XDBE XIM XINERAMA XINPUT2
XPM XRANDR LUCID ZLIB

Important settings:
  value of $LANG: en_IE.UTF-8
  locale-coding-system: utf-8-unix

Major mode: Lisp Interaction

Minor modes in effect:
  tooltip-mode: t
  global-eldoc-mode: t
  eldoc-mode: t
  show-paren-mode: t
  electric-indent-mode: t
  mouse-wheel-mode: t
  tool-bar-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  minibuffer-regexp-mode: t
  line-number-mode: t
  indent-tabs-mode: t
  transient-mark-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t

Load-path shadows:
None found.

Features:
(shadow sort mail-extr emacsbug message mailcap yank-media puny dired
dired-loaddefs rfc822 mml mml-sec password-cache epa derived epg rfc6068
epg-config gnus-util text-property-search time-date subr-x mm-decode
mm-bodies mm-encode mail-parse rfc2231 mailabbrev gmm-utils mailheader
cl-loaddefs cl-lib sendmail rfc2047 rfc2045 ietf-drums mm-util
mail-prsvr mail-utils rmc iso-transl tooltip cconv eldoc paren electric
uniquify ediff-hook vc-hooks lisp-float-type elisp-mode mwheel
term/x-win x-win term/common-win x-dnd touch-screen tool-bar dnd fontset
image regexp-opt fringe tabulated-list replace newcomment text-mode
lisp-mode prog-mode register page tab-bar menu-bar rfn-eshadow isearch
easymenu timer select scroll-bar mouse jit-lock font-lock syntax
font-core term/tty-colors frame minibuffer nadvice seq simple cl-generic
indonesian philippine cham georgian utf-8-lang misc-lang vietnamese
tibetan thai tai-viet lao korean japanese eucjp-ms cp51932 hebrew greek
romanian slovak czech european ethiopic indian cyrillic chinese
composite emoji-zwj charscript charprop case-table epa-hook
jka-cmpr-hook help abbrev obarray oclosure cl-preloaded button loaddefs
theme-loaddefs faces cus-face macroexp files window text-properties
overlay sha1 md5 base64 format env code-pages mule custom widget keymap
hashtable-print-readable backquote threads dbusbind inotify lcms2
dynamic-setting system-font-setting font-render-setting cairo x-toolkit
xinput2 x multi-tty move-toolbar make-network-process tty-child-frames
emacs)

Memory information:
((conses 16 39874 9371) (symbols 48 5391 0) (strings 32 13472 1563)
 (string-bytes 1 318133) (vectors 16 9452)
 (vector-slots 8 113642 8578) (floats 8 23 3) (intervals 56 268 0)
 (buffers 992 10))