Add custom GPRBuild mode
This commit is contained in:
parent
21754206dd
commit
645afc563f
121
config.org
121
config.org
@ -1009,6 +1009,127 @@
|
||||
(ada-indent-region . ada-indent)))
|
||||
#+end_src
|
||||
|
||||
*** GPRBuild files
|
||||
GPRBuild files are pretty straightforward, but there doesn't seem
|
||||
to be a major mode on ELPA for them so going to make a basic one.
|
||||
|
||||
**** Custom major mode
|
||||
Start out by defining a list of keywords:
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defvar gpr-keywords
|
||||
'("case" "end" "external" "for" "is" "null"
|
||||
"package" "project" "use" "when" "with"))
|
||||
#+end_src
|
||||
|
||||
And a list of builtins:
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defvar gpr-builtins
|
||||
'("Compiler" "Default_Switches" "Exec_Dir" "Library_Dir"
|
||||
"Library_Kind" "Library_Name" "Local_Configuration_Pragmas"
|
||||
"Main" "Object_Dir" "Source_Dirs"))
|
||||
#+end_src
|
||||
|
||||
Define some font lock regexes:
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defvar gpr-font-lock-defaults
|
||||
(let ((string-regex (rx (sequence "\"" (*? (not "\"")) "\"")))
|
||||
(constant-regex (rx (or (+ digit) "True" "False"))))
|
||||
`((,string-regex . font-lock-string-face)
|
||||
(,constant-regex . font-lock-constant-face)
|
||||
(,(regexp-opt gpr-builtins 'words) . font-lock-builtin-face)
|
||||
(,(regexp-opt gpr-keywords 'words) . font-lock-keyword-face))))
|
||||
#+end_src
|
||||
|
||||
Create a variable for the indent width:
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defvar gpr-indent-width 4)
|
||||
#+end_src
|
||||
|
||||
We then need to define a function for indentation, which is
|
||||
non-trivial. A simple set of rules that gets us most of the way is:
|
||||
|
||||
1. Start at indentation level 0
|
||||
2. Decrease indentation level if the line starts with "end"
|
||||
3. Indent to same level as a previous "end" line
|
||||
4. Increase indentation level if the previous line ends with "is"
|
||||
5. Otherwise indent to level 0
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defconst gpr-block-start-regex
|
||||
(rx (sequence line-start
|
||||
(zero-or-more not-newline)
|
||||
"is"
|
||||
(zero-or-more blank)
|
||||
line-end)))
|
||||
|
||||
(defconst gpr-block-end-regex
|
||||
(rx (sequence line-start
|
||||
(zero-or-more blank)
|
||||
"end")))
|
||||
|
||||
(defun gpr-indent-line ()
|
||||
"Indent the current line as GPRBuild code"
|
||||
(interactive)
|
||||
(beginning-of-line)
|
||||
(indent-line-to (gpr-get-indent-level)))
|
||||
|
||||
(defun gpr-get-indent-level ()
|
||||
(cond ((bobp) 0)
|
||||
((looking-at-p gpr-block-end-regex)
|
||||
(save-excursion
|
||||
(forward-line -1)
|
||||
(max (- (current-indentation) gpr-indent-width) 0)))
|
||||
(t (gpr-get-indent-level-from-previous))))
|
||||
|
||||
(defun gpr-get-indent-level-from-previous ()
|
||||
(save-excursion
|
||||
(let (indent)
|
||||
(while (not indent)
|
||||
(forward-line -1)
|
||||
(setq indent
|
||||
(cond ((looking-at-p gpr-block-start-regex)
|
||||
(+ (current-indentation) gpr-indent-width))
|
||||
((looking-at-p gpr-block-end-regex)
|
||||
(current-indentation))
|
||||
((bobp) 0))))
|
||||
indent)))
|
||||
#+end_src
|
||||
|
||||
Define the mode, inheriting from =prog-mode=:
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(define-derived-mode gpr-mode prog-mode "GPRBuild"
|
||||
"GPR Mode is a major mode for editing GPRBuild files"
|
||||
(set (make-local-variable 'comment-start) "--")
|
||||
(set (make-local-variable 'comment-end) "")
|
||||
|
||||
(set (make-local-variable 'font-lock-defaults)
|
||||
'(gpr-font-lock-defaults))
|
||||
|
||||
(set (make-local-variable 'indent-line-function)
|
||||
'gpr-indent-line))
|
||||
#+end_src
|
||||
|
||||
Finally, add an [[help:auto-load-alist][auto-load-alist]] entry for =.gpr= files:
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(add-to-list 'auto-mode-alist '("\\.gpr\\'" . gpr-mode))
|
||||
#+end_src
|
||||
|
||||
**** Extra tweaks
|
||||
Want to use tabs for indentation so adding a hook for that:
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(add-hook 'gpr-mode-hook
|
||||
(lambda ()
|
||||
(setq tab-width gpr-indent-width)
|
||||
(setq indent-tabs-mode t)))
|
||||
#+end_src
|
||||
|
||||
* Tool Integrations
|
||||
** Git
|
||||
=magit= is truly a wonderful creation! Add keybinding for
|
||||
|
Loading…
x
Reference in New Issue
Block a user