2

In AUXtex there is the key binding macro C-c ] which closes the lowest current TeX environment. For example

\begin{equation} 
...  

would be closed (by putting an \end{equation} on a new line after where the cursor is located) when using this macro.

I'm now trying to cobble together a major mode for editing the input files to the EPOCH plasma physics PIC code. (Unfortunately the code is only accessible to members of the group, but there is an older version of the instruction manual available.) The types of files I want to build my plug-in for are like the example inputs in section 5 of the instruction manual.

My question is should I go about to get a similar functionality as the AUCtex macro in this major mode that I'm writing. More specifically, the EPOCH input files consist of several blocks of the form

begin:xyz
...
end:xyz

which I would like to be able to close through some cunning command or key binding in my mode definition.

  • We cannot answer that question if we don't know anything about the language you want to write a major mode for. 1. Maybe there is a very close mode that can be adapted to your purpose. 2. There are languages which are parsed with regular expressions such as TeX and then there are languages that are primarily parsed by a parser. – Tobias Oct 23 '18 at 15:27
  • The "language" is for the input file to the plasma physics EPOCH PIC code, which I've now linked in the question, but the code can only be accessed by members. – Andréas Sundström Oct 23 '18 at 16:48
  • A google search returns the epoch_user.pdf. Could you check whether that is an appropriate link? One finds begin:blockname and end:blockname there too. – Tobias Oct 23 '18 at 16:52
  • Looks near Ruby. Suggest a feature-request at github.com/emacs-berlin/syntactic-close – Andreas Röhler Oct 23 '18 at 16:54
  • @Tobias Yes the link is appropriate, and the examples in section 5 should be enough for what I'm considering at the moment. – Andréas Sundström Oct 24 '18 at 7:09
0

With help from @Tobias, I at first managed to cobble together a simple solution:

;;;;;;;;;;;;;;;;;;;; Block closure ;;;;;;;;;;;;;;;;;;;;
(defun epoch-close-block ()
  "Closes code blocks in EPOCH"
  (interactive)
  (beginning-of-line)
  (let
      (block-indent
       block-type
       (block-begin-regexp "^\\([[:blank:]]*\\)begin:\\([a-z][a-z0-9_]+\\)"))

  (save-excursion
    ;;; https://www.gnu.org/software/emacs/manual/html_node/elisp/Simple-Match-Data.html
    (re-search-backward block-begin-regexp)
    ;;Match a the line one more time to save the matched group.
    (string-match block-begin-regexp (thing-at-point 'line t))
    ;;The two matched groups are then saved to variables
    (setq block-indent (match-string 1 (thing-at-point 'line t))) ;indentation level of the begin
    (setq block-type (match-string 2 (thing-at-point 'line t)))   ;the block type
    )
  ;;inserts the actual end:... on a new line
  (insert (concat "\n" block-indent "end:" block-type))
  )

The way this piece of code works is that it

  1. Searches backward with the regex define in block-begin-regexp.
  2. Then the two (non-shy) regex groups are used to save the matches. The first group, \\([[:blank:]]*\\), saves the indentation level of the begin: statement and the second regex group, \\([a-z][a-z0-9_]+\\), saves the block type.
  3. Lastly, the end:... is inserted on a new line, with the same indentation and block type as the begin:....

This is a rather crude, but general solution. This piece of code does not take into account other language specific details, such as e.g. comments and line continuation characters. There is also no handling of nestled begin/end blocks or blocks which are already closed.

For a more elaborate solution, with lots of language specific details for the EPOCH input deck, see the project on GitHub.

  • I believe that the simpleness and somewhat general nature of this solution makes it more suitable to this site than the much more language specific and elaborate solution under the GitHub link. – Andréas Sundström Oct 29 '18 at 9:21

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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