Homepage: https://elpa.gnu.org/packages/sm-c-mode.html
Author: Stefan Monnier
Updated:
C major mode based on SMIE
This started as an experiment to see concretely where&how SMIE falls down when trying to handle a language like C, to get an idea of maybe what it would take to change SMIE to better support C-style syntax. So, this does provide "SMIE-based indentation for C" and might even do it OK in practice, but it really doesn't benefit much from SMIE: - it does a lot of its own parsing 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 we can handle C without having to constantly work around SMIE, e.g. 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. This is not designed to supplant Emacs's built-in c-mode, which does a more thorough job. It was not even meant to be used by anyone, really, but I finally decided to release this because some users pointed out that on slow machines it can be a worthy lightweigth alternative. Known limitations: - This mode makes no attempt to try and handle sanely K&R style function definitions (i.e. where the type of arguments is given between the list of arguments and the body). There are 2 good reasons for that: this old syntax sucks and should be laid to rest, and it'd be a lot of extra work to try and handle it. Todo: - This mode mostly limits itself to the C99 syntax, so it would be nice to make it handle the syntactic constructs introduced since then. - 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. 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 .../emacs/; git reset --hard; mv src/macuvs.h src/globals.h ./); files=($(echo .../emacs/src/*.[ch])); (cd .../emacs/; mv macuvs.h globals.h src/); time make -j4 ${^${files}}.reindent EMACS="emacs24 -Q"; (cd .../emacs/; 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 IOW, in this "best case" scenario, `sm-c-mode' indented almost as well as `c-mode' does (as measured by diff|wc), and it did it about 4 times faster. BEWARE: 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.