From 5de9e31bdbc04d77ae6d854978e602a95873374f Mon Sep 17 00:00:00 2001 From: Tony Garnock-Jones Date: Sat, 13 Apr 2019 23:51:00 +1200 Subject: [PATCH] preserves.el --- preserves.el | 141 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 preserves.el diff --git a/preserves.el b/preserves.el new file mode 100644 index 0000000..071e2b3 --- /dev/null +++ b/preserves.el @@ -0,0 +1,141 @@ +;;; preserves.el --- Preserves editing commands for Emacs + +;; Add code like the following to your .emacs to install: +;; (autoload 'preserves-mode "...path.to.wherever.you.put.this.file.../preserves.el" nil t) +;; (setq auto-mode-alist (cons '("\\.mu\\'" . preserves-mode) +;; auto-mode-alist)) + +;; Copyright (C) 1988,94,96,2000 Free Software Foundation, Inc. +;; Copyright (C) 2003, 2005, 2011, 2016, 2019 Tony Garnock-Jones + +;; This is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; This is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this software; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +(require 'font-lock) +(require 'smie) + +;;--------------------------------------------------------------------------- +;; Font-lock, Indentation, and Mode + +(defvar preserves-mode-syntax-table (make-syntax-table) + "Syntax table in use in preserves-mode buffers.") + +;; (modify-syntax-entry ?' "\"" preserves-mode-syntax-table) +(modify-syntax-entry ?_ "_" preserves-mode-syntax-table) +(modify-syntax-entry ?\n "> b" preserves-mode-syntax-table) +(modify-syntax-entry ?\r "> b" preserves-mode-syntax-table) +(modify-syntax-entry ?/ ". 12b" preserves-mode-syntax-table) +(mapcar #'(lambda (x) (modify-syntax-entry x "w" preserves-mode-syntax-table)) + '(?- ?_ ?$ ?! ?? ?* ?+ ?~)) + +(defvar preserves-font-lock-keywords + (list + '("\\<\\(~\\|[A-Z]\\)[^[:space:].\n]*\\>" . font-lock-type-face) + '("\\\\[[:space:]]*?\n" . font-lock-warning-face) + (cons (regexp-opt '("->") 'symbols) 'font-lock-builtin-face) + + ;; (cons (regexp-opt + ;; '( + ;; "float" + ;; "double" + ;; "word32" + ;; "word64" + ;; "integer" + ;; "boolean" + ;; "text" + ;; "set" + ;; "list" + ;; "dict" + ;; "not" + ;; "ref" + ;; ) + ;; 'words) + ;; 'font-lock-builtin-face) + + )) + +(defun preserves-mode-variables () + (make-local-variable 'comment-use-syntax) + (make-local-variable 'comment-start) + (make-local-variable 'comment-end) + (make-local-variable 'comment-start-skip) + (setq comment-use-syntax t) + (setq comment-start "//") + (setq comment-end "") + (setq comment-start-skip "// *") + (make-local-variable 'font-lock-defaults) + (setq font-lock-defaults '(preserves-font-lock-keywords nil nil ())) + (make-local-variable 'indent-line-function) + (setq indent-line-function #'preserves-indent-line) + ) + +(defvar preserves-indent-basic 2 + "Basic indentation amount for Preserves.") + +(defun preserves-continuation-line-p () + (save-excursion + (and (zerop (forward-line -1)) + (progn (end-of-line) + (skip-syntax-backward " ") + (eq (char-before) ?\\))))) + +(defun preserves-hanging-paren-p () + (save-excursion + (forward-char) + (while (and (not (eq (char-after) ?\n)) + (eq (char-syntax (char-after)) ?\s)) + (forward-char)) + (eolp))) + +(defun preserves-indent-line () + (let ((new-indentation + (save-excursion + (beginning-of-line) + (skip-syntax-forward " ") + (let* ((at-close-paren (eq (char-syntax (char-after)) ?\))) + (ppss (syntax-ppss))) + (cond + ((cadddr ppss) nil) ;; when we are in a string, don't reindent + ((<= (car ppss) 0) 0) ;; not in any parentheses, outdent fully + (t (goto-char (cadr ppss)) + (cond + ((preserves-hanging-paren-p) + (beginning-of-line) + (skip-syntax-forward " ") + (if at-close-paren ;; close paren, no indent + (current-column) + (+ preserves-indent-basic (current-column)))) + (at-close-paren ;; close paren, treat it specially + (current-column)) + (t ;; not a close paren, do the default thing + (forward-char) + (skip-syntax-forward " ") + (current-column))))))))) + (when new-indentation + (indent-line-to (if (preserves-continuation-line-p) + (+ new-indentation preserves-indent-basic) + new-indentation))))) + +;;;###autoload +(define-derived-mode preserves-mode prog-mode "Preserves" + "Major mode for editing Preserves structures." + (preserves-mode-variables)) + +;;--------------------------------------------------------------------------- +;; Provides + +(provide 'preserves-mode) + +;;; preserves.el ends here