1 ;;; omn-mode.el --- Support for OWL Manchester Notation
3 ;; Copyright (C) 2013 Free Software Foundation, Inc.
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
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.
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.
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/>.
25 ;; Defines a major mode for editing the Manchester OWL syntax.
26 ;; Basically, this is just a bit of font locking.
30 ;; (defgroup omn-mode nil
31 ;; "Major mode to edit OWL Manchester Notation."
34 (defvar omn-obsolete-electric-indent nil
35 "Set to t to use the old electric indent. Better use `electric-indent-mode'.")
37 (defvar omn-imenu-generic-expression
39 ("Class" "Class: \\([a-zA-Z:_]+\\)" 1)
40 ("ObjectProperty" "ObjectProperty: \\([a-zA-Z:_]+\\)" 1)
41 ("Individual" "Individual: \\([a-zA-Z:_]+\\)" 1)
44 "Imenu support for OMN.
45 See `imenu-generic-expression' for details")
48 (defvar omn-mode-entity-keywords
62 (defvar omn-mode-property-keywords
80 (defun omn-indent-line()
82 (omn-determine-line-indent)))
84 (defun omn-determine-line-indent()
87 ;; check the first word
89 (let* ((match (re-search-forward "\\w+" (line-end-position) t))
97 ;; (if (not (forward-line -1))
98 ;; (omn-determine-line-indent)
101 ;; if it is string, ident should be 0.
102 ((nth 3 (syntax-ppss (point)))
105 ;; if it is a comment
106 ((nth 4 (syntax-ppss (point)))
107 ;; if there is a next line, indent the same as that
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))
117 ;; if it is one of Class:, Prefix: or so on, then indent should be 0
118 ((member word omn-mode-entity-keywords)
120 ;; if it is Annotations:, SubClassOf: or so on, then indent should be 4
121 ((member word omn-mode-property-keywords)
124 ;; if it is something else, then 8
127 (add-to-list 'auto-mode-alist '("\\.pomn\\'" . omn-mode))
129 (add-to-list 'auto-mode-alist '("\\.omn\\'" . omn-mode))
131 (defvar omn-font-lock-defaults
133 (regexp-opt omn-mode-entity-keywords t)
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)))
155 (defvar omn-mode-syntax-table
156 (let ((st (make-syntax-table)))
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)
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))
187 (defun omn-mode-electric-indent()
189 (self-insert-command 1)
190 (omn-mode-indent-here))
192 (defun omn-mode-indent-here()
193 (let ((m (point-marker)))
195 (goto-char (marker-position m))))
197 (defun omn-mode-electric-newline()
204 (define-derived-mode omn-mode fundamental-mode "Omn"
208 (setq font-lock-defaults
209 '(omn-font-lock-defaults))
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-*")
216 (set (make-local-variable 'imenu-generic-expression)
217 omn-imenu-generic-expression)
219 (set (make-local-variable 'electric-indent-chars)
220 (append `(?\ ?\, ?\:)
221 (if (boundp 'electric-indent-chars)
222 (default-value 'electric-indent-chars)
225 (set (make-local-variable 'indent-line-function) 'omn-indent-line))
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.
232 ;; Write a parser for this in Java.
233 ;; Write a "command" interface, use annotation to mark each of the command setMethods.
235 ;; Have the command interface return results between tags as lisp. We can eval
236 ;; this, and get the result in that way.
240 ;;; omn-mode.el ends here