10

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.]

  • 1
    You can take a look at ruby-mode which does something similar for ruby. Another option is to hook into smartparens, it has a special configuration for ruby mode which you can use as a starting point – Iqbal Ansari Dec 18 '14 at 7:16
9

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.

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))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.