From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Stefan Monnier Newsgroups: gmane.emacs.devel Subject: Re: SMIE help Date: Fri, 29 Nov 2013 16:28:28 -0500 Message-ID: References: <4EF77C65-4918-4FBA-A952-C8A4B7F538D8@gmail.com> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: ger.gmane.org 1385760524 32760 80.91.229.3 (29 Nov 2013 21:28:44 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Fri, 29 Nov 2013 21:28:44 +0000 (UTC) Cc: "emacs-devel@gnu.org List" To: Ivan Andrus Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Fri Nov 29 22:28:49 2013 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1VmVcE-0006k3-S4 for ged-emacs-devel@m.gmane.org; Fri, 29 Nov 2013 22:28:46 +0100 Original-Received: from localhost ([::1]:49529 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VmVcE-0005Y6-BG for ged-emacs-devel@m.gmane.org; Fri, 29 Nov 2013 16:28:46 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:50695) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VmVc5-0005Xv-1k for emacs-devel@gnu.org; Fri, 29 Nov 2013 16:28:44 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VmVbx-0001nw-ON for emacs-devel@gnu.org; Fri, 29 Nov 2013 16:28:36 -0500 Original-Received: from ironport2-out.teksavvy.com ([206.248.154.181]:57455) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VmVbx-0001mD-EY for emacs-devel@gnu.org; Fri, 29 Nov 2013 16:28:29 -0500 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Av4EABK/CFHO+KEh/2dsb2JhbABEvw4Xc4IeAQEEAVYjBQsLDiYSFBgNJIgeBsEtjRmDcQOIYZwZgV6DFYFI X-IPAS-Result: Av4EABK/CFHO+KEh/2dsb2JhbABEvw4Xc4IeAQEEAVYjBQsLDiYSFBgNJIgeBsEtjRmDcQOIYZwZgV6DFYFI X-IronPort-AV: E=Sophos;i="4.84,565,1355115600"; d="scan'208";a="40720365" Original-Received: from 206-248-161-33.dsl.teksavvy.com (HELO pastel.home) ([206.248.161.33]) by ironport2-out.teksavvy.com with ESMTP/TLS/ADH-AES256-SHA; 29 Nov 2013 16:28:28 -0500 Original-Received: by pastel.home (Postfix, from userid 20848) id 3F3AE60EFA; Fri, 29 Nov 2013 16:28:28 -0500 (EST) In-Reply-To: <4EF77C65-4918-4FBA-A952-C8A4B7F538D8@gmail.com> (Ivan Andrus's message of "Thu, 28 Nov 2013 00:00:44 -0700") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3.50 (gnu/linux) X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 206.248.154.181 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:165900 Archived-At: > 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