]> code.delx.au - gnu-emacs-elpa/blob - packages/omn-mode/omn-mode.el
Merge commit '199c52606dcd614cb856bbcaca13b5fada0772b6' from avy
[gnu-emacs-elpa] / packages / omn-mode / omn-mode.el
1 ;;; omn-mode.el --- Support for OWL Manchester Notation
2
3 ;; Copyright (C) 2013 Free Software Foundation, Inc.
4
5 ;; Author: Phillip Lord <phillip.lord@newcastle.ac.uk>
6 ;; Maintainer: Phillip Lord <phillip.lord@newcastle.ac.uk>
7 ;; Website: http://www.russet.org.uk/blog
8 ;; Version: 1.0
9
10 ;; This program is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3 of the License, or
13 ;; (at your option) any later version.
14
15 ;; This program is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
22
23 ;;; Commentary:
24 ;;
25 ;; Defines a major mode for editing the Manchester OWL syntax.
26 ;; Basically, this is just a bit of font locking.
27
28 ;;; Code:
29
30 ;; (defgroup omn-mode nil
31 ;; "Major mode to edit OWL Manchester Notation."
32 ;; :group 'languages)
33
34 (defvar omn-obsolete-electric-indent nil
35 "Set to t to use the old electric indent. Better use `electric-indent-mode'.")
36
37 (defvar omn-imenu-generic-expression
38 '(
39 ("Class" "Class: \\([a-zA-Z:_]+\\)" 1)
40 ("ObjectProperty" "ObjectProperty: \\([a-zA-Z:_]+\\)" 1)
41 ("Individual" "Individual: \\([a-zA-Z:_]+\\)" 1)
42 )
43
44 "Imenu support for OMN.
45 See `imenu-generic-expression' for details")
46
47
48 (defvar omn-mode-entity-keywords
49 '(
50 "Ontology:"
51 "Namespace:"
52 "Class:"
53 "Individual:"
54 "ObjectProperty:"
55 "Import:"
56 "Datatype:"
57 "AnnotationProperty:"
58 "DisjointClasses:"
59 "Prefix:"
60 "owl:Thing"))
61
62 (defvar omn-mode-property-keywords
63 '(
64 "EquivalentTo:"
65 "SubClassOf:"
66 "Annotations:"
67 "Characteristics:"
68 "DisjointUnion:"
69 "DisjointWith:"
70 "Domain:"
71 "Range:"
72 "InverseOf:"
73 "SubPropertyOf:"
74 "Types:"
75 "Facts:"
76 ))
77
78
79 ;; indentation engine
80 (defun omn-indent-line()
81 (indent-line-to
82 (omn-determine-line-indent)))
83
84 (defun omn-determine-line-indent()
85 (save-excursion
86 (beginning-of-line)
87 ;; check the first word
88
89 (let* ((match (re-search-forward "\\w+" (line-end-position) t))
90 (word (if match
91 (match-string 0)
92 "")))
93
94 (cond
95 ;; ((not match)
96 ;; (progn
97 ;; (if (not (forward-line -1))
98 ;; (omn-determine-line-indent)
99 ;; 0)))
100
101 ;; if it is string, ident should be 0.
102 ((nth 3 (syntax-ppss (point)))
103 0)
104
105 ;; if it is a comment
106 ((nth 4 (syntax-ppss (point)))
107 ;; if there is a next line, indent the same as that
108 (cond
109 ((eq 0 (forward-line 1))
110 (omn-determine-line-indent))
111 ;; if there isn't return the same as the line before
112 ((eq 0 (forward-line -1))
113 (omn-determine-line-indent))
114 ;; who knows?
115 (t 0)))
116
117 ;; if it is one of Class:, Prefix: or so on, then indent should be 0
118 ((member word omn-mode-entity-keywords)
119 0)
120 ;; if it is Annotations:, SubClassOf: or so on, then indent should be 4
121 ((member word omn-mode-property-keywords)
122 4)
123
124 ;; if it is something else, then 8
125 (t 8)))))
126
127 (add-to-list 'auto-mode-alist '("\\.pomn\\'" . omn-mode))
128
129 (add-to-list 'auto-mode-alist '("\\.omn\\'" . omn-mode))
130
131 (defvar omn-font-lock-defaults
132 `(,(concat "\\_<"
133 (regexp-opt omn-mode-entity-keywords t)
134 "\\_>")
135 (,(mapconcat
136 (lambda(x) x)
137 '("\\<some\\>"
138 "\\<only\\>"
139 "\\<and\\>"
140 "\\<or\\>"
141 "\\<exactly\\>"
142 "\\<max\\>"
143 "\\<min\\>"
144 "Transitive"
145 "Functional"
146 "InverseFunctional"
147 )
148 "\\|")
149 . font-lock-type-face)
150 (,(regexp-opt omn-mode-property-keywords)
151 . font-lock-builtin-face)
152 ("\\w+:\\w+" . font-lock-function-name-face)))
153
154
155 (defvar omn-mode-syntax-table
156 (let ((st (make-syntax-table)))
157 ;; string quotes
158 (modify-syntax-entry ?\" "\"" st)
159 ;; This is a bit underhand, but we define the < and > characters to be
160 ;; "generic-string" delimiters. This results in fontification for URLs
161 ;; which is no bad thing. Additionally, it makes the comment character
162 ;; work, as "#" is a valid in a URL. The semantics of this isn't quite
163 ;; right, because the two characters are not paired. So <url> is
164 ;; recognised, but so is <url< or >url>.
165 ;; We could use a syntax-propertize-function to do more carefully.
166 (modify-syntax-entry ?\< "|" st)
167 (modify-syntax-entry ?\> "|" st)
168 ;; define comment characters for syntax
169 (modify-syntax-entry ?\# "<" st)
170 (modify-syntax-entry ?\n ">" st)
171 ;; Let's not confuse "words" and "symbols": "_" should not be part of the
172 ;; definition of a "word".
173 ;;(modify-syntax-entry ?\_ "w" st)
174 ;; For name space prefixes.
175 (modify-syntax-entry ?\: "w" st)
176 st))
177
178 (defvar omn-mode-map
179 (let ((map (make-sparse-keymap)))
180 (when omn-obsolete-electric-indent
181 (dolist (x `(" " "," ":"))
182 (define-key map x 'omn-mode-electric-indent))
183 ;; need to bind to return as well
184 (define-key map (kbd "RET") 'omn-mode-electric-newline))
185 map))
186
187 (defun omn-mode-electric-indent()
188 (interactive)
189 (self-insert-command 1)
190 (omn-mode-indent-here))
191
192 (defun omn-mode-indent-here()
193 (let ((m (point-marker)))
194 (omn-indent-line)
195 (goto-char (marker-position m))))
196
197 (defun omn-mode-electric-newline()
198 (interactive)
199 (newline)
200 (save-excursion
201 (forward-line -1)
202 (omn-indent-line)))
203
204 (define-derived-mode omn-mode fundamental-mode "Omn"
205 "Doc string to add"
206
207 ;; font-lock stuff
208 (setq font-lock-defaults
209 '(omn-font-lock-defaults))
210
211 (set (make-local-variable 'comment-start) "#")
212 (set (make-local-variable 'comment-end) "")
213 ;; no idea what this is about -- stolen from generic
214 (set (make-local-variable 'comment-start-skip) "#+\\s-*")
215
216 (set (make-local-variable 'imenu-generic-expression)
217 omn-imenu-generic-expression)
218
219 (set (make-local-variable 'electric-indent-chars)
220 (append `(?\ ?\, ?\:)
221 (if (boundp 'electric-indent-chars)
222 (default-value 'electric-indent-chars)
223 '(?\n))))
224
225 (set (make-local-variable 'indent-line-function) 'omn-indent-line))
226
227
228 ;; interaction with a reasoner.....
229 ;; Define a struct using CL, which defines a command. Then send this to the command line
230 ;; program as a single key-value pair line.
231 ;;
232 ;; Write a parser for this in Java.
233 ;; Write a "command" interface, use annotation to mark each of the command setMethods.
234 ;;
235 ;; Have the command interface return results between tags as lisp. We can eval
236 ;; this, and get the result in that way.
237
238 (provide 'omn-mode)
239
240 ;;; omn-mode.el ends here