unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Stefan Monnier <monnier@iro.umontreal.ca>
To: Dmitry Gutov <dgutov@yandex.ru>
Cc: "Wedler, Christoph" <christoph.wedler@sap.com>,
	"Fabián E.Gallina" <fabian@anue.biz>,
	"emacs-devel@gnu.org" <emacs-devel@gnu.org>
Subject: Re: antlr-mode.el - need some support by python.el
Date: Wed, 18 Feb 2015 12:56:11 -0500	[thread overview]
Message-ID: <jwvk2zfun4c.fsf-monnier+emacs@gnu.org> (raw)
In-Reply-To: <54E4AC06.60300@yandex.ru> (Dmitry Gutov's message of "Wed, 18 Feb 2015 17:13:10 +0200")

>> Narrowing sucks, so no it's not a viable alternative.
> Do you suppose the submodes will implement prog-indentation-context support
> using something other than narrowing? It's a powerful approach.

They can choose to do so if it doesn't break some of the things they do,
of course, but forcing it upon them will lead to trouble.

> I think I'd rather change the indent-line-function API, to return the column
> offset.  Or add a new one, like `line-indentation-function'.

Agreed, but someone's got to do it.  FWIW I've appended code I've had in
my prog-mode.el for many years (e.g. long before add-function came
along ;-).

BTW, I consider any mode which needs auto-indentation to be
a "programming mode".  That includes LaTeX, XML, ... (which are also
text-modes, but I don't think the two are mutually exclusive).

>> Furthermore, I can imagine some cases where the inner mode may still
>> want to indent to a column smaller than LEFTMOST-COL for good reasons.
> I wonder what that is.

E.g. in latex-mode, a "\begin{verbatim}" has to go to column 0, no
matter what the context.

> But anyway, line-indentation-function would
> return a negative value in that case.

How would it know it has to do that (and how negative should it be) if
it's not told about LEFTMOST-COL?


        Stefan


;; Generic indentation support ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defun prog-indent-line (&optional arg)
  "Reindent current line.
If ARG is non-nil, indent any additional lines of the same expression rigidly
along with this one."
  (interactive)
  (if arg
      ;; We could use it to reindent the sexp at point:
      ;; (indent-region (point)
      ;;                (progn (forward-sexp 1) (point)))
      ;; But Lisp-mode by default does "indent any additional lines of the
      ;; same expression rigidly along with this one.", so let's
      ;; reproduce that.
      (let ((old-indent (current-indentation)))
        (if (eq (indent-according-to-mode) 'noindent)
            (funcall (default-value 'indent-line-function)))
        (let ((new-indent (current-indentation))
              (beg (line-beginning-position 2))
              (end (save-excursion (beginning-of-line)
                                   (forward-sexp 1)
                                   (point))))
          (when (and (> end beg) (/= new-indent old-indent))
            (indent-code-rigidly beg end (- new-indent old-indent)))))
    ;; Normal case.
    (let* ((savep (point))
           (indent (condition-case nil
                       (save-excursion
                         (forward-line 0)
                         (skip-chars-forward " \t")
                         (if (>= (point) savep) (setq savep nil))
                         (or (prog-indent-calculate) 0))
                     (error 0))))
      (if (not (numberp indent))
          ;; If something funny is used (e.g. `noindent'), return it.
          indent
        (if (< indent 0) (setq indent 0)) ;Just in case.
        (if savep
            (save-excursion (indent-line-to indent))
          (indent-line-to indent))))))

(defvar prog-indent-calculate-functions
  '(prog-indent-calculate-in-string
    prog-indent-calculate-fixindent
    prog-indent-calculate-comment
    prog-indent-calculate-close-sexp)
  "Functions to indent the current line.
Each function is called in turn with no argument until one of them returns
  a non-nil value, which is then used as the column number to which point
  should be indented.
Each function is responsible for restoring point to its correct location
  for the next function to work properly.
Functions should expect to be sometimes called with point in
  the middle of a line, in which case they should pretend that the
  preceding text is on another line.")

(defun prog-indent-calculate ()
  "Compute the column at which point should be indented.
Point may be in the middle of a line, in which case this returns the column
at which point should be indented if it were at the beginning of a line.
May return `noindent' to indicate that point's indentation should not be
touched, typically because it is inside a string."
  (run-hook-with-args-until-success 'prog-indent-calculate-functions))

(defun prog-indent-calculate-fixindent ()
  "Don't indent the line if the magic string is there.
The magic string is \"fixindent\" alone inside a comment or at the end
of the line (preceded by a TAB) if no comment style is defined."
  (when (looking-at (concat ".*" (regexp-quote (or comment-start "\t"))
			    "[ \t]*fixindent[ \t]*"
			    (regexp-quote (or comment-end "\n"))))
    (current-indentation)))

(defun prog-indent-calculate-comment ()
  "Indentation of a comment.
The indentation used is the same as would be used for the line following
the comment, unless `comment-indent-function' says otherwise."
  ;; FIXME: This should be moved to newcomment.el.
  (let ((pos (point)))
    (when (and (not (looking-at "\\s-\\|\n")) (forward-comment 1))
      (or (save-excursion
            (goto-char pos)
            (funcall comment-indent-function))
          (save-excursion
            (skip-chars-forward " \t")
            (prog-indent-calculate))))))

(defun prog-indent-calculate-in-string ()
  "Indentation inside a string.  Don't touch it."
  (if (nth 3 (syntax-ppss)) 'noindent))

(defun prog-bolp ()
  (save-excursion (skip-chars-backward " \t") (bolp)))

(defun prog-indent-hanging-p ()
  "Non-nil if token at point is hanging.
A hanging token is a token that starts an sexp (e.g. an open parenthesis),
is not at the beginning of a line, and is at the end of a line."
  (and (not (prog-bolp))
       (looking-at "\\s(+[ \t]*$")))

(defun prog-indent-current ()
  "Current indentation at point.
Return the indentation currently used at point."
  (if (prog-indent-hanging-p)
      (prog-indent-calculate)
    (current-column)))

(defun prog-indent-calculate-close-sexp ()
  "Indentation of the closing token of an sexp."
  (and (looking-at "\\s)+")
       (save-excursion
         (goto-char (match-end 0))
         (forward-sexp -1)
         ;; Align with the matching opening token.
         (prog-indent-current))))




  parent reply	other threads:[~2015-02-18 17:56 UTC|newest]

Thread overview: 79+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-01-16 19:50 antlr-mode.el - need some support by python.el Wedler, Christoph
2015-01-16 23:37 ` Stefan Monnier
2015-02-05 11:39   ` Wedler, Christoph
2015-02-05 14:27     ` Stefan Monnier
2015-02-06 15:14       ` Wedler, Christoph
2015-02-06 17:47         ` Stefan Monnier
2015-02-13 10:56           ` Wedler, Christoph
2015-02-13 19:40             ` Stefan Monnier
2015-02-16 14:38               ` Wedler, Christoph
2015-02-16 19:23                 ` Stefan Monnier
2015-02-17 10:55                   ` Wedler, Christoph
2015-02-18  0:00                     ` Stefan Monnier
2015-02-18 14:27                       ` Wedler, Christoph
2015-02-18  3:39                 ` Dmitry Gutov
2015-02-18  5:48                   ` Stefan Monnier
2015-02-18 14:13                     ` Wedler, Christoph
2015-02-18 15:13                     ` Dmitry Gutov
2015-02-18 15:41                       ` Wedler, Christoph
2015-02-18 17:56                       ` Stefan Monnier [this message]
2015-02-19  2:43                         ` Dmitry Gutov
2015-02-19  3:20                           ` Stefan Monnier
2015-02-19  3:30                             ` Dmitry Gutov
2015-02-19 13:18                               ` Stefan Monnier
2015-02-21 22:14                                 ` Dmitry Gutov
2015-02-25 11:05                                   ` Wedler, Christoph
2015-03-01 17:04                                   ` Stefan Monnier
2015-03-01 22:16                                     ` Dmitry Gutov
2015-03-02  5:23                                       ` Stefan Monnier
2015-03-02 15:08                                         ` Dmitry Gutov
2015-03-02 16:48                                           ` Stefan Monnier
2015-03-02 18:04                                             ` Dmitry Gutov
2015-03-02 18:51                                               ` Stefan Monnier
2015-03-02 19:31                                                 ` Dmitry Gutov
2015-03-03 16:32                                                   ` Stefan Monnier
2015-03-04 16:53                                                     ` Wedler, Christoph
2015-03-04 17:20                                                       ` Dmitry Gutov
2015-03-05  9:46                                                         ` Wedler, Christoph
2015-03-05 12:29                                                           ` Dmitry Gutov
2015-03-05 12:43                                                             ` Dmitry Gutov
2015-04-02 14:10                                                         ` Wedler, Christoph
2015-04-07 17:49                                                           ` Stefan Monnier
2015-04-09 14:07                                                             ` Wedler, Christoph
2015-04-09 18:13                                                               ` Stefan Monnier
2015-06-03 14:14                                                                 ` Wedler, Christoph
2015-06-03 15:31                                                                   ` Stefan Monnier
2015-06-05 14:17                                                                     ` Wedler, Christoph
2015-06-05 17:46                                                                       ` Dmitry Gutov
2015-06-08  9:12                                                                         ` Wedler, Christoph
2015-06-08 13:26                                                                           ` Stefan Monnier
2015-06-08 16:02                                                                             ` Dmitry Gutov
2015-06-08 20:50                                                                               ` Stefan Monnier
2015-06-08 21:33                                                                                 ` Dmitry Gutov
2015-06-09  9:07                                                                                   ` Wedler, Christoph
2015-06-09 15:58                                                                                     ` Stefan Monnier
2015-06-09 19:05                                                                                       ` Wedler, Christoph
2015-06-15 11:02                                                                           ` Dmitry Gutov
2015-06-08 13:18                                                                       ` Stefan Monnier
2015-03-04 17:37                                                     ` Dmitry Gutov
2015-03-04 22:26                                                       ` Stefan Monnier
2015-03-04 22:59                                                         ` Dmitry Gutov
2015-03-10  1:16                                                           ` Stefan Monnier
2015-03-21 15:30                                                             ` Dmitry Gutov
2015-03-21 17:08                                                               ` Stefan Monnier
2015-03-21 23:41                                                                 ` Dmitry Gutov
2015-03-22 13:54                                                                   ` Stefan Monnier
2015-03-22 19:31                                                                     ` Dmitry Gutov
2015-03-22 21:59                                                                       ` Stefan Monnier
2015-03-23 14:03                                                                         ` Dmitry Gutov
2015-03-23 19:25                                                                           ` Stefan Monnier
2015-03-04 16:29                                                   ` Wedler, Christoph
2015-03-04 17:16                                                     ` Dmitry Gutov
2015-03-01 22:25                                     ` Dmitry Gutov
2015-02-18 12:22                   ` Wedler, Christoph
2015-02-18 15:29                     ` Dmitry Gutov
2015-02-18 16:10                       ` Wedler, Christoph
2015-02-18 22:55                         ` Dmitry Gutov
2015-02-25 11:16                           ` Wedler, Christoph
2015-02-18  3:15               ` Dmitry Gutov
2015-02-22  7:52 ` Andreas Röhler

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

  List information: https://www.gnu.org/software/emacs/

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

  git send-email \
    --in-reply-to=jwvk2zfun4c.fsf-monnier+emacs@gnu.org \
    --to=monnier@iro.umontreal.ca \
    --cc=christoph.wedler@sap.com \
    --cc=dgutov@yandex.ru \
    --cc=emacs-devel@gnu.org \
    --cc=fabian@anue.biz \
    /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 public inbox

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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).