[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/sm-c-mode 5646e71 05/12: * sm-c-mode.el: Improve "Comme
From: |
Stefan Monnier |
Subject: |
[elpa] externals/sm-c-mode 5646e71 05/12: * sm-c-mode.el: Improve "Commentary:" and docstrings |
Date: |
Sat, 28 Nov 2020 18:11:07 -0500 (EST) |
branch: externals/sm-c-mode
commit 5646e714cfd5a69d8bc76055cbaaf92e31971d01
Author: Stefan Monnier <monnier@iro.umontreal.ca>
Commit: Stefan Monnier <monnier@iro.umontreal.ca>
* sm-c-mode.el: Improve "Commentary:" and docstrings
* sm-c-mode.el: Improve "Commentary:" and docstrings.
(sm-c-smie--*-token): Fix inf-loop at BOB.
* GNUmakefile (%.reindent): New rule.
(HIJACK): New var.
(%.test): Use $<.
---
GNUmakefile | 9 ++++++++-
sm-c-mode.el | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++--------
2 files changed, 60 insertions(+), 9 deletions(-)
diff --git a/GNUmakefile b/GNUmakefile
index 2c6da32..c9d648a 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -1,6 +1,7 @@
EMACS=emacs
DIFF=diff
+HIJACK=--eval "(defalias 'c-mode 'sm-c-mode)"
test: sm-c-mode-test.c.test
@@ -12,10 +13,16 @@ refresh:
%.test: % sm-c-mode.elc refresh
$(EMACS) --batch -l sm-c-mode-autoloads.el \
- sm-c-mode-test.c \
+ $< \
--eval '(setq indent-tabs-mode nil)' \
--eval '(setq create-lockfiles nil)' \
--eval '(indent-region (point-min) (point-max) nil)' \
--eval '(indent-region (point-min) (point-max) nil)' \
--eval '(write-region (point-min) (point-max) "$@")'
$(DIFF) $< $@ || true; $(RM) $@
+
+%.reindent: % sm-c-mode.elc refresh
+ $(EMACS) --batch -l sm-c-mode-autoloads.el $(HIJACK) \
+ $< \
+ --eval '(indent-region (point-min) (point-max) nil)' \
+ --eval '(save-buffer)'
diff --git a/sm-c-mode.el b/sm-c-mode.el
index 1ac263e..72cd75e 100644
--- a/sm-c-mode.el
+++ b/sm-c-mode.el
@@ -29,15 +29,53 @@
;; might even do it OK for simple cases, but it really doesn't benefit much
;; from SMIE:
;; - it does a lot of its own parsing by hand.
-;; - its smie-ruled-function also does a lot of indentation by hand.
+;; - its smie-rules-function also does a lot of indentation by hand.
;; Hopefully at some point, someone will find a way to extend SMIE such that
;; it can handle C without having to constantly work around SMIE, e.g.
-;; it'd be nice to hook the sm-c--while-to-do, sm-c--else-to-if, and sm-c--boi
-;; functions into SMIE at some level.
+;; it'd be nice to hook sm-c--while-to-do, sm-c--else-to-if, sm-c--boi,
+;; sm-c--boe, ... into SMIE at some level.
;; Note that this mode makes no attempt to try and handle sanely K&R style
;; function definitions.
+;;;; Benchmarks
+
+;; This code can't be compared to CC-mode since its scope is much more limited
+;; (only tries to handle the kind of code found in Emacs's source code, for
+;; example; does not intend to be extensible to handle C++ or ObjC; does not
+;; offer the same kind of customizability of indentation style, ...).
+;; But in order to make sure it's doing a good enough job on the code for which
+;; it was tuned, I did run some quick benchmarks against CC-mode:
+;;
+;; Benchmarks: reindent emacs/src/*.[ch] (skipping macuvs.h and globals.h
+;; because CC-mode gets pathologically slow on them).
+;; (cd src/emacs/work/; git reset --hard; mv src/macuvs.h src/globals.h ./);
+;; files=($(echo ~/src/emacs/work/src/*.[ch]));
+;; (cd src/emacs/work/; mv macuvs.h globals.h src/);
+;; time make -j4 ${^${files}}.reindent EMACS="emacs24 -Q";
+;; (cd src/emacs/work/; git diff|wc)
+;; - Default settings:
+;; diff|wc => 86800 379362 2879534
+;; make -j4 191.57s user 1.77s system 334% cpu 57.78 total
+;; - With (setq sm-c-indent-cpp-basic 0)
+;; diff|wc => 59909 275415 2034045
+;; make -j4 177.88s user 1.70s system 340% cpu 52.80 total
+;; - For reference, CC-mode gets:
+;; diff|wc => 79164 490894 3428542
+;; make -j4 804.83s user 2.79s system 277% cpu 4:51.08 total
+;;
+;; Again: take this with a large grain of salt, since this is testing sm-c-mode
+;; in the most favorable light (IOW it's a very strongly biased benchmark).
+;; All this says, is that sm-c-mode's indentation might actually be usable if
+;; you use it on C code that is sufficiently similar to Emacs's.
+
+;;;; FIXME:
+
+;; - We "use but don't use" SMIE.
+;; - CPP directives are treated as comments. To some extent this is OK, but in
+;; many other cases it isn't. See for instance the comment-only-p advice.
+;; - M-q in a comment doesn't do the right thing.
+
;;; Code:
(require 'cl-lib)
@@ -53,7 +91,10 @@ Typically 2 for GNU style and `tab-width' for Linux style."
:type 'integer)
(defcustom sm-c-indent-braces t
- "If non-nil, braces in if/while/... are indented."
+ "If nil, braces in if/while/... are aligned with the if/while/...
+Else, they're indented by `sm-c-indent-basic' columns.
+For braces placed at the end of lines (which SMIE calls \"hanging\"), it makes
+no difference."
:type 'boolean)
;;; Handling CPP directives.
@@ -115,7 +156,9 @@ Typically 2 for GNU style and `tab-width' for Linux style."
;;;; Indenting CPP directives.
(defcustom sm-c-indent-cpp-basic 1
- "Indent step for CPP directives."
+ "Indent step for CPP directives.
+If non-zero, CPP directives are indented according to CPP depth.
+E.g. a #define nested within 2 #ifs will be turned into \"# define\"."
:type 'integer)
(defun sm-c--cpp-prev (tok)
@@ -503,7 +546,7 @@ if INNER is non-nil, it stops at the innermost one."
(`nil
(goto-char pos)
(let ((res nil))
- (while (not res)
+ (while (not (or res (bobp)))
(pcase (smie-backward-sexp)
(`(,_ ,_ ,(or ";" "{")) (setq res "* deref"))
((and `nil (guard (looking-at "{"))) (setq res "* deref"))
@@ -514,7 +557,7 @@ if INNER is non-nil, it stops at the innermost one."
(nth 1 (assoc "* mult" smie-grammar))))
(smie-backward-sexp 'halfsexp)
(setq res "* mult")))))
- res))
+ (or res "* mult")))
(_ "* mult")))))
(defun sm-c-smie-hanging-eolp ()
@@ -839,7 +882,8 @@ if INNER is non-nil, it stops at the innermost one."
(let ((parse-sexp-lookup-properties nil))
(apply args))))
-;; FIXME: Clearly, we should change newcomment.el instead.
+;; FIXME: Maybe we should change newcomment.el instead; or maybe CPP directives
+;; should not be defined as comments, or at least "not always"!
(advice-add 'comment-only-p :around #'sm-c--cpp-is-not-really-a-comment)
(provide 'sm-c-mode)
- [elpa] branch externals/sm-c-mode created (now a207ad8), Stefan Monnier, 2020/11/28
- [elpa] externals/sm-c-mode 1f2c7ec 04/12: * sm-c-mode: Improve indentation of struct; plus bug fixes, Stefan Monnier, 2020/11/28
- [elpa] externals/sm-c-mode 9d2cff5 06/12: * packages/sm-c-mode: Add imenu/which-func/add-log support, Stefan Monnier, 2020/11/28
- [elpa] externals/sm-c-mode 97dea83 02/12: * sm-c-mode.el (sm-c-font-lock-keywords): Match function defs., Stefan Monnier, 2020/11/28
- [elpa] externals/sm-c-mode 4c63cb1 03/12: * sm-c-mode.el: Auto-align backslashes. Improve indent rules, Stefan Monnier, 2020/11/28
- [elpa] externals/sm-c-mode 5e67afc 07/12: * sm-c-mode/sm-c-mode.el (sm-c-smie-rules): Improve indent of enum's {...}, Stefan Monnier, 2020/11/28
- [elpa] externals/sm-c-mode 3ef465d 11/12: * packages/sm-c-mode/sm-c-mode.el: Improve \ alignment with long lines, Stefan Monnier, 2020/11/28
- [elpa] externals/sm-c-mode a207ad8 12/12: * .gitignore: New file, Stefan Monnier, 2020/11/28
- [elpa] externals/sm-c-mode a3efebd 09/12: * sm-c-mode.el: Fix some problems reported by Andrés Ramírez, Stefan Monnier, 2020/11/28
- [elpa] externals/sm-c-mode 5646e71 05/12: * sm-c-mode.el: Improve "Commentary:" and docstrings,
Stefan Monnier <=
- [elpa] externals/sm-c-mode 3c3b1f7 08/12: * sm-c-mode.el (sm-c--comment-regexp): Fix excessive backtracking, Stefan Monnier, 2020/11/28
- [elpa] externals/sm-c-mode 3b5d1e0 01/12: * sm-c-mode: New experimental package, Stefan Monnier, 2020/11/28
- [elpa] externals/sm-c-mode 0fde734 10/12: * packages/sm-c-mode/sm-c-mode.el: Release as version 1.0, Stefan Monnier, 2020/11/28