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
63 (defvar omn-mode-property-keywords
81 (defun omn-indent-line()
83 (omn-determine-line-indent)))
85 (defun omn-determine-line-indent()
88 ;; check the first word
90 (let* ((match (re-search-forward "\\w+" (line-end-position) t))
98 ;; (if (not (forward-line -1))
99 ;; (omn-determine-line-indent)
102 ;; if it is string, ident should be 0.
103 ((nth 3 (syntax-ppss (point)))
106 ;; if it is a comment
107 ((nth 4 (syntax-ppss (point)))
108 ;; if there is a next line, indent the same as that
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))
118 ;; if it is one of Class:, Prefix: or so on, then indent should be 0
119 ((member word omn-mode-entity-keywords)
121 ;; if it is Annotations:, SubClassOf: or so on, then indent should be 4
122 ((member word omn-mode-property-keywords)
125 ;; if it is something else, then 8
128 (add-to-list 'auto-mode-alist '("\\.pomn\\'" . omn-mode))
130 (add-to-list 'auto-mode-alist '("\\.omn\\'" . omn-mode))
132 (defvar omn-font-lock-defaults
134 (regexp-opt omn-mode-entity-keywords t)
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)))
152 (defvar omn-mode-syntax-table
153 (let ((st (make-syntax-table)))
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)
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))
184 (defun omn-mode-electric-indent()
186 (self-insert-command 1)
187 (omn-mode-indent-here))
189 (defun omn-mode-indent-here()
190 (let ((m (point-marker)))
192 (goto-char (marker-position m))))
194 (defun omn-mode-electric-newline()
201 (define-derived-mode omn-mode fundamental-mode "Omn"
205 (setq font-lock-defaults
206 '(omn-font-lock-defaults))
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-*")
213 (set (make-local-variable 'imenu-generic-expression)
214 omn-imenu-generic-expression)
216 (set (make-local-variable 'electric-indent-chars)
217 (append `(?\ ?\, ?\:)
218 (if (boundp 'electric-indent-chars)
219 (default-value 'electric-indent-chars)
222 (set (make-local-variable 'indent-line-function) 'omn-indent-line))
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.
229 ;; Write a parser for this in Java.
230 ;; Write a "command" interface, use annotation to mark each of the command setMethods.
232 ;; Have the command interface return results between tags as lisp. We can eval
233 ;; this, and get the result in that way.
237 ;;; omn-mode.el ends here