summaryrefslogtreecommitdiff
path: root/editors
diff options
context:
space:
mode:
authorAlasdair Armstrong2019-02-06 19:44:22 +0000
committerAlasdair Armstrong2019-02-06 19:48:55 +0000
commitaadbe7ede88dc9bbbda6a09876baacd6797153fb (patch)
tree308d68ff63b2801f5de9a087e2b8785c1ceee3e1 /editors
parent55f65f92812a6927d5661c2c25a09051630334b3 (diff)
Improve emacs mode
Can now use C-c C-s to start an interactive Sail process, C-c C-l to load a file, and C-c C-q to kill the sail process. Type errors are highlighted in the emacs buffer (like with merlin for OCaml) with a tooltip for the type-error, as well as being displayed in the minibuffer. Need to add a C-c C-x command like merlin to jump to the error, and figure out how to handle multiple files nicely, as well as hooking the save function like tuareg/merlin, but this is already enough to make working with small examples quite a bit more pleasant.
Diffstat (limited to 'editors')
-rw-r--r--editors/sail-mode.el81
1 files changed, 81 insertions, 0 deletions
diff --git a/editors/sail-mode.el b/editors/sail-mode.el
index 25181fea..35025d52 100644
--- a/editors/sail-mode.el
+++ b/editors/sail-mode.el
@@ -20,6 +20,8 @@
;;; Code:
+(require 'easymenu)
+
(defvar sail2-mode-hook nil)
(add-to-list 'auto-mode-alist '("\\.sail\\'" . sail2-mode))
@@ -76,6 +78,8 @@
(interactive)
(kill-all-local-variables)
(set-syntax-table sail2-mode-syntax-table)
+ (use-local-map sail-mode-map)
+ (sail-build-menu)
(setq font-lock-defaults '(sail2-font-lock-keywords))
(setq comment-start-skip "\\(//+\\|/\\*+\\)\\s *")
(setq comment-start "/*")
@@ -84,6 +88,83 @@
(setq mode-name "Sail2")
(run-hooks 'sail2-mode-hook))
+(defvar sail-process nil)
+
+(defun sail-filter (proc string)
+ (when (buffer-live-p (process-buffer proc))
+ (with-current-buffer (process-buffer proc)
+ (let ((moving (= (point) (process-mark proc))))
+ (save-excursion
+ ;; Insert the text, advancing the process marker.
+ (goto-char (process-mark proc))
+ (insert string)
+ (set-marker (process-mark proc) (point)))
+ (if moving (goto-char (process-mark proc)))))
+ (eval (car (read-from-string string)))))
+
+(defun sail-start ()
+ "start Sail interactive mode"
+ (interactive)
+ (setq sail-process (start-process "sail" "Sail" "sail" "-i" "-emacs"))
+ (set-process-filter sail-process 'sail-filter))
+
+(defun sail-quit ()
+ "quit Sail interactive mode"
+ (interactive)
+ (when sail-process
+ (process-send-string sail-process ":quit\n")
+ (setq sail-process nil)))
+
+(defun sail-error-region (begin end text)
+ (progn
+ (let ((overlay (make-overlay begin end)))
+ (overlay-put overlay 'face 'error)
+ (overlay-put overlay 'help-echo text)
+ (setq mark-active nil))))
+
+(defun sail-error (l1 c1 l2 c2 text)
+ (let ((begin (save-excursion
+ (goto-line l1)
+ (forward-char c1)
+ (point)))
+ (end (save-excursion
+ (goto-line l2)
+ (forward-char c2)
+ (point))))
+ (sail-error-region begin end text)
+ (message text)))
+
+(defun sail-test ()
+ (interactive)
+ (sail-error 6 18 6 19 "error message\ntooltip"))
+
+(defun sail-load ()
+ "load a Sail file"
+ (interactive)
+ (if (null sail-process)
+ (error "No sail process (call sail-start)")
+ (progn
+ (remove-overlays)
+ (process-send-string sail-process ":unload\n")
+ (process-send-string sail-process (mapconcat 'identity `(":load " ,buffer-file-name "\n") "")))))
+
+(defvar sail-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "C-c C-s") 'sail-start)
+ (define-key map (kbd "C-c C-l") 'sail-load)
+ (define-key map (kbd "C-c C-q") 'sail-quit)
+ map))
+
+(defun sail-build-menu ()
+ (easy-menu-define
+ sail-mode-menu (list sail-mode-map)
+ "Sail Mode Menu."
+ '("Sail"
+ ["Start" sail-start t]
+ ["Quit" sail-quit t]
+ ["Check buffer" sail-load t]))
+ (easy-menu-add sail-mode-menu))
+
(provide 'sail2-mode)
;;; sail-mode.el ends here