]> code.delx.au - gnu-emacs-elpa/blob - packages/omn-mode/omn-mode.el
Mark merge point of eldoc-eval.
[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 "Alias:"
61 "owl:Thing"))
62
63 (defvar omn-mode-property-keywords
64 '(
65 "EquivalentTo:"
66 "SubClassOf:"
67 "Annotations:"
68 "Characteristics:"
69 "DisjointUnion:"
70 "DisjointWith:"
71 "Domain:"
72 "Range:"
73 "InverseOf:"
74 "SubPropertyOf:"
75 "Types:"
76 "Facts:"
77 ))
78
79
80 ;; indentation engine
81 (defun omn-indent-line()
82 (indent-line-to
83 (omn-determine-line-indent)))
84
85 (defun omn-determine-line-indent()
86 (save-excursion
87 (beginning-of-line)
88 ;; check the first word
89
90 (let* ((match (re-search-forward "\\w+" (line-end-position) t))
91 (word (if match
92 (match-string 0)
93 "")))
94
95 (cond
96 ;; ((not match)
97 ;; (progn
98 ;; (if (not (forward-line -1))
99 ;; (omn-determine-line-indent)
100 ;; 0)))
101
102 ;; if it is string, ident should be 0.
103 ((nth 3 (syntax-ppss (point)))
104 0)
105
106 ;; if it is a comment
107 ((nth 4 (syntax-ppss (point)))
108 ;; if there is a next line, indent the same as that
109 (cond
110 ((eq 0 (forward-line 1))
111 (omn-determine-line-indent))
112 ;; if there isn't return the same as the line before
113 ((eq 0 (forward-line -1))
114 (omn-determine-line-indent))
115 ;; who knows?
116 (t 0)))
117
118 ;; if it is one of Class:, Prefix: or so on, then indent should be 0
119 ((member word omn-mode-entity-keywords)
120 0)
121 ;; if it is Annotations:, SubClassOf: or so on, then indent should be 4
122 ((member word omn-mode-property-keywords)
123 4)
124
125 ;; if it is something else, then 8
126 (t 8)))))
127
128 (add-to-list 'auto-mode-alist '("\\.pomn\\'" . omn-mode))
129
130 (add-to-list 'auto-mode-alist '("\\.omn\\'" . omn-mode))
131
132 (defvar omn-font-lock-defaults
133 `(,(concat "\\_<"
134 (regexp-opt omn-mode-entity-keywords t)
135 "\\_>")
136 (,(mapconcat
137 (lambda(x) x)
138 '("\\<some\\>"
139 "\\<only\\>"
140 "\\<and\\>"
141 "\\<or\\>"
142 "\\<exactly\\>"
143 "Transitive"
144 )
145 "\\|")
146 . font-lock-type-face)
147 (,(regexp-opt omn-mode-property-keywords)
148 . font-lock-builtin-face)
149 ("\\w+:\\w+" . font-lock-function-name-face)))
150
151
152 (defvar omn-mode-syntax-table
153 (let ((st (make-syntax-table)))
154 ;; string quotes
155 (modify-syntax-entry ?\" "\"" st)
156 ;; This is a bit underhand, but we define the < and > characters to be
157 ;; "generic-string" delimiters. This results in fontification for URLs
158 ;; which is no bad thing. Additionally, it makes the comment character
159 ;; work, as "#" is a valid in a URL. The semantics of this isn't quite
160 ;; right, because the two characters are not paired. So <url> is
161 ;; recognised, but so is <url< or >url>.
162 ;; We could use a syntax-propertize-function to do more carefully.
163 (modify-syntax-entry ?\< "|" st)
164 (modify-syntax-entry ?\> "|" st)
165 ;; define comment characters for syntax
166 (modify-syntax-entry ?\# "<" st)
167 (modify-syntax-entry ?\n ">" st)
168 ;; Let's not confuse "words" and "symbols": "_" should not be part of the
169 ;; definition of a "word".
170 ;;(modify-syntax-entry ?\_ "w" st)
171 ;; For name space prefixes.
172 (modify-syntax-entry ?\: "w" st)
173 st))
174
175 (defvar omn-mode-map
176 (let ((map (make-sparse-keymap)))
177 (when omn-obsolete-electric-indent
178 (dolist (x `(" " "," ":"))
179 (define-key map x 'omn-mode-electric-indent))
180 ;; need to bind to return as well
181 (define-key map (kbd "RET") 'omn-mode-electric-newline))
182 map))
183
184 (defun omn-mode-electric-indent()
185 (interactive)
186 (self-insert-command 1)
187 (omn-mode-indent-here))
188
189 (defun omn-mode-indent-here()
190 (let ((m (point-marker)))
191 (omn-indent-line)
192 (goto-char (marker-position m))))
193
194 (defun omn-mode-electric-newline()
195 (interactive)
196 (newline)
197 (save-excursion
198 (forward-line -1)
199 (omn-indent-line)))
200
201 (define-derived-mode omn-mode fundamental-mode "Omn"
202 "Doc string to add"
203
204 ;; font-lock stuff
205 (setq font-lock-defaults
206 '(omn-font-lock-defaults))
207
208 (set (make-local-variable 'comment-start) "#")
209 (set (make-local-variable 'comment-end) "")
210 ;; no idea what this is about -- stolen from generic
211 (set (make-local-variable 'comment-start-skip) "#+\\s-*")
212
213 (set (make-local-variable 'imenu-generic-expression)
214 omn-imenu-generic-expression)
215
216 (set (make-local-variable 'electric-indent-chars)
217 (append `(?\ ?\, ?\:)
218 (if (boundp 'electric-indent-chars)
219 (default-value 'electric-indent-chars)
220 '(?\n))))
221
222 (set (make-local-variable 'indent-line-function) 'omn-indent-line))
223
224
225 ;; interaction with a reasoner.....
226 ;; Define a struct using CL, which defines a command. Then send this to the command line
227 ;; program as a single key-value pair line.
228 ;;
229 ;; Write a parser for this in Java.
230 ;; Write a "command" interface, use annotation to mark each of the command setMethods.
231 ;;
232 ;; Have the command interface return results between tags as lisp. We can eval
233 ;; this, and get the result in that way.
234
235 (provide 'omn-mode)
236
237 ;;; omn-mode.el ends here