all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Stefan Monnier <monnier@iro.umontreal.ca>
To: Ivan Andrus <darthandrus@gmail.com>
Cc: "emacs-devel@gnu.org List" <emacs-devel@gnu.org>
Subject: Re: SMIE help
Date: Fri, 29 Nov 2013 16:28:28 -0500	[thread overview]
Message-ID: <jwvd2liapqx.fsf-monnier+emacs@gnu.org> (raw)
In-Reply-To: <4EF77C65-4918-4FBA-A952-C8A4B7F538D8@gmail.com> (Ivan Andrus's message of "Thu, 28 Nov 2013 00:00:44 -0700")

> What I have works in many ways (though it could no doubt be
> simplified).  My indentation is wildly off however in at least one
> case, and I have no idea how to fix it.  The case of interest is the
> first line inside of a function (in the example the line starting with
> local).  Interestingly other lines in a function are fine.

> # example of well indented GAP code
> FittingHeight := function (G)
>     local  fittingLength, F;
> 
>     fittingLength := 0;

Here's the problem: with the grammar you have, the above is parsed as
something like the following structure:

  (:= FittingHeight
      (function
       ((G) (local (, fittingLength F)))
       (:= fittingLength 0)))

So the "local ..." is aligned with "(G)".

You can see that it's a parsing problem by hitting C-M-b from right
after the first semi-colon of your example: it should jump to just
before "local" but instead it jumps to just before "(G)", as if "(G)"
was part of the first instruction.

SMIE is not very good with "positional rules", as is the case here where
there is no clear keyword between "(G)" and the function's body.
By "positional" I mean that "the *first* sexp-like thingy after
`function' is special".

You can solve this problem at 2 levels:
- the grammar level: you can't really fix it in gap-smie-grammar itself
  because SMIE's class of grammars is too limited to understand this,
  but you can change the lexer such that it treats the close-paren after
  "(G" specially and returns another token.
- the indent-rules level: you give up parsing the code correctly and
  instead patch things up in gap-smie-rules by adding a rule for
  (:after . ")") which checks if this is the closing parent of
  a "function (...)".

Doing it in indent-rules will lead to more efficient code, usually, but
may also force you to add more and more special cases (tho in this
particular case, it might work OK).
In this particular case, you might like to try and patch things up in
gap-smie-rules, along the lines of:

    (`(:after . ")")
     (save-excursion
       (up-list -1)
       (when (equal "function" (car (smie-indent-backward-token)))
	 `(column . ,(+ gap-indent-step (smie-indent-virtual))))))
    
After that, you'll also want to change the smie-rules for (:before
. "function"), probably, so as to treat "function (..)\n" as "hanging":

    (`(:before . "function")
     (when (save-excursion
	     (forward-word 1)
	     (forward-sexp 1)
	     (smie-rule-hanging-p))
       (smie-rule-parent)))
    
so that the body of "function" is not indented relative to "function"
but relative to "FittingHeight :=".


        Stefan



  reply	other threads:[~2013-11-29 21:28 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-11-28  7:00 SMIE help Ivan Andrus
2013-11-29 21:28 ` Stefan Monnier [this message]
2013-11-30  5:05   ` Ivan Andrus
2013-12-03  6:11     ` Ivan Andrus
2013-12-03 13:47       ` Stefan Monnier
2013-12-03 16:14         ` Ivan Andrus

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=jwvd2liapqx.fsf-monnier+emacs@gnu.org \
    --to=monnier@iro.umontreal.ca \
    --cc=darthandrus@gmail.com \
    --cc=emacs-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.