Commit Diff


commit - da85c33e6032c4eeaafec9d4b678ffe22d05e754
commit + 364d8905c4b402f16888661371a24e3d7cfe5598
blob - bbec57761e43504d705fef1d68986c1ab9ae950b (mode 644)
blob + /dev/null
--- algol-mode.el
+++ /dev/null
@@ -1,226 +0,0 @@
-;;; a68-mode.el --- Major mode for editing Algol 68 code
-
-;; Copyright (C) 2011 Jose E. Marchesi
-;; Copyright (C) 2021 Omar Polo <op@omarpolo.com>
-
-;; Author: Jose E. Marchesi
-;;         Omar Polo <op@omarpolo.com>
-;; Maintainer: Omar Polo
-;; URL: https://git.omarpolo.com/a68-mode
-;; Keywords: languages
-;; Version: 0
-;; Package-Requires: ((emacs "24.3"))
-
-;; This file is NOT part of GNU Emacs.
-
-;; This program 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 3, or (at your option)
-;; any later version.
-
-;; This program 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 program; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
-
-;;; Commentary:
-
-;; A major mode for editing Algol 68 code.
-;;
-;; TODO: support quote and dot stropping.
-
-;;; Code:
-
-(require 'syntax)
-(require 'font-lock)
-
-(eval-when-compile
-  (require 'rx))
-
-(defvar a68-indent-step 3
-  "Indentation step for Algol 68.")
-
-(defvar a68-mode-hook '()
-  "Hook run when entering Algol68 mode.")
-
-(defvar a68-mode-map
-  (let ((map (make-keymap)))
-    (define-key map (kbd "C-j") #'newline-and-indent)
-    (define-key map (kbd "RET") #'a68-electric-terminate-line)
-    (define-key map (kbd "C-i") #'a68-electric-tab)
-    map)
-  "Keymap for Algol 68 major mode.")
-
-(defconst a68-font-lock-keywords
-  (list
-   (cons (rx word-start
-             (or "DECS" "PROGRAM" "CONTEXT" "USE" "FINISH" "KEEP"
-                 "ALIEN"
-                 "MODE" "OP" "PRIO" "PROC"
-                 "OF" "AT" "IS" "ISNT" "EMPTY" "SKIP"
-                 "PR" "PRAGMAT"
-                 "CASE" "IN" "OUSE" "OUT" "ESAC"
-                 "FOR" "FORALL" "FROM" "TO" "BY" "WHILE" "DO" "OD"
-                 "IF" "THEN" "ELIF" "THEN" "ELSE" "FI"
-                 "PAR" "BEGIN" "END" "GOTO" "EXIT"
-                 "LWB" "UPB" "NOT" "ABS" "BIN" "REPR" "LENG"
-                 "SHORTEN" "ODD" "SIGN" "ROUND" "ENTIER" "AND" "OR"
-                 "DIV" "OVER" "MOD" "ELEM" "SHL" "SHR" "OVERAB" "DIVAB" "MODAB"
-                 "REF")
-             word-end)
-         'font-lock-keyword-face)
-   (cons (rx word-start
-             (or "TRUE" "FALSE")
-             word-end)
-         'font-lock-constant-face)
-   ;; only valid for bold stropping
-   (cons (concat "\\<[A-Z]+\\>") 'font-lock-type-face)
-   (cons "\\('\\w*'\\)"
-         'font-lock-variable-name-face))
-  "Highlighting expressions for Algol 68 mode.")
-
-(defsubst a68-within-string ()
-  "Check if inside a string."
-  (nth 3 (syntax-ppss)))
-
-(defsubst a68-within-comment ()
-  "Check if inside a comment."
-  (nth 4 (syntax-ppss)))
-
-;; Indentation rules:
-;;
-;; - If we are at the beginning of the buffer, or looking at some
-;;   indent-0 content, indent to column 0.
-;;
-;; - If we are currently at an END, ), FI or OD, then de-indent
-;;   relative to the previous line.
-;;
-;; - If we first see and "end line" before our current line,
-;;   then we should indent our current line to the same indentation as
-;;   the end line.
-;;
-;; - If we first see a "start line" like IF, then we need to increase
-;;   our indentation relative to that start line.
-;;
-;; - If into a balanced expression, we should indent to the column
-;;   where the start of the innermost parenthetical group.
-;;
-;; - If none of the above apply, then do not indent at all.
-
-(defun a68-indent-line ()
-  "Indent current line as Algol 68 code."
-  (interactive)
-  (let ((case-fold-search nil))
-    (save-excursion
-      (beginning-of-line)
-      (if (nth 1 (syntax-ppss)) ; Check for rule 5
-          (let ((offset (save-excursion (goto-char (+ (nth 1 (syntax-ppss)) 1))
-                                        (current-column))))
-            (indent-line-to offset))
-        (if (or (bobp) ; Check for rule 1
-                (looking-at "^[ \t]*\\<\\(KEEP\\|FINISH\\|DECS\\|USE\\|PROGRAM\\)\\>"))
-            (indent-line-to 0)
-          (let ((not-indented t)
-                (prev-indent (current-indentation))
-                (begin-indent-re "^[ \t]*\\<\\(PAR\\|BEGIN\\|KEEP\\|IF\\|DO\\|ELSE\\|ELIF\\|THEN\\)")
-                (deindent-line-re "^[ \t]*\\<\\(END\\|FI\\|OD\\|ELSE\\|ELIF\\)\\>")
-                (eqindent-line-re "^[ \t]*\\<\\(THEN\\)\\>")
-                (end-line-re "^[ \t]*\\(END\\|FI\\|OD\\)")
-                cur-indent)
-            (if (looking-at eqindent-line-re)
-                (save-excursion
-                  (forward-line -1)
-                  (setq cur-indent (current-indentation)))
-              (if (looking-at deindent-line-re) ; Check for rule 2
-                  (progn
-                    (save-excursion
-                      (forward-line -1)
-                      (setq cur-indent (- (current-indentation) a68-indent-step)))
-                    (when (< cur-indent 0)
-                      (setq cur-indent 0)))
-                (save-excursion
-                  (while not-indented
-                    (forward-line -1)
-                    (if (looking-at end-line-re) ; Check for rule 3
-                        (progn
-                          (setq cur-indent (current-indentation))
-                          (setq not-indented nil))
-                      ;; Check for rule 4
-                      (if (looking-at begin-indent-re)
-                          (progn
-                            (setq cur-indent (+ (current-indentation) a68-indent-step))
-                            (setq not-indented nil))
-                        (when (bobp) ; Check for rule 5
-                          (setq not-indented nil))))))))
-            (if cur-indent
-                (indent-line-to cur-indent)
-              ;; If we didn't see an indentation hint, then allow no
-              ;; indentation.
-              (indent-line-to 0)))))))
-  (when (< (current-column) (current-indentation))
-    (move-to-column (current-indentation))))
-
-(defvar a68-mode-syntax-table
-  (let ((st (make-syntax-table)))
-    (modify-syntax-entry ?{ "<" st)
-    (modify-syntax-entry ?# "<" st)
-    (modify-syntax-entry ?} ">" st)
-    (modify-syntax-entry ?# ">" st)
-    (modify-syntax-entry ?\\ "." st)
-;;    (modify-syntax-entry ?C "< 13" st)
-;;    (modify-syntax-entry ?O "> 24" st)
-    ;; define parentheses to match
-    (modify-syntax-entry ?\( "()" st)
-    (modify-syntax-entry ?\) ")(" st)
-    st))
-
-;;;
-;;; Electric functions
-;;;
-
-(defconst a68-autoindent-lines-re
-  (rx word-start
-      (or "BEGIN" "END" "ELSE" "ELIF" "DO" "OD" "CASE" "ESAC" "IN" "OUT")
-      word-end))
-
-(defun a68-electric-terminate-line ()
-  "Terminate line and indent next line."
-  (interactive)
-  ;; First, check if current line should be indented
-  (save-excursion
-    (beginning-of-line)
-    (skip-chars-forward " \t")
-    (when (looking-at a68-autoindent-lines-re)
-      (a68-indent-line)))
-  (delete-horizontal-space) ; Removes triling whitespaces
-  (newline)
-  ;; Indent next line if we are not in a string
-  (unless (a68-within-string)
-    (a68-indent-line)))
-
-(defun a68-electric-tab ()
-  "Function called when TAB is pressed in Algol68 mode."
-  (interactive)
-  (unless (save-excursion
-            (beginning-of-line)
-            (a68-within-string))
-    (a68-indent-line)))
-
-;;;###autoload
-(define-derived-mode a68-mode prog-mode "Algol68"
-  "Major mode for editing Alogl68 files."
-  (setq-local font-lock-defaults '(a68-font-lock-keywords))
-  (setq-local indent-line-function #'a68-indent-line)
-  (setq-local comment-start "#")
-  (setq-local comment-end "#"))
-
-;;;###autoload
-(add-to-list 'auto-mode-alist '("\\.a68\\'" . a68-mode))
-
-(provide 'algol-mode)
-;;; algol-mode.el ends here
blob - /dev/null
blob + bbec57761e43504d705fef1d68986c1ab9ae950b (mode 644)
--- /dev/null
+++ a68-mode.el
@@ -0,0 +1,226 @@
+;;; a68-mode.el --- Major mode for editing Algol 68 code
+
+;; Copyright (C) 2011 Jose E. Marchesi
+;; Copyright (C) 2021 Omar Polo <op@omarpolo.com>
+
+;; Author: Jose E. Marchesi
+;;         Omar Polo <op@omarpolo.com>
+;; Maintainer: Omar Polo
+;; URL: https://git.omarpolo.com/a68-mode
+;; Keywords: languages
+;; Version: 0
+;; Package-Requires: ((emacs "24.3"))
+
+;; This file is NOT part of GNU Emacs.
+
+;; This program 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 3, or (at your option)
+;; any later version.
+
+;; This program 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 program; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; A major mode for editing Algol 68 code.
+;;
+;; TODO: support quote and dot stropping.
+
+;;; Code:
+
+(require 'syntax)
+(require 'font-lock)
+
+(eval-when-compile
+  (require 'rx))
+
+(defvar a68-indent-step 3
+  "Indentation step for Algol 68.")
+
+(defvar a68-mode-hook '()
+  "Hook run when entering Algol68 mode.")
+
+(defvar a68-mode-map
+  (let ((map (make-keymap)))
+    (define-key map (kbd "C-j") #'newline-and-indent)
+    (define-key map (kbd "RET") #'a68-electric-terminate-line)
+    (define-key map (kbd "C-i") #'a68-electric-tab)
+    map)
+  "Keymap for Algol 68 major mode.")
+
+(defconst a68-font-lock-keywords
+  (list
+   (cons (rx word-start
+             (or "DECS" "PROGRAM" "CONTEXT" "USE" "FINISH" "KEEP"
+                 "ALIEN"
+                 "MODE" "OP" "PRIO" "PROC"
+                 "OF" "AT" "IS" "ISNT" "EMPTY" "SKIP"
+                 "PR" "PRAGMAT"
+                 "CASE" "IN" "OUSE" "OUT" "ESAC"
+                 "FOR" "FORALL" "FROM" "TO" "BY" "WHILE" "DO" "OD"
+                 "IF" "THEN" "ELIF" "THEN" "ELSE" "FI"
+                 "PAR" "BEGIN" "END" "GOTO" "EXIT"
+                 "LWB" "UPB" "NOT" "ABS" "BIN" "REPR" "LENG"
+                 "SHORTEN" "ODD" "SIGN" "ROUND" "ENTIER" "AND" "OR"
+                 "DIV" "OVER" "MOD" "ELEM" "SHL" "SHR" "OVERAB" "DIVAB" "MODAB"
+                 "REF")
+             word-end)
+         'font-lock-keyword-face)
+   (cons (rx word-start
+             (or "TRUE" "FALSE")
+             word-end)
+         'font-lock-constant-face)
+   ;; only valid for bold stropping
+   (cons (concat "\\<[A-Z]+\\>") 'font-lock-type-face)
+   (cons "\\('\\w*'\\)"
+         'font-lock-variable-name-face))
+  "Highlighting expressions for Algol 68 mode.")
+
+(defsubst a68-within-string ()
+  "Check if inside a string."
+  (nth 3 (syntax-ppss)))
+
+(defsubst a68-within-comment ()
+  "Check if inside a comment."
+  (nth 4 (syntax-ppss)))
+
+;; Indentation rules:
+;;
+;; - If we are at the beginning of the buffer, or looking at some
+;;   indent-0 content, indent to column 0.
+;;
+;; - If we are currently at an END, ), FI or OD, then de-indent
+;;   relative to the previous line.
+;;
+;; - If we first see and "end line" before our current line,
+;;   then we should indent our current line to the same indentation as
+;;   the end line.
+;;
+;; - If we first see a "start line" like IF, then we need to increase
+;;   our indentation relative to that start line.
+;;
+;; - If into a balanced expression, we should indent to the column
+;;   where the start of the innermost parenthetical group.
+;;
+;; - If none of the above apply, then do not indent at all.
+
+(defun a68-indent-line ()
+  "Indent current line as Algol 68 code."
+  (interactive)
+  (let ((case-fold-search nil))
+    (save-excursion
+      (beginning-of-line)
+      (if (nth 1 (syntax-ppss)) ; Check for rule 5
+          (let ((offset (save-excursion (goto-char (+ (nth 1 (syntax-ppss)) 1))
+                                        (current-column))))
+            (indent-line-to offset))
+        (if (or (bobp) ; Check for rule 1
+                (looking-at "^[ \t]*\\<\\(KEEP\\|FINISH\\|DECS\\|USE\\|PROGRAM\\)\\>"))
+            (indent-line-to 0)
+          (let ((not-indented t)
+                (prev-indent (current-indentation))
+                (begin-indent-re "^[ \t]*\\<\\(PAR\\|BEGIN\\|KEEP\\|IF\\|DO\\|ELSE\\|ELIF\\|THEN\\)")
+                (deindent-line-re "^[ \t]*\\<\\(END\\|FI\\|OD\\|ELSE\\|ELIF\\)\\>")
+                (eqindent-line-re "^[ \t]*\\<\\(THEN\\)\\>")
+                (end-line-re "^[ \t]*\\(END\\|FI\\|OD\\)")
+                cur-indent)
+            (if (looking-at eqindent-line-re)
+                (save-excursion
+                  (forward-line -1)
+                  (setq cur-indent (current-indentation)))
+              (if (looking-at deindent-line-re) ; Check for rule 2
+                  (progn
+                    (save-excursion
+                      (forward-line -1)
+                      (setq cur-indent (- (current-indentation) a68-indent-step)))
+                    (when (< cur-indent 0)
+                      (setq cur-indent 0)))
+                (save-excursion
+                  (while not-indented
+                    (forward-line -1)
+                    (if (looking-at end-line-re) ; Check for rule 3
+                        (progn
+                          (setq cur-indent (current-indentation))
+                          (setq not-indented nil))
+                      ;; Check for rule 4
+                      (if (looking-at begin-indent-re)
+                          (progn
+                            (setq cur-indent (+ (current-indentation) a68-indent-step))
+                            (setq not-indented nil))
+                        (when (bobp) ; Check for rule 5
+                          (setq not-indented nil))))))))
+            (if cur-indent
+                (indent-line-to cur-indent)
+              ;; If we didn't see an indentation hint, then allow no
+              ;; indentation.
+              (indent-line-to 0)))))))
+  (when (< (current-column) (current-indentation))
+    (move-to-column (current-indentation))))
+
+(defvar a68-mode-syntax-table
+  (let ((st (make-syntax-table)))
+    (modify-syntax-entry ?{ "<" st)
+    (modify-syntax-entry ?# "<" st)
+    (modify-syntax-entry ?} ">" st)
+    (modify-syntax-entry ?# ">" st)
+    (modify-syntax-entry ?\\ "." st)
+;;    (modify-syntax-entry ?C "< 13" st)
+;;    (modify-syntax-entry ?O "> 24" st)
+    ;; define parentheses to match
+    (modify-syntax-entry ?\( "()" st)
+    (modify-syntax-entry ?\) ")(" st)
+    st))
+
+;;;
+;;; Electric functions
+;;;
+
+(defconst a68-autoindent-lines-re
+  (rx word-start
+      (or "BEGIN" "END" "ELSE" "ELIF" "DO" "OD" "CASE" "ESAC" "IN" "OUT")
+      word-end))
+
+(defun a68-electric-terminate-line ()
+  "Terminate line and indent next line."
+  (interactive)
+  ;; First, check if current line should be indented
+  (save-excursion
+    (beginning-of-line)
+    (skip-chars-forward " \t")
+    (when (looking-at a68-autoindent-lines-re)
+      (a68-indent-line)))
+  (delete-horizontal-space) ; Removes triling whitespaces
+  (newline)
+  ;; Indent next line if we are not in a string
+  (unless (a68-within-string)
+    (a68-indent-line)))
+
+(defun a68-electric-tab ()
+  "Function called when TAB is pressed in Algol68 mode."
+  (interactive)
+  (unless (save-excursion
+            (beginning-of-line)
+            (a68-within-string))
+    (a68-indent-line)))
+
+;;;###autoload
+(define-derived-mode a68-mode prog-mode "Algol68"
+  "Major mode for editing Alogl68 files."
+  (setq-local font-lock-defaults '(a68-font-lock-keywords))
+  (setq-local indent-line-function #'a68-indent-line)
+  (setq-local comment-start "#")
+  (setq-local comment-end "#"))
+
+;;;###autoload
+(add-to-list 'auto-mode-alist '("\\.a68\\'" . a68-mode))
+
+(provide 'algol-mode)
+;;; algol-mode.el ends here