diff options
| author | Alasdair Armstrong | 2019-02-06 19:44:22 +0000 |
|---|---|---|
| committer | Alasdair Armstrong | 2019-02-06 19:48:55 +0000 |
| commit | aadbe7ede88dc9bbbda6a09876baacd6797153fb (patch) | |
| tree | 308d68ff63b2801f5de9a087e2b8785c1ceee3e1 /editors | |
| parent | 55f65f92812a6927d5661c2c25a09051630334b3 (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.el | 81 |
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 |
