diff options
Diffstat (limited to 'tw/home/files/emacs-packages')
-rw-r--r-- | tw/home/files/emacs-packages/actionlint.el | 34 | ||||
-rw-r--r-- | tw/home/files/emacs-packages/alidist-mode.el | 162 | ||||
-rw-r--r-- | tw/home/files/emacs-packages/bemscript-mode.el | 92 | ||||
-rw-r--r-- | tw/home/files/emacs-packages/environmentd-mode.el | 46 | ||||
-rw-r--r-- | tw/home/files/emacs-packages/ifm-mode.el | 18 | ||||
-rw-r--r-- | tw/home/files/emacs-packages/org-latex-classes.el | 54 | ||||
-rw-r--r-- | tw/home/files/emacs-packages/pam-env-mode.el | 45 | ||||
-rw-r--r-- | tw/home/files/emacs-packages/vcard-mode.el | 56 |
8 files changed, 507 insertions, 0 deletions
diff --git a/tw/home/files/emacs-packages/actionlint.el b/tw/home/files/emacs-packages/actionlint.el new file mode 100644 index 00000000..3c37e34b --- /dev/null +++ b/tw/home/files/emacs-packages/actionlint.el @@ -0,0 +1,34 @@ +;;; actionlint.el --- Flycheck checker for GitHub Actions. +;;; Commentary: +;; GitHub Actions are defined using mostly plain YAML files. +;; Actionlint is a linter catching GitHub Action-specific mistakes, and also +;; checks Shell and Python code embedded in Actions (using shellcheck and +;; pyflakes, respectively). +;;; Code: + +(require 'flycheck) + +(defun actionlint-github-workflow-p () + "Does the current buffer contain a GitHub Action?" + (string-match-p "\\.github/workflows/[^/]+\\.yml\\'" (buffer-file-name))) + +(flycheck-def-executable-var actionlint "actionlint") + +(flycheck-define-checker actionlint + "A syntax checker and linter for alidist recipes." + ;; `flycheck-alidist-executable' automatically overrides the car of the + ;; :command list if set and non-nil. + :command ("actionlint" "-no-color" "-oneline" source) + :error-patterns + ((error line-start (file-name) ":" line ":" column ": " (message) + " [" (id (minimal-match (one-or-more not-newline))) "]" line-end)) + ;; Only enable this in actual GitHub Actions, not just any YAML document. + :modes (yaml-mode) + :predicate actionlint-github-workflow-p + ;; Also check the document with YAML checkers, whether or not we have errors. + :next-checkers (yaml-ruby yaml-yamllint)) + +(add-to-list 'flycheck-checkers 'actionlint) + +(provide 'actionlint) +;;; actionlint.el ends here diff --git a/tw/home/files/emacs-packages/alidist-mode.el b/tw/home/files/emacs-packages/alidist-mode.el new file mode 100644 index 00000000..0f264e3b --- /dev/null +++ b/tw/home/files/emacs-packages/alidist-mode.el @@ -0,0 +1,162 @@ +;;; alidist-mode.el --- Major mode for alidist recipes -*- lexical-binding: t -*- +;;; Commentary: +;;; alidist recipes are shell scripts with a YAML header in front. We +;;; want both these parts highlighted properly, and to lint the whole +;;; thing with a custom script that glues together yamllint and +;;; shellcheck with a few custom checks. +;;; Code: + +(require 'custom) +(require 'flymake) +(require 'mmm-mode) +(require 'mmm-cmds) +(require 'mmm-vars) +(require 'sh-script) +(require 'yaml-mode) + +(defgroup alidist-mode nil + "Alidist-related options." + :group 'languages + :prefix "alidist-mode-") + +(defcustom alidist-mode-alidistlint-executable "alidistlint" + "The alidistlint executable to use. This will be looked up in $PATH." + :type '(string) + :risky t + :group 'alidist-mode) + +(defvar alidist-mode--message-regexp + (rx bol "-:" ; filename + (group (+ digit)) ":" ; line + (group (+ digit)) ": " ; column + (group (or "note" "warning" "error")) ": " ; type + (group (+ not-newline)) eol) ; message + "Regular expression matching messages from alidistlint. +`alidist-flymake' expects the following capturing groups in this +regexp: (1) line number; (2) column number; (3) error type; (4) +message.") + +(defvar-local alidist-mode--flymake-proc nil + "The latest invocation of alidistlint.") + +;; See info node: (flymake)An annotated example backend. +(defun alidist-flymake (report-fn &rest _args) + "Run alidistlint and report diagnostics from it using REPORT-FN. +Any running invocations are killed before running another one." + (unless (executable-find alidist-mode-alidistlint-executable) + (funcall report-fn :panic + :explanation "Cannot find `alidist-mode-alidistlint-executable' program") + (error "Cannot find alidistlint executable")) + + ;; Kill previous check, if it's still running. + (when (process-live-p alidist-mode--flymake-proc) + (kill-process alidist-mode--flymake-proc)) + + ;; This needs `lexical-binding'. + (let ((source (current-buffer))) + (save-restriction + (widen) + (setq alidist-mode--flymake-proc + (make-process + :name "alidistlint-flymake" :noquery t :connection-type 'pipe + ;; Direct output to a temporary buffer. + :buffer (generate-new-buffer " *alidistlint-flymake*") + :command (list alidist-mode-alidistlint-executable "-f" "gcc" "-") + :sentinel + (lambda (proc _event) + "Parse diagnostic messages once the process PROC has exited." + ;; Check the process has actually exited, not just been suspended. + (when (memq (process-status proc) '(exit signal)) + (unwind-protect + ;; Only proceed if we've got the "latest" process. + (if (with-current-buffer source (eq proc alidist-mode--flymake-proc)) + (with-current-buffer (process-buffer proc) + (goto-char (point-min)) + (cl-loop + while (search-forward-regexp alidist-mode--message-regexp nil t) + for (beg . end) = (flymake-diag-region + source + (string-to-number (match-string 1)) + (string-to-number (match-string 2))) + for type = (pcase (match-string 3) + ("note" :note) + ("warning" :warning) + ("error" :error) + (type (error "Unknown alidistlint error type %s" type))) + collect (flymake-make-diagnostic source beg end type (match-string 4)) + into diags + finally (funcall report-fn diags))) + (flymake-log :warning "Canceling obsolete check %s" proc)) + ;; Clean up temporary buffer. + (kill-buffer (process-buffer proc))))))) + ;; Send the buffer to alidistlint on stdin. + (process-send-region alidist-mode--flymake-proc (point-min) (point-max)) + (process-send-eof alidist-mode--flymake-proc)))) + +(defvar-local alidist-mode--mmm-refresh-timer nil + "An idle timer for the current buffer, to make `mmm-mode' reparse it.") +(put 'alidist-mode--mmm-refresh-timer 'risky-local-variable t) + +(defun alidist-mode--cancel-refresh-timer () + "Cancel and delete the timer that reparses the buffer. +It is stored in `alidist-mode--mmm-refresh-timer'." + (when alidist-mode--mmm-refresh-timer + (cancel-timer alidist-mode--mmm-refresh-timer) + (setq alidist-mode--mmm-refresh-timer nil))) + +(define-derived-mode alidist-mode yaml-mode "alidist" + "An outer mode for alidist recipes, handling the metadata." + (mmm-mode) + ;; `mmm-mode' doesn't refresh its submodes when the buffer changes + ;; (e.g. when a *_recipe key is added to the YAML header), so + ;; refresh manually when idle. + (alidist-mode--cancel-refresh-timer) + (add-hook 'kill-buffer-hook #'alidist-mode--cancel-refresh-timer 0 t) + (setq alidist-mode--mmm-refresh-timer + (run-with-idle-timer + 2 t (lambda (original-buffer) + (when (eq original-buffer (current-buffer)) + ;; Silence `mmm-parse-buffer''s annoying message. + (let ((inhibit-message t)) + (mmm-parse-buffer)))) + ;; Idle timers are global, so make sure we only run the timer + ;; in the right buffer. Save the buffer now to enable this, + ;; and compare every time the timer ticks over. + (current-buffer))) + ;; Set up `flymake-mode'. + (add-hook 'flymake-diagnostic-functions #'alidist-flymake nil t)) + +(define-derived-mode alidist-script-mode sh-mode "Script" + "A mode for scripts in alidist recipes with some default settings." + (sh-set-shell "bash")) + +(mmm-add-group + 'alidist-recipe + '((alidist-main-script + :submode alidist-script-mode + :face mmm-default-submode-face + :front (rx line-start "---\n") + :back (rx buffer-end)) + (alidist-option-script + :submode alidist-script-mode + :face mmm-default-submode-face + ;; Any *_recipe key with a multiline string value is probably a script. + :front (rx line-start (* whitespace) (1+ (any alnum ?\_)) "_recipe: |\n") + ;; End of YAML header, or another YAML key. + :back (rx line-start + (or "---\n" + (seq (* whitespace) (+ (any alnum ?\_)) ":" + (or line-end whitespace))))))) + +;; Make `mmm-mode' remember `sh-mode' indentation variables. +(cl-dolist (var sh-var-list) + (cl-pushnew `(,var nil (sh-mode)) + mmm-save-local-variables :test 'equal)) + +(mmm-add-mode-ext-class 'alidist-mode nil 'alidist-recipe) +(add-to-list 'auto-mode-alist + (cons (rx (or bot "/") "alidist/" (1+ (not ?\/)) ".sh" eot) + #'alidist-mode)) + +(provide 'alidist-mode) +;;; alidist-mode.el ends here diff --git a/tw/home/files/emacs-packages/bemscript-mode.el b/tw/home/files/emacs-packages/bemscript-mode.el new file mode 100644 index 00000000..f46c858b --- /dev/null +++ b/tw/home/files/emacs-packages/bemscript-mode.el @@ -0,0 +1,92 @@ +;;; bemscript-mode.el --- Syntax highlighting for MERRILL BEMScript files. +;;; Commentary: +;;; Based on the MERRILL manual. Some commands may have been missed. +;;; Code: + +(defconst bemscript-mode-keywords + '("set" "setsubdomain" "magnetite" "iron" "tm54" "resize" "cubic anisotropy" + "uniaxial anisotropy" "cubicrotation" "easy axis" "external field strength" + "external field direction" "readmesh" "loadmesh" "readmagnetization" + "uniform magnetization" "randomize magnetization" "randomize all moments" + "remesh" "conjugategradient" "steepestdescent" "minimize" "energylog" + "closelogfile" "writeloopdata" "writemagnetization" "writedemag" "writehyst" + "writeboxdata" "appenddemagzone" "magnetizationtopath" "pathtomagnetization" + "renewpath" "refinepathto" "writetecplotpath" "readtecplotpath" + "readtecplotzone" "keypause" "makeinitialpath" "pathminimize" "pathlogfile" + "systemcommand" "pathstructureenergies" "reportenergy" "stop" "end" "loop" + "endloop" "define" "addto" "undefine" "generatecubemesh" "zonename") + "List of keywords for BEMScript mode. Intended for case folding.") + +(defconst bemscript-mode-builtins + '("Aex" "CurvatureWeight" "ExchangeCalculator" "K1" "K2" "Ls" "Ms" "mu" + "MaxEnergyEvaluations" "MaxPathEvaluations" "MaxRestart" "MaxMeshNumber" + "NEBSpring" "PathN" "Zone" "ZoneIncrement") + "List of built-in variable names for BEMScript.") + +(defconst bemscript-mode-special + '("patran" "tecplot" "POINT" "BLOCK" "SD" "muT" "mT" "T" "C") + "Variables with special meanings and units in BEMScript.") + +;; Available font-lock-*-faces: doc type string builtin comment keyword warning +;; constant (reference) preprocessor syntactic-function function-name +;; negation-char variable-name comment-delimiter +(defconst bemscript-mode-font-lock-defaults + `((;; See font-lock-keywords docs. Earlier lines seem to override later ones, + ;; except if both have OVERRIDE? t. + ;; Format: (REGEXP (GROUPNUM FACENAME OVERRIDE? LAXMATCH?)...) + ;; Comments + ("!\\(.*\\)" 1 font-lock-comment-face t t) + ("!" 0 font-lock-comment-delimiter-face t) + ("!!.*$" 0 font-lock-doc-face t) + + ;; Equals signs need spaces around them. + ("\\s-=\\s-" 0 font-lock-type-face t) ; there is no "operator" etc face + ("=" . font-lock-warning-face) + + ;; Numbers and variables + ("\\<[0-9]*\\.?[0-9]+\\(e[-+]?\\)?[0-9]*\\>" . font-lock-constant-face) + ("\\(\\<[#%][A-Z_a-z][0-9A-Z_a-z]*\\>\\|\\$[A-Z_a-z][0-9A-Za-z_]*\\$\\)" + . font-lock-variable-name-face) + + ;; Preprocessor (&-substitution) + (,(concat "\\([^&]\\|^\\)\\(&&\\)*" ; && escapes & + "\\(&\\([_a-zA-Z][_a-zA-Z0-9]*\\|{[_a-zA-Z][_a-zA-Z0-9]*}\\)\\)") + 3 font-lock-preprocessor-face) + (,(concat "\\([^&]\\|^\\)\\(&&\\)*" ; && escapes & + "\\(&\\($" ; bare & + "\\|[^&{_a-zA-Z]\\|{[^_a-zA-Z]" ; invalid char following & or &{ + ; invalid name or unclosed { + "\\|{[_a-zA-Z][_0-9a-zA-Z]*\\([^_0-9a-zA-Z}]\\|$\\)\\)\\)") + 3 font-lock-warning-face t) + + ;; Variable definitions + ("\\<\\(loop\\|define\\)\\s-+\\([_a-zA-Z][_a-zA-Z0-9]*\\)\\>" + 2 font-lock-function-name-face) + ("\\<\\(addto\\|undefine\\)\\s-+\\([_a-zA-Z][_a-zA-Z0-9]*\\)\\>" + 2 font-lock-variable-name-face) + + ;; Keywords + (,(regexp-opt bemscript-mode-special 'words) . font-lock-string-face) + (,(regexp-opt bemscript-mode-keywords 'words) . font-lock-keyword-face) + (,(regexp-opt bemscript-mode-builtins 'words) . font-lock-builtin-face)) + + ;; KEYWORDS-ONLY: if t, no syntactic fontification (strings and comments) + nil + ;; CASE-FOLD: if t, make keywords case-insensitive. + t) + "Font lock settings for BEMScript mode.") + +(define-derived-mode bemscript-mode prog-mode "BEMScript" + "BEMScript-mode is used for editing MERRILL scripts." + (setq comment-start "!" + comment-end "" + tab-width 2 + font-lock-defaults bemscript-mode-font-lock-defaults) + ;; Only word syntax entries are highlighted; add needed chars. + (modify-syntax-entry ?# "w") + ;; Strings in BEMScript are not quoted. + (modify-syntax-entry ?\" "w")) + +(add-to-list 'auto-mode-alist '("\\.bem\\'" . bemscript-mode)) +(provide 'bemscript-mode) +;;; bemscript-mode.el ends here diff --git a/tw/home/files/emacs-packages/environmentd-mode.el b/tw/home/files/emacs-packages/environmentd-mode.el new file mode 100644 index 00000000..4bb8812e --- /dev/null +++ b/tw/home/files/emacs-packages/environmentd-mode.el @@ -0,0 +1,46 @@ +;;; environmentd-mode.el --- Major mode for environment.d(5) files. + +;;; Commentary: + +;; This major mode font-locks files including /etc/environment and +;; ~/.config/environment.d/*.conf. Their format is specified by the +;; environment.d(5) man page. + +;;; Code: + +(defconst environmentd-mode/font-lock-defaults + '((("^[[:blank:]]+[^[:blank:]]+" . font-lock-warning-face) ; stray leading whitespace + ("^#+[[:blank:]]*" . font-lock-comment-delimiter-face) + ("^#+[[:blank:]]*\\(.*\\)$" 1 font-lock-comment-face) + ("\\\\[$\\]" . font-lock-string-face) ; escaped $ \ + ("^\\([A-Za-z_][A-Za-z0-9_]*\\)\\(=\\)" + (1 font-lock-variable-name-face) + (2 font-lock-keyword-face)) + ("\\(\\${\\)\\([A-Za-z_][A-Za-z0-9_]*\\)\\(:[+-]\\)[^}]*\\(}\\)" + (1 font-lock-keyword-face) + (2 font-lock-variable-name-face) + (3 font-lock-keyword-face) + (4 font-lock-keyword-face)) ; ${X:-default}-variable references + ("\\(\\${\\)\\([A-Za-z_][A-Za-z0-9_]*\\)\\(}\\)" + (1 font-lock-keyword-face) + (2 font-lock-variable-name-face) + (3 font-lock-keyword-face)) ; ${X}-variable references + ("\\(\\$\\)\\([A-Za-z_][A-Za-z0-9_]*\\)" + (1 font-lock-keyword-face) + (2 font-lock-variable-name-face))) ; $X-variable references + t nil ((?\' . "w") (?\" . "w"))) + "Font lock settings for Environment.d mode. See `font-lock-defaults' for documentation.") + +(define-derived-mode environmentd-mode prog-mode "Environment.d" + "Environment.d mode is used for environment.d(5) files." + (setq-local comment-start "#" + comment-start-skip "#" + comment-end "" + font-lock-defaults environmentd-mode/font-lock-defaults)) + +(add-to-list 'auto-mode-alist + '("/environment\\.d/[^/]+\\.conf\\'\\|\\`/etc/environment\\'" + . environmentd-mode)) + +(provide 'environmentd-mode) +;;; environmentd-mode.el ends here diff --git a/tw/home/files/emacs-packages/ifm-mode.el b/tw/home/files/emacs-packages/ifm-mode.el new file mode 100644 index 00000000..7416588b --- /dev/null +++ b/tw/home/files/emacs-packages/ifm-mode.el @@ -0,0 +1,18 @@ +(define-generic-mode 'ifm-mode + '("#") + '("title" "map" "require" "room" "join" "to" "dir" "exit" "go" "oneway" + "tag" "from" "link" "nolink" "item" "in" "note" "score" "need" "after" + "before" "leave" "all" "except" "cmd" "length" "start" "finish" "nodrop" + "nopath" "style" "hidden" "keep" "with" "until" "ignore" "give" "lost" + "do" "get" "drop" "until" "safe" "ignore" "goto" "endstyle") + '(("\\<\\(\\(north\\|south\\)\\(east\\|west\\)?\\|[ns][ew]?\\|east\\|west\\|[ew]\\)\\>" + . 'font-lock-builtin-face) + ("\\<\\([du]\\|down\\|up\\|in\\|out\\|last\\|it\\|them\\)\\>" + . 'font-lock-builtin-face) + ("\\<[0-9]+" . 'font-lock-constant-face) + ("\\<[_a-zA-Z][_0-9A-Za-z]*\\>" . 'font-lock-variable-name-face)) + '("\\.ifm\\'") + nil + "A mode for interactive fiction manager files") + +(provide 'ifm-mode) diff --git a/tw/home/files/emacs-packages/org-latex-classes.el b/tw/home/files/emacs-packages/org-latex-classes.el new file mode 100644 index 00000000..90d13341 --- /dev/null +++ b/tw/home/files/emacs-packages/org-latex-classes.el @@ -0,0 +1,54 @@ +;;; org-latex-classes.el --- LaTeX documentclass definitions for org-mode. +;;; Commentary: +;;; Code: +(require 'ox-latex) + +(defun tw/latex-section-commands (name) + "Create a pair of section commands like (\"\\NAME{%s}\" . \"\\NAME*{%s}\")." + (cons (format "\\%s{%%s}" name) (format "\\%s*{%%s}" name))) + +(defconst tw/latex-part (tw/latex-section-commands "part")) +(defconst tw/latex-chapter (tw/latex-section-commands "chapter")) +(defconst tw/latex-section-and-below + (mapcar #'tw/latex-section-commands + '("section" "subsection" "subsubsection" "paragraph" "subparagraph"))) + +(setq org-latex-classes + `(("paperlike" "\\documentclass{paperlike}" + . ,tw/latex-section-and-below) + + ("examtext" "\\documentclass{examtext}" + . ,tw/latex-section-and-below) + + ("minutes" "\\documentclass{minutes}" + . ,tw/latex-section-and-below) + + ("mapreport" "\\documentclass{mapreport}" + ,tw/latex-chapter . ,tw/latex-section-and-below) + + ("pt3report" "\\documentclass{pt3report}" + ,tw/latex-chapter . ,tw/latex-section-and-below) + + ("article" "\\documentclass{article}" + . ,tw/latex-section-and-below) + + ("scrartcl" "\\documentclass{scrartcl}" + . ,tw/latex-section-and-below) + + ("report" "\\documentclass{report}" + ,tw/latex-part ,tw/latex-chapter . ,tw/latex-section-and-below) + + ("report-noparts" "\\documentclass{report}" + ,tw/latex-chapter . ,tw/latex-section-and-below) + + ("book" "\\documentclass{book}" + ,tw/latex-part ,tw/latex-chapter . ,tw/latex-section-and-below) + + ("book-noparts" "\\documentclass{book}" + ,tw/latex-chapter . ,tw/latex-section-and-below) + + ("checklist" "\\documentclass{checklist}" + . ,tw/latex-section-and-below))) + +(provide 'org-latex-classes) +;;; org-latex-classes.el ends here diff --git a/tw/home/files/emacs-packages/pam-env-mode.el b/tw/home/files/emacs-packages/pam-env-mode.el new file mode 100644 index 00000000..75b0bf94 --- /dev/null +++ b/tw/home/files/emacs-packages/pam-env-mode.el @@ -0,0 +1,45 @@ +;;; pam-env.el --- Major mode for pam_env.conf(5) files. + +;;; Commentary: + +;; This major mode font-locks files including ~/.pam_environment and +;; /etc/security/pam_env.conf, but notably not /etc/environment. Their format is +;; specified by the pam_env.conf(5) man page. + +;; TODO: Only apply font-lock-variable-name-face to variable declarations if +;; the previous line didn't end with a backslash. The following case didn't +;; work (some declarations that should've been font-locked weren't): +;; '("\\(?:^$\\|[^\\\\]\\)[\r\n]\\([^[:blank:]]+\\)" +;; 1 font-lock-variable-name-face keep) + +;; pam_env does not support escaped double quotes ("). Single-quoted strings are +;; not used as string delimiters. We can only match against word chars in +;; `pam-env-mode/font-lock-defaults', so make double quotes word chars. + +;;; Code: + +(defconst pam-env-mode/font-lock-defaults + '((("^#+" . font-lock-comment-delimiter-face) + ("^#+[[:blank:]]*\\(.*\\)$" 1 font-lock-comment-face) + ("\\\\[@$\\]" . font-lock-string-face) ; escaped $ @ \ + ("@{[^}]+}" . font-lock-builtin-face) ; @{}-variable references + ("\\${[^}]+}" . font-lock-variable-name-face) ; ${}-variable references + ("\"[^\"]*\"" 0 font-lock-string-face keep) ; double-quoted strings; escaped " not supported + ("\\<\\(DEFAULT\\|OVERRIDE\\)=" . font-lock-keyword-face) ; DEFAULT= and OVERRIDE= + ("^[^[:blank:]]+" . font-lock-variable-name-face) ; variable declarations + ("[[:blank:]]+[^[:blank:]]+" . font-lock-warning-face)) ; stray whitespace + t nil ((?\' . "w") (?\" . "w"))) + "Font lock settings for PAM-Environment mode. See `font-lock-defaults' for documentation.") + +(define-derived-mode pam-env-mode prog-mode "PAM-Environment" + "PAM-environment mode is used for pam_env.conf(5) files." + (set (make-local-variable 'comment-start) "#") + (set (make-local-variable 'comment-start-skip) "^#+[[:blank:]]*") + (set (make-local-variable 'comment-end) "") + (set (make-local-variable 'font-lock-defaults) pam-env-mode/font-lock-defaults)) + +(let ((regexp "\\(\\`\\|/\\)\\(pam_env\\.conf\\|\\.pam_environment\\)\\'")) + (add-to-list 'auto-mode-alist `(,regexp . pam-env-mode))) + +(provide 'pam-env-mode) +;;; pam-env.el ends here diff --git a/tw/home/files/emacs-packages/vcard-mode.el b/tw/home/files/emacs-packages/vcard-mode.el new file mode 100644 index 00000000..a932477a --- /dev/null +++ b/tw/home/files/emacs-packages/vcard-mode.el @@ -0,0 +1,56 @@ +;;; vcard-mode.el --- Major mode for vCard files. + +;; Copyright (C) 2012 Desmond O. Chang + +;; Author: Desmond O. Chang <dochang@gmail.com> +;; Version: 0.1.0 +;; Keywords: files + +;; 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 of the License, 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. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; This package provides a major mode to edit vCard files. + +;; To install it, put this file under your load path. Then add the +;; following to your .emacs file: + +;; (require 'vcard-mode) + +;; Or if you don't want to load it until editing a vCard file: + +;; (autoload 'vcard-mode "vcard-mode" "Major mode for vCard files" t) +;; (add-to-list 'auto-mode-alist '("\\.vc\\(f\\|ard\\)\\'" . vcard-mode)) + +;;; Code: + +(require 'generic) + +(defun vcard-mode-init () + (set (make-local-variable 'paragraph-start) "BEGIN:VCARD")) + +;;;###autoload +(define-generic-mode vcard-mode + '() + nil + '(("^BEGIN:VCARD" . font-lock-function-name-face) + (";[^:\n]+:" . font-lock-type-face) + ("^\\([^;:\n]+\\):?" . font-lock-keyword-face)) + '("\\.\\(vcf\\|vcard\\)\\'") + '(vcard-mode-init) + "Generic mode for vCard files.") + +(provide 'vcard-mode) + +;;; vcard-mode.el ends here |