Emacs regexp for indentation

  • Follow


Hello,

In writing a major mode for Emacs, I am confused by the use of regular
expressions in indent-line-function. The indentation rules are simple:

- if the last non-blank character of the previous line is a semicolon
or an equal sign (; or =), indent the line (of, say, default-tab-
width),
- otherwise, do not indent (i.e., indent to column 0).

The regexp I use seems straightforward: [:=][ \t]*$

(defun my-indent-line ()
  "Simple indentation"
  (interactive)
  (let ((position 0)
        (reason nil))

    (save-excursion
      (beginning-of-line)   ; Set point to beginning of line

      ;; Flush left at beginning of buffer
      (if (bobp)
          (prog1
              (setq position 0)
            (setq reason "top of buffer"))

        (progn
          (forward-line -1) ; move point to beginning of previous
line, if any
          (if (looking-at "[:=][ \t]*$") ; if previous line ends
with : or =
              (prog1
                  (setq position default-tab-width) ; indent
                (setq reason "previous line ends in : or ="))
            (prog1
                (setq position 0)  ; otherwise, do not indent
              (setq reason "nothing special"))))))
    (message "Indentation column will be %d (%s)" position reason)
    (indent-line-to position)))

I tried "occur mode" and isearch-forward-regexp on the buffer I am
trying to indent, and in both cases, the lines that I expect to be
matched are matched. However, when I call my-indent-line, it only
wants to indent to column 0 (I did set indent-line-function to my-
indent-line).

I must be misunderstanding something. What am I doing wrong here?

Thanks,
Dominique
0
Reply Dominique 3/2/2008 10:47:37 PM

On 2008-03-02, Dominique <dominique.orban@gmail.com> wrote:
> Hello,
>
> In writing a major mode for Emacs, I am confused by the use of regular
> expressions in indent-line-function. The indentation rules are simple:
>
> - if the last non-blank character of the previous line is a semicolon
> or an equal sign (; or =), indent the line (of, say, default-tab-
> width),
> - otherwise, do not indent (i.e., indent to column 0).
>
> The regexp I use seems straightforward: [:=][ \t]*$
>
> (defun my-indent-line ()
>   "Simple indentation"
>   (interactive)
>   (let ((position 0)
>         (reason nil))
>
>     (save-excursion
>       (beginning-of-line)   ; Set point to beginning of line
>
>       ;; Flush left at beginning of buffer
>       (if (bobp)
>           (prog1
>               (setq position 0)
>             (setq reason "top of buffer"))
>
>         (progn
>           (forward-line -1) ; move point to beginning of previous
> line, if any
>           (if (looking-at "[:=][ \t]*$") ; if previous line ends
> with : or =
>               (prog1
>                   (setq position default-tab-width) ; indent
>                 (setq reason "previous line ends in : or ="))
>             (prog1
>                 (setq position 0)  ; otherwise, do not indent
>               (setq reason "nothing special"))))))
>     (message "Indentation column will be %d (%s)" position reason)
>     (indent-line-to position)))
>
> I tried "occur mode" and isearch-forward-regexp on the buffer I am
> trying to indent, and in both cases, the lines that I expect to be
> matched are matched. However, when I call my-indent-line, it only
> wants to indent to column 0 (I did set indent-line-function to my-
> indent-line).
>
> I must be misunderstanding something. What am I doing wrong here?
>

I think your "looking-at" is wrong. You are only matching lines that
only contain : or =. Try:

  (if (looking-at ".*[:=][ \t]*$") ; if previous line *ends* with : or =

0
Reply Tyler 3/2/2008 11:21:59 PM


On Mar 2, 6:21 pm, Tyler Smith <tyler.sm...@mail.mcgill.ca> wrote:
> On 2008-03-02, Dominique <dominique.or...@gmail.com> wrote:
>
>
>
> > Hello,
>
> > In writing a major mode for Emacs, I am confused by the use of regular
> > expressions in indent-line-function. The indentation rules are simple:
>
> > - if the last non-blank character of the previous line is a semicolon
> > or an equal sign (; or =), indent the line (of, say, default-tab-
> > width),
> > - otherwise, do not indent (i.e., indent to column 0).
>
> > The regexp I use seems straightforward: [:=][ \t]*$
>
> > (defun my-indent-line ()
> >   "Simple indentation"
> >   (interactive)
> >   (let ((position 0)
> >         (reason nil))
>
> >     (save-excursion
> >       (beginning-of-line)   ; Set point to beginning of line
>
> >       ;; Flush left at beginning of buffer
> >       (if (bobp)
> >           (prog1
> >               (setq position 0)
> >             (setq reason "top of buffer"))
>
> >         (progn
> >           (forward-line -1) ; move point to beginning of previous
> > line, if any
> >           (if (looking-at "[:=][ \t]*$") ; if previous line ends
> > with : or =
> >               (prog1
> >                   (setq position default-tab-width) ; indent
> >                 (setq reason "previous line ends in : or ="))
> >             (prog1
> >                 (setq position 0)  ; otherwise, do not indent
> >               (setq reason "nothing special"))))))
> >     (message "Indentation column will be %d (%s)" position reason)
> >     (indent-line-to position)))
>
> > I tried "occur mode" and isearch-forward-regexp on the buffer I am
> > trying to indent, and in both cases, the lines that I expect to be
> > matched are matched. However, when I call my-indent-line, it only
> > wants to indent to column 0 (I did set indent-line-function to my-
> > indent-line).
>
> > I must be misunderstanding something. What am I doing wrong here?
>
> I think your "looking-at" is wrong. You are only matching lines that
> only contain : or =. Try:
>
>   (if (looking-at ".*[:=][ \t]*$") ; if previous line *ends* with : or =

Tha's it! I guess the way regexps are processed in this context
differs from, e.g, isearch-forwar-regexp...

Thanks !
Dominique
0
Reply Dominique 3/3/2008 12:08:42 AM

On 2008-03-03, Dominique <dominique.orban@gmail.com> wrote:
>> >           (if (looking-at "[:=][ \t]*$") ; if previous line ends
>> > with : or =
>> >               (prog1
>> >                   (setq position default-tab-width) ; indent
>> >                 (setq reason "previous line ends in : or ="))
>> >             (prog1
>> >                 (setq position 0)  ; otherwise, do not indent
>> >               (setq reason "nothing special"))))))
>> >     (message "Indentation column will be %d (%s)" position reason)
>> >     (indent-line-to position)))
>>
>> > I tried "occur mode" and isearch-forward-regexp on the buffer I am
>> > trying to indent, and in both cases, the lines that I expect to be
>> > matched are matched. However, when I call my-indent-line, it only
>> > wants to indent to column 0 (I did set indent-line-function to my-
>> > indent-line).
>>
>> > I must be misunderstanding something. What am I doing wrong here?
>>
>> I think your "looking-at" is wrong. You are only matching lines that
>> only contain : or =. Try:
>>
>>   (if (looking-at ".*[:=][ \t]*$") ; if previous line *ends* with : or =
>
> Tha's it! I guess the way regexps are processed in this context
> differs from, e.g, isearch-forwar-regexp...
>

Glad that helps. The difference is that isearch-forward-regexp
searches ahead to the next match. looking-at is anchored at point, so
the matching text has to be there - it won't search forward.

Tyler
0
Reply Tyler 3/3/2008 2:33:04 AM

3 Replies
128 Views

(page loaded in 0.319 seconds)

Similiar Articles:





7/16/2012 10:44:10 PM


Reply: