9

In a language (julia) that has blocks defined by keywords such as for..end, begin..end, as well as parentheses, what is a good way to skip over such a block? Also, end is not only a block keyword, but also a valid identifier used in other places.

One way is to look for block-starting/closing regex, and to skip over all strings, comments, and ends, etc., but this is somewhat inefficient, and a little ugly.

Is there a way to make emacs's own syntax parsing recognize such block keywords, so that forward/backward-sexp would automatically work, and so that one could quickly tell the beginning of the current block from the output of, e.g., syntax-ppss?

[Note: I don't mind parsing the file myself, but in that case I would still like to know how my parser should be plugged into the rest of emacs.]

Kirill
  • 1,019
  • 7
  • 19
  • 1
    You can take a look at `ruby-mode` which does something similar for ruby. Another option is to hook into [smartparens](https://github.com/Fuco1/smartparens), it has a special configuration for [ruby](https://github.com/Fuco1/smartparens/blob/master/smartparens-ruby.el) mode which you can use as a starting point – Iqbal Ansari Dec 18 '14 at 07:16

2 Answers2

8

You can have a look at the built-in library SMIE (stands for Simple-Minded Indentation Engine). Despite the name, indentation is only one of the features it provides. This is the method used by many modes (including ruby-mode, mentioned in a comment), to provide sexp movement and indentation.

Deploying SMIE for a language is roughly a two-steps job:

  • define the grammar for your language, together with a lexer identifying tokens;
  • define indentation rules.

For your purpose, only the first step will be needed!

Overall, the parser defined this way plugs nicely into emacs. For example, show-parens will highlight paren-like expressions defined in the SMIE grammar (at least in recent enough versions of emacs).

Note that you will still not be able to use syntax-ppss to get information about the enclosing environment, because it will only give you the result of the syntax-table parser. But sexp movement functions (for example up-list followed by backward-sexp) can be a replacement.

T. Verron
  • 4,233
  • 1
  • 22
  • 55
2

I made a library for this

Once defined, a bunch of commands are available, moving forward, backward, copy etc.

Defining --in pseudo-code--:

(put 'MY-FORM 'beginning-op-at
           (lambda () MY-FORWARD-MOVE-CODE))

(put 'MY-FORM 'end-op-at
     (lambda () MY-BACKWARD-MOVE-CODE))

When done, it's should be available, i.e. copied and returned like this

(defun MY-FORM-atpt (&optional arg)
  " "
  (interactive "p")
  (ar-th 'MY-FORM arg))
T. Verron
  • 4,233
  • 1
  • 22
  • 55
Andreas Röhler
  • 1,894
  • 10
  • 10