emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: good "modern" example code for a programming-language mode?


From: Stefan Monnier
Subject: Re: good "modern" example code for a programming-language mode?
Date: Wed, 16 Feb 2011 09:56:05 -0500
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.50 (gnu/linux)

> Regarding indentation: this is much more a matter of taste than
> semantics or syntax. If there was a direct connection between semantical
> analysis and indentation, why were all those wars fought for the
> "correct" indentation of C, for instance?

OTOH there is a clear connection between syntax and indentation.
My experience (which lead me to write SMIE) is that all indentation
styles for all languages share a lot of common principles, so that
indentation can be (partly) automatically derived from the language's
grammar.  And indeed, if you give a valid grammar to SMIE, it will give
you a valid indentation function in return.  Of course, the indentation
style it uses will most likely not fully match the user's expectations,
so SMIE provides a hook to tweak the default indentation rules for the
various possible situations.

E.g. for Prolog, the tweaks I've needed until now are limited to:

(defun prolog-smie-rules (kind token)
  (pcase (cons kind token)
    (`(:elem . basic) prolog-indent-width)
    (`(:after . ".") 0) ;; To work around smie-closer-alist.
    (`(:after . ,(or `":-" `"->" `"-->")) prolog-indent-width))

and for /bin/sh it currently looks like:

(defun sh-smie-rules (kind token)
  (pcase (cons kind token)
    (`(:elem . basic) sh-indentation)
    (`(:after . "case-)") (or sh-indentation smie-indent-basic))
    (`(:before . ,(or `"(" `"{" `"["))
     (if (smie-rule-hanging-p) (smie-rule-parent)))
    ;; FIXME: Maybe this handling of ;; should be made into
    ;; a smie-rule-terminator function that takes the substitute ";" as arg.
    (`(:before . ,(or `";;" `";&" `";;&"))
     (if (and (smie-rule-bolp) (looking-at ";;?&?[ \t]*\\(#\\|$\\)"))
         (cons 'column (smie-indent-keyword ";"))
       (smie-rule-separator kind)))
    (`(:after . ,(or `";;" `";&" `";;&"))
     (with-demoted-errors
       (smie-backward-sexp token)
       (cons 'column (current-column))))))

You can check what's used in Modula-2 and Octave by looking for
"smie-rules".

For SML it is a good bit more complex, for some reason (even though SML
was my original inspiration for SMIE).  Maybe it's because the
language's syntax tends to introduce a lot more indentation than is
practical, so people have come up with all kinds of conventions for
cases where indentation can be reduced without losing the property that
indentation reflects internal structure.

> Just looking at c-style-alist will make that clear.

Indeed, for some reason C indentation is a lot more contentious than
most other languages.  I haven't yet tried to use SMIE for C-like
languages, so I'm not sure how well it would accommodate all the
nitty-gritty details of each one's personal favorite indentation style.


        Stefan



reply via email to

[Prev in Thread] Current Thread [Next in Thread]