comments, modul operators, mark error messages
- add comments - add keybord shortcuts - add modul operators (from naturals, sequences) - add functions to mark error messages in the SANY check buffer.
This commit is contained in:
parent
87707476af
commit
c58bbb6671
458
tla+-mode.el
458
tla+-mode.el
|
@ -1,24 +1,24 @@
|
||||||
;; Copyright (C) 2019 Christian Barthel <bch@online.de>
|
;; Copyright (C) 2019 Christian Barthel <bch@online.de>
|
||||||
|
|
||||||
;; Author: Christian Barthel
|
;; Author: Christian Barthel
|
||||||
;; Keywords: TLA+
|
;; Keywords: TLA+
|
||||||
|
|
||||||
;; This file is free software; you can redistribute it and/or modify
|
;; This file is free software; you can redistribute it and/or modify
|
||||||
;; it under the terms of the GNU General Public License as published by
|
;; it under the terms of the GNU General Public License as published by
|
||||||
;; the Free Software Foundation; either version 2, or (at your option)
|
;; the Free Software Foundation; either version 2, or (at your option)
|
||||||
;; any later version.
|
;; any later version.
|
||||||
|
|
||||||
;; This file is distributed in the hope that it will be useful,
|
;; This file is distributed in the hope that it will be useful,
|
||||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
;; GNU General Public License for more details.
|
;; GNU General Public License for more details.
|
||||||
|
|
||||||
;; You should have received a copy of the GNU General Public License
|
;; You should have received a copy of the GNU General Public License
|
||||||
;; along with GNU Emacs; see the file COPYING. If not, write to
|
;; along with GNU Emacs; see the file COPYING. If not, write to
|
||||||
;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
;; Boston, MA 02111-1307, USA.
|
;; Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
;;; Commentary:
|
;;; Commentary:
|
||||||
|
|
||||||
;; This package defines TLA+ Major Mode to manipulate TLA+
|
;; This package defines TLA+ Major Mode to manipulate TLA+
|
||||||
;; specifications.
|
;; specifications.
|
||||||
|
@ -26,6 +26,10 @@
|
||||||
|
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
|
||||||
|
|
||||||
|
;; -------------------------------------------------------------------
|
||||||
|
;; Customization variables:
|
||||||
|
|
||||||
(defcustom tla+-mode-hook '()
|
(defcustom tla+-mode-hook '()
|
||||||
"Normal hook run when entering TLA+ mode."
|
"Normal hook run when entering TLA+ mode."
|
||||||
:type 'hook
|
:type 'hook
|
||||||
|
@ -55,21 +59,185 @@
|
||||||
:type 'file
|
:type 'file
|
||||||
:group 'tla+)
|
:group 'tla+)
|
||||||
|
|
||||||
|
|
||||||
|
;; -------------------------------------------------------------------------------
|
||||||
(defvar tla+-mode-map
|
(defvar tla+-mode-map
|
||||||
(let
|
(let
|
||||||
((map (make-sparse-keymap))
|
((map (make-sparse-keymap))
|
||||||
(menu-map (make-sparse-keymap "TLA+"))
|
(menu-map (make-sparse-keymap "TLA+"))
|
||||||
|
|
||||||
(operator-map (make-sparse-keymap))
|
(operator-map (make-sparse-keymap))
|
||||||
|
|
||||||
(action-operator-map (make-sparse-keymap))
|
(action-operator-map (make-sparse-keymap))
|
||||||
(temporal-operator-map (make-sparse-keymap))
|
(temporal-operator-map (make-sparse-keymap))
|
||||||
(export-map (make-sparse-keymap)))
|
(export-map (make-sparse-keymap))
|
||||||
|
|
||||||
|
(modul-operators (make-sparse-keymap))
|
||||||
|
(modul-sequences-operators (make-sparse-keymap))
|
||||||
|
(modul-naturals-operators (make-sparse-keymap))
|
||||||
|
)
|
||||||
(set-keymap-parent map lisp-mode-shared-map)
|
(set-keymap-parent map lisp-mode-shared-map)
|
||||||
(define-key map "\e\t" 'ispell-complete-word)
|
(define-key map "\e\t" 'ispell-complete-word)
|
||||||
|
(define-key map (kbd "C-c C-t e") 'tla+-run-tlatex-dvi)
|
||||||
|
(define-key map (kbd "C-c C-t o") 'tla+-open-dvi)
|
||||||
|
(define-key map (kbd "C-c C-t c") 'tla+-run-sany)
|
||||||
|
|
||||||
;; Main TLA+ Menu:
|
;; Main TLA+ Menu:
|
||||||
(bindings--define-key map [menu-bar tla+]
|
(bindings--define-key map [menu-bar tla+]
|
||||||
(cons "TLA+" menu-map))
|
(cons "TLA+" menu-map))
|
||||||
|
|
||||||
|
;; Modul Operators
|
||||||
|
(bindings--define-key menu-map [modul-operators]
|
||||||
|
(cons "Insert Modul Operator.." modul-operators))
|
||||||
|
|
||||||
|
;; Naturals Operators
|
||||||
|
(bindings--define-key modul-operators
|
||||||
|
[modul-naturals-operator]
|
||||||
|
(cons "Naturals" modul-naturals-operators))
|
||||||
|
|
||||||
|
(bindings--define-key
|
||||||
|
modul-naturals-operators [add-nat]
|
||||||
|
'(menu-item "+"
|
||||||
|
(lambda () (interactive)
|
||||||
|
(insert "+"))
|
||||||
|
:help "Addition"))
|
||||||
|
|
||||||
|
(bindings--define-key
|
||||||
|
modul-naturals-operators [sub-nat]
|
||||||
|
'(menu-item "-"
|
||||||
|
(lambda () (interactive)
|
||||||
|
(insert "-")
|
||||||
|
(backward-char 2))
|
||||||
|
:help "Subtraction"))
|
||||||
|
|
||||||
|
(bindings--define-key
|
||||||
|
modul-naturals-operators [mult-nat]
|
||||||
|
'(menu-item "*"
|
||||||
|
(lambda () (interactive)
|
||||||
|
(insert "*"))
|
||||||
|
:help "Multiplication"))
|
||||||
|
|
||||||
|
(bindings--define-key
|
||||||
|
modul-naturals-operators [div-nat]
|
||||||
|
'(menu-item "/"
|
||||||
|
(lambda () (interactive)
|
||||||
|
(insert "/"))
|
||||||
|
:help "Division"))
|
||||||
|
|
||||||
|
(bindings--define-key
|
||||||
|
modul-naturals-operators [exp-nat]
|
||||||
|
'(menu-item "^"
|
||||||
|
(lambda () (interactive)
|
||||||
|
(insert "^"))
|
||||||
|
:help "Exponentiation"))
|
||||||
|
|
||||||
|
(bindings--define-key
|
||||||
|
modul-naturals-operators [ft-nat]
|
||||||
|
'(menu-item ".."
|
||||||
|
(lambda () (interactive)
|
||||||
|
(insert ".."))
|
||||||
|
:help "From..To"))
|
||||||
|
|
||||||
|
(bindings--define-key
|
||||||
|
modul-naturals-operators [div2-nat]
|
||||||
|
'(menu-item "\\div"
|
||||||
|
(lambda () (interactive)
|
||||||
|
(insert "\div"))
|
||||||
|
:help "Integer Division"))
|
||||||
|
|
||||||
|
|
||||||
|
(bindings--define-key
|
||||||
|
modul-naturals-operators [mod-nat]
|
||||||
|
'(menu-item "%"
|
||||||
|
(lambda () (interactive)
|
||||||
|
(insert "%"))
|
||||||
|
:help "Modulo"))
|
||||||
|
|
||||||
|
|
||||||
|
(bindings--define-key
|
||||||
|
modul-naturals-operators [leq-nat]
|
||||||
|
'(menu-item "\\leq"
|
||||||
|
(lambda () (interactive)
|
||||||
|
(insert "\\leq"))
|
||||||
|
:help "Lower Equal"))
|
||||||
|
|
||||||
|
(bindings--define-key
|
||||||
|
modul-naturals-operators [geq-nat]
|
||||||
|
'(menu-item "\\geq"
|
||||||
|
(lambda () (interactive)
|
||||||
|
(insert "\\geq"))
|
||||||
|
:help "Greater Equal"))
|
||||||
|
|
||||||
|
(bindings--define-key
|
||||||
|
modul-naturals-operators [lt-nat]
|
||||||
|
'(menu-item "<"
|
||||||
|
(lambda () (interactive)
|
||||||
|
(insert "<"))
|
||||||
|
:help "Lower than"))
|
||||||
|
|
||||||
|
(bindings--define-key
|
||||||
|
modul-naturals-operators [gt-nat]
|
||||||
|
'(menu-item ">"
|
||||||
|
(lambda () (interactive)
|
||||||
|
(insert ">"))
|
||||||
|
:help "Greater than"))
|
||||||
|
|
||||||
|
|
||||||
|
;; Sequence Operators
|
||||||
|
(bindings--define-key modul-operators
|
||||||
|
[modul-sequences-operator]
|
||||||
|
(cons "Sequences" modul-sequences-operators))
|
||||||
|
|
||||||
|
(bindings--define-key
|
||||||
|
modul-sequences-operators [seq-s]
|
||||||
|
'(menu-item "Seq(S)"
|
||||||
|
(lambda () (interactive)
|
||||||
|
(insert "Seq(S)")
|
||||||
|
(backward-char 2))
|
||||||
|
:help
|
||||||
|
"Set of all Sequences of Elements of Set `S'"))
|
||||||
|
|
||||||
|
(bindings--define-key
|
||||||
|
modul-sequences-operators [head-s]
|
||||||
|
'(menu-item "Head(s)"
|
||||||
|
(lambda () (interactive)
|
||||||
|
(insert "Head(s)")
|
||||||
|
(backward-char 2))
|
||||||
|
:help "Head element of sequence `s'"))
|
||||||
|
|
||||||
|
(bindings--define-key
|
||||||
|
modul-sequences-operators [tail-s]
|
||||||
|
'(menu-item "Tail(s)"
|
||||||
|
(lambda () (interactive)
|
||||||
|
(insert "Tail(s)")
|
||||||
|
(backward-char 2))
|
||||||
|
:help "Tail sequence of sequence `s'"))
|
||||||
|
|
||||||
|
(bindings--define-key
|
||||||
|
modul-sequences-operators [append-s]
|
||||||
|
'(menu-item "Append(s,e)"
|
||||||
|
(lambda () (interactive)
|
||||||
|
(insert "Tail(S)")
|
||||||
|
(backward-char 2))
|
||||||
|
:help "Tail sequence of sequence `S'"))
|
||||||
|
|
||||||
|
(bindings--define-key
|
||||||
|
modul-sequences-operators [circ-s]
|
||||||
|
'(menu-item "s \\circ t"
|
||||||
|
(lambda () (interactive)
|
||||||
|
(insert "s \\circ t")
|
||||||
|
(backward-char 2))
|
||||||
|
:help "concatenation of sequence s and t"))
|
||||||
|
|
||||||
|
(bindings--define-key
|
||||||
|
modul-sequences-operators [len-s]
|
||||||
|
'(menu-item "Len(s)"
|
||||||
|
(lambda () (interactive)
|
||||||
|
(insert "Len(s)")
|
||||||
|
(backward-char 2))
|
||||||
|
:help "length of sequence s"))
|
||||||
|
|
||||||
|
|
||||||
;; Operators
|
;; Operators
|
||||||
(bindings--define-key menu-map [operator]
|
(bindings--define-key menu-map [operator]
|
||||||
(cons "Insert Operator.." operator-map))
|
(cons "Insert Operator.." operator-map))
|
||||||
|
@ -79,32 +247,32 @@
|
||||||
(cons "Action Operator" action-operator-map))
|
(cons "Action Operator" action-operator-map))
|
||||||
|
|
||||||
(bindings--define-key
|
(bindings--define-key
|
||||||
action-operator-map [primed-operator]
|
action-operator-map [primed-operator]
|
||||||
'(menu-item "e'" tla+-operator-primed
|
'(menu-item "e'" tla+-operator-primed
|
||||||
:help "Value of e in final state of a step"))
|
:help "Value of e in final state of a step"))
|
||||||
|
|
||||||
(bindings--define-key
|
(bindings--define-key
|
||||||
action-operator-map [stutter-operator]
|
action-operator-map [stutter-operator]
|
||||||
'(menu-item "[A]_e" tla+-operator-stutter
|
'(menu-item "[A]_e" tla+-operator-stutter
|
||||||
:help "A \\/ (e' = e)"))
|
:help "A \\/ (e' = e)"))
|
||||||
|
|
||||||
(bindings--define-key
|
(bindings--define-key
|
||||||
action-operator-map [nonstutter-operator]
|
action-operator-map [nonstutter-operator]
|
||||||
'(menu-item "<<A>>_e" tla+-operator-nonstutter
|
'(menu-item "<<A>>_e" tla+-operator-nonstutter
|
||||||
:help "A /\ (e' \\= e)"))
|
:help "A /\\ (e' \\\\ = e)"))
|
||||||
|
|
||||||
(bindings--define-key
|
(bindings--define-key
|
||||||
action-operator-map [enabled-operator]
|
action-operator-map [enabled-operator]
|
||||||
'(menu-item "ENABLED A" tla+-operator-enabled
|
'(menu-item "ENABLED A" tla+-operator-enabled
|
||||||
:help "An A step is possible"))
|
:help "An A step is possible"))
|
||||||
|
|
||||||
(bindings--define-key
|
(bindings--define-key
|
||||||
action-operator-map [unchanged-operator]
|
action-operator-map [unchanged-operator]
|
||||||
'(menu-item "UNCHANGED e" tla+-operator-unchanged
|
'(menu-item "UNCHANGED e" tla+-operator-unchanged
|
||||||
:help "e = e'"))
|
:help "e = e'"))
|
||||||
|
|
||||||
(bindings--define-key
|
(bindings--define-key
|
||||||
action-operator-map [composition-operator]
|
action-operator-map [composition-operator]
|
||||||
'(menu-item "A \\cdot B" tla+-operator-composition
|
'(menu-item "A \\cdot B" tla+-operator-composition
|
||||||
:help "Composition of actions"))
|
:help "Composition of actions"))
|
||||||
|
|
||||||
|
@ -113,32 +281,33 @@
|
||||||
(cons "Temporal Operator" temporal-operator-map))
|
(cons "Temporal Operator" temporal-operator-map))
|
||||||
|
|
||||||
(bindings--define-key
|
(bindings--define-key
|
||||||
temporal-operator-map [always-temporal-operator]
|
temporal-operator-map [always-temporal-operator]
|
||||||
'(menu-item "[]F" tla+-operator-alwaystrue
|
'(menu-item "[]F" tla+-operator-alwaystrue
|
||||||
:help "F is always true"))
|
:help "F is always true"))
|
||||||
|
|
||||||
(bindings--define-key
|
(bindings--define-key
|
||||||
temporal-operator-map [eventually-temporal-operator]
|
temporal-operator-map [eventually-temporal-operator]
|
||||||
'(menu-item "<>F" tla+-operator-eventually
|
'(menu-item "<>F" tla+-operator-eventually
|
||||||
:help "F is eventually true"))
|
:help "F is eventually true"))
|
||||||
|
|
||||||
(bindings--define-key
|
(bindings--define-key
|
||||||
temporal-operator-map [wf-temporal-operator]
|
temporal-operator-map [wf-temporal-operator]
|
||||||
'(menu-item "WF_e(A)" tla+-operator-weakfairness
|
'(menu-item "WF_e(A)" tla+-operator-weakfairness
|
||||||
:help "Weak fairness for action A"))
|
:help "Weak fairness for action A"))
|
||||||
|
|
||||||
(bindings--define-key
|
(bindings--define-key
|
||||||
temporal-operator-map [sf-temporal-operator]
|
temporal-operator-map [sf-temporal-operator]
|
||||||
'(menu-item "SF_e(A)" tla+-operator-strongfairness
|
'(menu-item "SF_e(A)" tla+-operator-strongfairness
|
||||||
:help "Strong fairness for action A"))
|
:help "Strong fairness for action A"))
|
||||||
|
|
||||||
(bindings--define-key
|
(bindings--define-key
|
||||||
temporal-operator-map [leadsto-temporal-operator]
|
temporal-operator-map [leadsto-temporal-operator]
|
||||||
'(menu-item "F ~> G" tla+-operator-leadsto
|
'(menu-item "F ~> G" tla+-operator-leadsto
|
||||||
:help "F leads to G"))
|
:help "F leads to G"))
|
||||||
|
|
||||||
;; Export Menu:
|
;; Export Menu:
|
||||||
(bindings--define-key menu-map [export] (cons "Export.." export-map))
|
(bindings--define-key menu-map [export]
|
||||||
|
(cons "Export.." export-map))
|
||||||
|
|
||||||
(bindings--define-key export-map [export-pdf]
|
(bindings--define-key export-map [export-pdf]
|
||||||
'(menu-item "Run TLatex and create PDF" tla+-run-tlatex-pdf
|
'(menu-item "Run TLatex and create PDF" tla+-run-tlatex-pdf
|
||||||
|
@ -161,24 +330,24 @@
|
||||||
|
|
||||||
(bindings--define-key map [menu-bar tla+ tla+-run-sany]
|
(bindings--define-key map [menu-bar tla+ tla+-run-sany]
|
||||||
'(menu-item "Run Syntax Checker" tla+-run-sany
|
'(menu-item "Run Syntax Checker" tla+-run-sany
|
||||||
:help
|
:help
|
||||||
"Run SANY2 "
|
"Run SANY2 "
|
||||||
"(parser/syntax checker for TLA+ specifications.) "))
|
"(syntax checker for TLA+ specifications) "))
|
||||||
|
|
||||||
(bindings--define-key map [menu-bar tla+ tla+-create-module]
|
(bindings--define-key map [menu-bar tla+ tla+-create-module]
|
||||||
'(menu-item "Create new Module" tla+-create-module
|
'(menu-item "Create new Module" tla+-create-module
|
||||||
:help "Create a new TLA+ Module"))
|
:help "Create a new TLA+ Module"))
|
||||||
(bindings--define-key map [menu-bar tla+ sep] menu-bar-separator)
|
(bindings--define-key map [menu-bar tla+ sep] menu-bar-separator)
|
||||||
map)
|
map)
|
||||||
"Keymap for `tla+-mode'.")
|
"Keymap for `tla+-mode'.")
|
||||||
|
|
||||||
|
|
||||||
(defconst tla+-font-lock-keywords
|
(defconst tla+-font-lock-keywords
|
||||||
(list
|
(list
|
||||||
'("\\<\\(MODULE\\|CONSTANTS?\\|UNCHANGED\\|VARIABLES?\\|THEOREM\\|INSTANCE\\|LOCAL\\|ASUME\\|EXCEPT\\|EXTENDS?\\)\\>"
|
'("\\<\\(MODULE\\|CONSTANTS?\\|UNCHANGED\\|VARIABLES?\\|THEOREM\\|LOCAL\\|ASUME\\|EXTENDS?\\)\\>"
|
||||||
. font-lock-builtin-face)
|
. font-lock-builtin-face)
|
||||||
'("\\<\\(TRUE\\|FALSE\\|OTHER\\|BOOLEAN\\)\\>" . font-lock-type-face)
|
'("\\<\\(TRUE\\|FALSE\\|OTHER\\|BOOLEAN\\)\\>" . font-lock-type-face)
|
||||||
'("\\<\\(CONSTANT\\|SUBSET\\|ENABLED\\|UNCHANGED\\|UNION\\|DOMAIN\\|EXCEPT\\|IF\\|THEN\\|ELSE\\|CHOOSE\\)\\>" . font-lock-keyword-face)
|
'("\\<\\(CONSTANT\\|SUBSET\\|ENABLED\\|UNCHANGED\\|INSTANCE\\|WITH\\|EXCEPT\\|UNION\\|DOMAIN\\|EXCEPT\\|IF\\|THEN\\|ELSE\\|CHOOSE\\)\\>" . font-lock-keyword-face)
|
||||||
'("\\\\\\*.*$" . font-lock-comment-face)
|
'("\\\\\\*.*$" . font-lock-comment-face)
|
||||||
'("(\\*.*\\*)" . font-lock-comment-face)
|
'("(\\*.*\\*)" . font-lock-comment-face)
|
||||||
'("\\('\\w*'\\)" . font-lock-variable-name-face)
|
'("\\('\\w*'\\)" . font-lock-variable-name-face)
|
||||||
|
@ -194,50 +363,74 @@ files. Various operators can be inserted by `tla+-operator-NAME'.
|
||||||
\\{text-mode-map}
|
\\{text-mode-map}
|
||||||
Turning on Text mode runs the normal hook `text-mode-hook'."
|
Turning on Text mode runs the normal hook `text-mode-hook'."
|
||||||
(setq-local font-lock-defaults
|
(setq-local font-lock-defaults
|
||||||
'(tla+-font-lock-keywords))
|
'(tla+-font-lock-keywords))
|
||||||
(setq-local text-mode-variant t)
|
(setq-local text-mode-variant t)
|
||||||
(setq-local comment-start "\\* ")
|
(setq-local comment-start "\\* ")
|
||||||
(setq-local require-final-newline mode-require-final-newline))
|
(setq-local require-final-newline mode-require-final-newline))
|
||||||
|
|
||||||
|
|
||||||
(defun tla+-create-module ()
|
(defun tla+-create-module ()
|
||||||
|
"Insert the base template for a new Module.
|
||||||
|
A new module will be created with the typical structure of a TLA+
|
||||||
|
specification file."
|
||||||
(interactive)
|
(interactive)
|
||||||
(insert
|
(let ((modulename
|
||||||
(concat
|
(concat (file-name-base (buffer-file-name)))))
|
||||||
"------------------- MODULE ......... -----------------------\n"
|
(insert
|
||||||
"EXTENDS Naturals, ...\n"
|
(concat
|
||||||
"VARIABLE ..\n"
|
"------------------- MODULE "
|
||||||
"------------------------------------------------------------\n"
|
modulename
|
||||||
"============================================================\n"
|
" -----------------------\n"
|
||||||
"\\* Modification History\n"
|
"EXTENDS Naturals, ...\n"
|
||||||
"\\* Created "
|
"VARIABLE ..\n"
|
||||||
(current-time-string) " by " user-full-name "\n")))
|
"------------------------------------------------------------\n"
|
||||||
|
"============================================================\n"
|
||||||
|
"\\* Modification History\n"
|
||||||
|
"\\* Created "
|
||||||
|
(current-time-string) " by " user-full-name "\n"))))
|
||||||
|
|
||||||
|
|
||||||
(defun tla+-run-sany ()
|
(defun tla+-run-sany ()
|
||||||
"TODO: jump to line.."
|
"This function runs tla2sany.SANY (TLA syntax checker)
|
||||||
|
The function executes the TLA+ Syntax checker and reports errors
|
||||||
|
in a new frame. Errors are clickable buttons and the user can
|
||||||
|
directly go to the error line.
|
||||||
|
|
||||||
|
Operation:
|
||||||
|
1. execute the tla2sany.SANY program
|
||||||
|
2. the output of the shell-command is inserted into a newly
|
||||||
|
created buffer
|
||||||
|
3. errors are converted into clickable buttons by using the
|
||||||
|
`tla+/find-error-marks' function."
|
||||||
(interactive)
|
(interactive)
|
||||||
(let* ((filename (buffer-file-name))
|
(let* ((filename (buffer-file-name))
|
||||||
(sanybuffer (get-buffer-create "*tla2sany.SANY*"))
|
(sanybuffer (get-buffer-create "*tla2sany.SANY*"))
|
||||||
(output (shell-command-to-string (concat
|
(output (shell-command-to-string (concat
|
||||||
tla+-java-path
|
tla+-java-path
|
||||||
" -cp "
|
" -cp "
|
||||||
tla+-tlatools-path
|
tla+-tlatools-path
|
||||||
" tla2sany.SANY "
|
" tla2sany.SANY "
|
||||||
filename))))
|
filename))))
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(split-window-below)
|
(split-window-below)
|
||||||
(other-window 1)
|
(other-window 1)
|
||||||
(switch-to-buffer sanybuffer)
|
(switch-to-buffer sanybuffer)
|
||||||
(erase-buffer)
|
(erase-buffer)
|
||||||
(insert output))))
|
(insert output)
|
||||||
|
(tla+/find-error-marks))))
|
||||||
|
|
||||||
(defun tla+-open-dvi (buffername)
|
(defun tla+-open-dvi (buffername)
|
||||||
|
"Function to open a DVI file.
|
||||||
|
This function starts the `xdvi' utility and opens the TLA+
|
||||||
|
specification file as DVI. It must be created beforehand
|
||||||
|
with the `tla+-run-tlatex-dvi'.
|
||||||
|
"
|
||||||
(interactive "b")
|
(interactive "b")
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(switch-to-buffer buffername)
|
(switch-to-buffer buffername)
|
||||||
(let* ((filename (buffer-file-name))
|
(let* ((filename (buffer-file-name))
|
||||||
(dviname (replace-regexp-in-string
|
(dviname (replace-regexp-in-string
|
||||||
".tla$" ".dvi" filename)))
|
".tla$" ".dvi" filename)))
|
||||||
(shell-command (concat "xdvi " dviname " &")))))
|
(shell-command (concat "xdvi " dviname " &")))))
|
||||||
|
|
||||||
(defun tla+-operator-alwaystrue ()
|
(defun tla+-operator-alwaystrue ()
|
||||||
|
@ -269,37 +462,46 @@ Turning on Text mode runs the normal hook `text-mode-hook'."
|
||||||
(interactive) (insert " ENABLED A"))
|
(interactive) (insert " ENABLED A"))
|
||||||
|
|
||||||
(defun tla+-operator-unchanged ()
|
(defun tla+-operator-unchanged ()
|
||||||
|
"insert UNCHANGED operator.
|
||||||
|
Variables declared as unchanged will have the same value when a
|
||||||
|
step is taken to a new state, i.e. e' = e. "
|
||||||
(interactive) (insert " UNCHANGED e"))
|
(interactive) (insert " UNCHANGED e"))
|
||||||
|
|
||||||
(defun tla+-operator-unchanged ()
|
(defun tla+-operator-cdot ()
|
||||||
|
"insert operator A \\cdot B
|
||||||
|
A \\cdot B describes the composition of actions A, B."
|
||||||
(interactive) (insert " A \\cdot B"))
|
(interactive) (insert " A \\cdot B"))
|
||||||
|
|
||||||
(defun tla+-run-tlatex (type)
|
(defun tla+-run-tlatex (type)
|
||||||
"TODO: jump to line.."
|
"Run TLaTeX and generate DVI, PDF or PS file.
|
||||||
|
This function runs `pdflatex(1)' and geneartes a DVI file which can
|
||||||
|
be viewed with `xdvi'. If TYPE is 'pdf or 'ps, a PDF or PostScript
|
||||||
|
file will be generated as well.
|
||||||
|
The function executes one or two shell commands synchronously."
|
||||||
(interactive
|
(interactive
|
||||||
(list
|
(list
|
||||||
(completing-read
|
(completing-read
|
||||||
"Format: "
|
"Format: "
|
||||||
'(("pdf" 1) ("dvi" 2) ("ps" 3)) nil t "")))
|
'(("pdf" 1) ("dvi" 2) ("ps" 3)) nil t "")))
|
||||||
(let* ((filename (buffer-file-name))
|
(let* ((filename (buffer-file-name))
|
||||||
(output (shell-command (concat
|
(output (shell-command (concat
|
||||||
tla+-java-path
|
tla+-java-path
|
||||||
" -cp "
|
" -cp "
|
||||||
tla+-tlatools-path
|
tla+-tlatools-path
|
||||||
" tla2tex.TLA "
|
" tla2tex.TLA "
|
||||||
filename)))
|
filename)))
|
||||||
(dvipath (replace-regexp-in-string
|
(dvipath (replace-regexp-in-string
|
||||||
".tla$" ".dvi" filename))
|
".tla$" ".dvi" filename))
|
||||||
(convert2pdf (concat
|
(convert2pdf (concat
|
||||||
tla+-dvipdf-path " " dvipath))
|
tla+-dvipdf-path " " dvipath))
|
||||||
(convert2ps (concat
|
(convert2ps (concat
|
||||||
tla+-dvips-path " " dvipath)))
|
tla+-dvips-path " " dvipath)))
|
||||||
(progn
|
(progn
|
||||||
(cond
|
(cond
|
||||||
((eq type 'pdf)
|
((eq type 'pdf)
|
||||||
(shell-command convert2pdf))
|
(shell-command convert2pdf))
|
||||||
((eq type 'ps)
|
((eq type 'ps)
|
||||||
(shell-command convert2ps)))
|
(shell-command convert2ps)))
|
||||||
type)))
|
type)))
|
||||||
;; (save-excursion
|
;; (save-excursion
|
||||||
;; (split-window-below)
|
;; (split-window-below)
|
||||||
|
@ -308,10 +510,116 @@ Turning on Text mode runs the normal hook `text-mode-hook'."
|
||||||
;; (insert output))))
|
;; (insert output))))
|
||||||
|
|
||||||
(defun tla+-run-tlatex-pdf ()
|
(defun tla+-run-tlatex-pdf ()
|
||||||
|
"Create PDF file from TLA+ Specification.
|
||||||
|
This function creates a PDF file of a TLA+ Specification by
|
||||||
|
`tla+-run-tlatex'"
|
||||||
(interactive) (tla+-run-tlatex 'pdf))
|
(interactive) (tla+-run-tlatex 'pdf))
|
||||||
(defun tla+-run-tlatex-dvi ()
|
(defun tla+-run-tlatex-dvi ()
|
||||||
|
"Create DVI file from TLA+ Specification.
|
||||||
|
This function creates a DVI file of a TLA+ Specification by
|
||||||
|
`tla+-run-tlatex'"
|
||||||
(interactive) (tla+-run-tlatex 'dvi))
|
(interactive) (tla+-run-tlatex 'dvi))
|
||||||
(defun tla+-run-tlatex-ps ()
|
(defun tla+-run-tlatex-ps ()
|
||||||
|
"Create PS file from TLA+ Specification.
|
||||||
|
This function creates a PS file of a TLA+ Specification by
|
||||||
|
`tla+-run-tlatex'"
|
||||||
(interactive) (tla+-run-tlatex 'ps))
|
(interactive) (tla+-run-tlatex 'ps))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;; internal functions:
|
||||||
|
|
||||||
|
(define-button-type
|
||||||
|
'tla+/sany-button-pressed
|
||||||
|
'action 'tla+/sany-button-pressed
|
||||||
|
'follow-link t
|
||||||
|
'help-echo "Goto Source"
|
||||||
|
'help-args "test")
|
||||||
|
|
||||||
|
;; example: (make-button 1 12 :type 'custom-button)
|
||||||
|
|
||||||
|
(defun tla+/sany-button-pressed (button)
|
||||||
|
"Find the position and goto a sany error position.
|
||||||
|
This function will be executed when a user clicks on a button inside
|
||||||
|
the SANY error report buffer. This is done by selecting the other
|
||||||
|
window and going to the line mentioned in the error message.
|
||||||
|
The parameter BUTTON is currently unused.
|
||||||
|
|
||||||
|
Steps done by this function:
|
||||||
|
1. get the button at the current position of the `point'
|
||||||
|
2. get the text label of the button which is usually a line like
|
||||||
|
line XX, column YY
|
||||||
|
3. Get line number and column count of the error message
|
||||||
|
4. select the other-window (it is assumed that this is the *.tla
|
||||||
|
specification where SANY was executed.
|
||||||
|
5. goto line and column.
|
||||||
|
"
|
||||||
|
(let* ((pos (point))
|
||||||
|
(the-button (button-at pos))
|
||||||
|
(text (button-label the-button))
|
||||||
|
(s (string-match
|
||||||
|
(concat
|
||||||
|
"line \\([0-9][0-9]*\\)," ; line XYZ
|
||||||
|
"\\(column\\|col\\) " ; "column" or "col"
|
||||||
|
"\\([0-9][0-9]*\\)" ; XYZ
|
||||||
|
text))
|
||||||
|
(line (string-to-number (match-string 1 text)))
|
||||||
|
(col (string-to-number (match-string 3 text)))
|
||||||
|
)
|
||||||
|
;(message (format "Button pressed: %s" text))
|
||||||
|
(progn
|
||||||
|
;(switch-to-buffer (other-buffer))
|
||||||
|
(other-window 1)
|
||||||
|
;(switch-to-buffer (other-buffer))
|
||||||
|
;(switch-to-buffer-other-window (current-buffer))
|
||||||
|
(goto-char (point-min))
|
||||||
|
(goto-line line)
|
||||||
|
(forward-char col)
|
||||||
|
;(switch-to-buffer (other-buffer))
|
||||||
|
;(message "%s" (buffer-name))
|
||||||
|
)))
|
||||||
|
|
||||||
|
(defun tla+/make-link-button (begin end)
|
||||||
|
"Generate button from BEGIN until END
|
||||||
|
This function generates a new button starting at BEGIN until END.
|
||||||
|
The button will execute the `tla+/sany-button-pressed' when a user
|
||||||
|
clicks on it.
|
||||||
|
"
|
||||||
|
(make-button begin end :type 'tla+/sany-button-pressed))
|
||||||
|
|
||||||
|
(defun tla+/find-error-marks ()
|
||||||
|
"find error marks reported by SANY.
|
||||||
|
This function tries to find errors reported by SANY and converts them
|
||||||
|
into clickable buttons. By clicking on an error, the point will be
|
||||||
|
set to the other-buffer on that particular line and column. Currently
|
||||||
|
supported:
|
||||||
|
line XX, column YY
|
||||||
|
line XX, col YY
|
||||||
|
XX,YY are natural numbers.
|
||||||
|
|
||||||
|
The procedure works by:
|
||||||
|
1. finding a line that may look like an error message as described
|
||||||
|
above.
|
||||||
|
2. find the first offset and the last one
|
||||||
|
3. execute the `tla+/make-link-button' function to create a new button
|
||||||
|
"
|
||||||
|
(progn
|
||||||
|
(goto-char (point-min))
|
||||||
|
(while (re-search-forward
|
||||||
|
(concat
|
||||||
|
"line \\([0-9][0-9]*\\), "
|
||||||
|
"\\(column\\|col\\) "
|
||||||
|
"\\([0-9][0-9]*\\)")
|
||||||
|
(point-max) t)
|
||||||
|
(let* ((rstart (match-beginning 0))
|
||||||
|
(linenum (match-beginning 1))
|
||||||
|
(colnum (match-beginning 3))
|
||||||
|
(rend (+ colnum (- (length (int-to-string colnum)) 0)))
|
||||||
|
)
|
||||||
|
;(message "%s %s" linenum colnum)
|
||||||
|
(tla+/make-link-button rstart rend)
|
||||||
|
))))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(provide 'tla+-mode)
|
(provide 'tla+-mode)
|
||||||
|
|
Loading…
Reference in New Issue