]> rtime.felk.cvut.cz Git - omk.git/blob - contrib/omk-mode.el
Add experimental version of omk-mode for Emacs
[omk.git] / contrib / omk-mode.el
1 ;;; omk-mode.el --- Major mode for editing OMK makefiles
2
3 ;; Copyright (C) 2014  Michal Sojka
4
5 ;; Author: Michal Sojka <sojkam1@fel.cvut.cz>
6 ;; Keywords: convenience, files, extensions
7
8 ;; This program is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation, either version 3 of the License, or
11 ;; (at your option) any later version.
12
13 ;; This program is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
17
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
21 ;;; Commentary:
22
23 ;;
24
25 ;;; Code:
26
27 (require 'make-mode)
28
29 ;; config_include_HEADERS -> _DEFINES
30
31 (defconst omk-target-keywords-regex
32   "\\<\\(\\(lib\\|shared\\)_LIBRARIES\\|\\(bin\\|test\\|utils\\)_PROGRAMS\\)\\>")
33
34 (defconst omk-target-specific-keywords
35   '(SOURCES LIBS CFLAGS CXXFLAGS CPPFLAGS GEN_SOURCES))
36
37 (defconst omk-keywords
38   '("lib_LOADLIBES" "LOADLIBES" "INCLUDES" "DEFS" "LN_HEADERS" "SUBDIRS"
39     "ALL_OMK_SUBDIRS" "AUTOMATIC_SUBDIRS"
40     "default_CONFIG" "LOCAL_CONFIG_H" "config_include_HEADERS"))
41
42 (defun omk-match-keywords (bound)
43   (re-search-forward (concat "\\<\\(" (mapconcat 'identity omk-keywords "\\|")  "\\)\\>") bound t))
44
45 (defun omk-get-targets ()
46   (save-excursion
47     (save-match-data
48       (goto-char (point-min))
49       (loop while
50             (re-search-forward
51              (concat omk-target-keywords-regex "[ \t]*\\(?:!=\\|[*:+]?[:?]?=\\)")
52              nil t)
53             append
54             (loop while (re-search-forward "[^ \t]+" (line-end-position) t)
55                   collect (match-string 0))))))
56 (defun omk-match-target-specific-keywords (bound)
57   (let ((targets (omk-get-targets)))    ; This is not very effective
58     (re-search-forward
59      (concat "\\<\\(" (mapconcat 'identity targets "\\|") "\\)_"
60              "\\(" (mapconcat 'symbol-name omk-target-specific-keywords "\\|")
61              "\\)\\>")
62      bound t)))
63
64 (defconst omk-font-lock-keywords
65   `((,omk-target-keywords-regex . font-lock-keyword-face)
66     ("\\<\\(nobase_\\|rename_\\)?include_HEADERS\\>" . font-lock-keyword-face)
67     (omk-match-keywords . font-lock-keyword-face)
68     (omk-match-target-specific-keywords . font-lock-keyword-face)
69     ,@makefile-gmake-font-lock-keywords))
70
71 (defun omk-font-lock-extend-after-change-region (beg end ond-len)
72   (if (save-excursion
73         (save-match-data
74           (let ((endl (progn (goto-char end) (end-of-line))))
75             (goto-char beg)
76             (beginning-of-line)
77             (re-search-forward omk-target-keywords-regex endl t))))
78       (cons (point-min) (point-max))
79     nil))
80
81 (define-derived-mode omk-mode makefile-gmake-mode "OMK"
82   "An adapted `makefile-gmake-mode' that know about OMK"
83   (setq font-lock-defaults
84         `(omk-font-lock-keywords ,@(cdr font-lock-defaults)))
85   (setq font-lock-extend-after-change-region-function 'omk-font-lock-extend-after-change-region))
86
87 (add-to-list 'auto-mode-alist '("\\.omk$" . omk-mode))
88
89 (provide 'omk-mode)
90 ;;; omk-mode.el ends here