From: Andreas Gerler Date: Thu, 31 Oct 2019 16:08:08 +0000 (+0100) Subject: update yaml-mode X-Git-Url: http://git.bundesbrandschatzamt.de/?a=commitdiff_plain;h=43cd3f682a97d3328a108fde8146d3d340a7b63e;p=emacsconfig.git update yaml-mode --- diff --git a/bba.org b/bba.org index b7ee5831..a5a0493f 100644 --- a/bba.org +++ b/bba.org @@ -270,7 +270,6 @@ Keep track of your important stuff! (progn (add-to-list 'load-path "~/.emacs.d/elpa/cl-lib-0.5") (add-to-list 'load-path "~/.emacs.d/elpa/magit-1.2.0") - (add-to-list 'load-path "~/.emacs.d/elpa/yaml-mode-20160220.340") (require 'yaml-mode) ) diff --git a/elpa/yaml-mode-20180409.607/yaml-mode-autoloads.el b/elpa/yaml-mode-20180409.607/yaml-mode-autoloads.el deleted file mode 100644 index fa9bb779..00000000 --- a/elpa/yaml-mode-20180409.607/yaml-mode-autoloads.el +++ /dev/null @@ -1,33 +0,0 @@ -;;; yaml-mode-autoloads.el --- automatically extracted autoloads -;; -;;; Code: - -(add-to-list 'load-path (directory-file-name - (or (file-name-directory #$) (car load-path)))) - - -;;;### (autoloads nil "yaml-mode" "yaml-mode.el" (0 0 0 0)) -;;; Generated autoloads from yaml-mode.el - -(let ((loads (get 'yaml 'custom-loads))) (if (member '"yaml-mode" loads) nil (put 'yaml 'custom-loads (cons '"yaml-mode" loads)))) - -(autoload 'yaml-mode "yaml-mode" "\ -Simple mode to edit YAML. - -\\{yaml-mode-map} - -\(fn)" t nil) - -(add-to-list 'auto-mode-alist '("\\.\\(e?ya?\\|ra\\)ml\\'" . yaml-mode)) - -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "yaml-mode" '("yaml-"))) - -;;;*** - -;; Local Variables: -;; version-control: never -;; no-byte-compile: t -;; no-update-autoloads: t -;; coding: utf-8 -;; End: -;;; yaml-mode-autoloads.el ends here diff --git a/elpa/yaml-mode-20180409.607/yaml-mode-pkg.el b/elpa/yaml-mode-20180409.607/yaml-mode-pkg.el deleted file mode 100644 index 3b278865..00000000 --- a/elpa/yaml-mode-20180409.607/yaml-mode-pkg.el +++ /dev/null @@ -1,2 +0,0 @@ -;;; -*- no-byte-compile: t -*- -(define-package "yaml-mode" "20180409.607" "Major mode for editing YAML files" '((emacs "24.1")) :commit "40067a10ac1360f0b9533f0bbbb2eea128e2574d" :keywords '("data" "yaml") :authors '(("Yoshiki Kurihara" . "clouder@gmail.com") ("Marshall T. Vandegrift" . "llasram@gmail.com")) :maintainer '("Vasilij Schneidermann" . "v.schneidermann@gmail.com")) diff --git a/elpa/yaml-mode-20180409.607/yaml-mode.el b/elpa/yaml-mode-20180409.607/yaml-mode.el deleted file mode 100644 index 455fa269..00000000 --- a/elpa/yaml-mode-20180409.607/yaml-mode.el +++ /dev/null @@ -1,472 +0,0 @@ -;;; yaml-mode.el --- Major mode for editing YAML files - -;; Copyright (C) 2010-2014 Yoshiki Kurihara - -;; Author: Yoshiki Kurihara -;; Marshall T. Vandegrift -;; Maintainer: Vasilij Schneidermann -;; Package-Requires: ((emacs "24.1")) -;; Package-Version: 20180409.607 -;; Keywords: data yaml -;; Version: 0.0.13 - -;; This file is not part of Emacs - -;; This file 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 file 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, write to the Free Software Foundation, Inc., -;; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -;;; Commentary: - -;; This is a major mode for editing files in the YAML data -;; serialization format. It was initially developed by Yoshiki -;; Kurihara and many features were added by Marshall Vandegrift. As -;; YAML and Python share the fact that indentation determines -;; structure, this mode provides indentation and indentation command -;; behavior very similar to that of python-mode. - -;;; Installation: - -;; To install, just drop this file into a directory in your -;; `load-path' and (optionally) byte-compile it. To automatically -;; handle files ending in '.yml', add something like: -;; -;; (require 'yaml-mode) -;; (add-to-list 'auto-mode-alist '("\\.yml\\'" . yaml-mode)) -;; -;; to your .emacs file. -;; -;; Unlike python-mode, this mode follows the Emacs convention of not -;; binding the ENTER key to `newline-and-indent'. To get this -;; behavior, add the key definition to `yaml-mode-hook': -;; -;; (add-hook 'yaml-mode-hook -;; '(lambda () -;; (define-key yaml-mode-map "\C-m" 'newline-and-indent))) - -;;; Known Bugs: - -;; YAML is easy to write but complex to parse, and this mode doesn't -;; even really try. Indentation and highlighting will break on -;; abnormally complicated structures. - -;;; Code: - - -;; User definable variables - -;;;###autoload -(defgroup yaml nil - "Support for the YAML serialization format" - :group 'languages - :prefix "yaml-") - -(defcustom yaml-mode-hook nil - "*Hook run by `yaml-mode'." - :type 'hook - :group 'yaml) - -(defcustom yaml-indent-offset 2 - "*Amount of offset per level of indentation." - :type 'integer - :safe 'natnump - :group 'yaml) - -(defcustom yaml-backspace-function 'backward-delete-char-untabify - "*Function called by `yaml-electric-backspace' when deleting backwards. -It will receive one argument, the numeric prefix value." - :type 'function - :group 'yaml) - -(defcustom yaml-block-literal-search-lines 100 - "*Maximum number of lines to search for start of block literals." - :type 'integer - :group 'yaml) - -(defcustom yaml-block-literal-electric-alist - '((?| . "") (?> . "-")) - "*Characters for which to provide electric behavior. -The association list key should be a key code and the associated value -should be a string containing additional characters to insert when -that key is pressed to begin a block literal." - :type 'alist - :group 'yaml) - -(defface yaml-tab-face - '((((class color)) (:background "red" :foreground "red" :bold t)) - (t (:reverse-video t))) - "Face to use for highlighting tabs in YAML files." - :group 'faces - :group 'yaml) - -(defcustom yaml-imenu-generic-expression - '((nil "^\\(:?[a-zA-Z_-]+\\):" 1)) - "The imenu regex to parse an outline of the yaml file." - :type 'string - :group 'yaml) - - -;; Constants - -(defconst yaml-mode-version "0.0.13" "Version of `yaml-mode'.") - -(defconst yaml-blank-line-re "^ *$" - "Regexp matching a line containing only (valid) whitespace.") - -(defconst yaml-directive-re "^\\(?:--- \\)? *%\\(\\w+\\)" - "Regexp matching a line contatining a YAML directive.") - -(defconst yaml-document-delimiter-re "^\\(?:---\\|[.][.][.]\\)" - "Rexexp matching a YAML document delimiter line.") - -(defconst yaml-node-anchor-alias-re "[&*][a-zA-Z0-9_-]+" - "Regexp matching a YAML node anchor or alias.") - -(defconst yaml-tag-re "!!?[^ \n]+" - "Rexexp matching a YAML tag.") - -(defconst yaml-bare-scalar-re - "\\(?:[^-:,#!\n{\\[ ]\\|[^#!\n{\\[ ]\\S-\\)[^#\n]*?" - "Rexexp matching a YAML bare scalar.") - -(defconst yaml-hash-key-re - (concat "\\(?:^\\(?:--- \\)?\\|{\\|\\(?:[-,] +\\)+\\) *" - "\\(?:" yaml-tag-re " +\\)?" - "\\(" yaml-bare-scalar-re "\\) *:" - "\\(?: +\\|$\\)") - "Regexp matching a single YAML hash key.") - -(defconst yaml-scalar-context-re - (concat "\\(?:^\\(?:--- \\)?\\|{\\|\\(?: *[-,] +\\)+\\) *" - "\\(?:" yaml-bare-scalar-re " *: \\)?") - "Regexp indicating the beginning of a scalar context.") - -(defconst yaml-nested-map-re - (concat ".*: *\\(?:&.*\\|{ *\\|" yaml-tag-re " *\\)?$") - "Regexp matching a line beginning a YAML nested structure.") - -(defconst yaml-block-literal-base-re " *[>|][-+0-9]* *\\(?:\n\\|\\'\\)" - "Regexp matching the substring start of a block literal.") - -(defconst yaml-block-literal-re - (concat yaml-scalar-context-re - "\\(?:" yaml-tag-re "\\)?" - yaml-block-literal-base-re) - "Regexp matching a line beginning a YAML block literal.") - -(defconst yaml-nested-sequence-re - (concat "^\\(?:\\(?: *- +\\)+\\|\\(:? *-$\\)\\)" - "\\(?:" yaml-bare-scalar-re " *:\\(?: +.*\\)?\\)?$") - "Regexp matching a line containing one or more nested YAML sequences.") - -(defconst yaml-constant-scalars-re - (concat "\\(?:^\\|\\(?::\\|-\\|,\\|{\\|\\[\\) +\\) *" - (regexp-opt - '("~" "null" "Null" "NULL" - ".nan" ".NaN" ".NAN" - ".inf" ".Inf" ".INF" - "-.inf" "-.Inf" "-.INF" - "y" "Y" "yes" "Yes" "YES" "n" "N" "no" "No" "NO" - "true" "True" "TRUE" "false" "False" "FALSE" - "on" "On" "ON" "off" "Off" "OFF") t) - " *$") - "Regexp matching certain scalar constants in scalar context.") - - -;; Mode setup - -(defvar yaml-mode-map - (let ((map (make-sparse-keymap))) - (define-key map "|" 'yaml-electric-bar-and-angle) - (define-key map ">" 'yaml-electric-bar-and-angle) - (define-key map "-" 'yaml-electric-dash-and-dot) - (define-key map "." 'yaml-electric-dash-and-dot) - (define-key map (kbd "DEL") 'yaml-electric-backspace) - map) - "Keymap used in `yaml-mode' buffers.") - -(defvar yaml-mode-syntax-table - (let ((syntax-table (make-syntax-table))) - (modify-syntax-entry ?\' "\"" syntax-table) - (modify-syntax-entry ?\" "\"" syntax-table) - (modify-syntax-entry ?# "<" syntax-table) - (modify-syntax-entry ?\n ">" syntax-table) - (modify-syntax-entry ?\\ "\\" syntax-table) - (modify-syntax-entry ?- "_" syntax-table) - (modify-syntax-entry ?_ "_" syntax-table) - (modify-syntax-entry ?& "." syntax-table) - (modify-syntax-entry ?* "." syntax-table) - (modify-syntax-entry ?\( "." syntax-table) - (modify-syntax-entry ?\) "." syntax-table) - (modify-syntax-entry ?\{ "(}" syntax-table) - (modify-syntax-entry ?\} "){" syntax-table) - (modify-syntax-entry ?\[ "(]" syntax-table) - (modify-syntax-entry ?\] ")[" syntax-table) - syntax-table) - "Syntax table in use in `yaml-mode' buffers.") - -;;;###autoload -(define-derived-mode yaml-mode text-mode "YAML" - "Simple mode to edit YAML. - -\\{yaml-mode-map}" - :syntax-table yaml-mode-syntax-table - (set (make-local-variable 'comment-start) "# ") - (set (make-local-variable 'comment-start-skip) "#+ *") - (set (make-local-variable 'indent-line-function) 'yaml-indent-line) - (set (make-local-variable 'indent-tabs-mode) nil) - (set (make-local-variable 'fill-paragraph-function) 'yaml-fill-paragraph) - - (set (make-local-variable 'syntax-propertize-function) - 'yaml-mode-syntax-propertize-function) - (setq font-lock-defaults '(yaml-font-lock-keywords))) - - -;; Font-lock support - -(defvar yaml-font-lock-keywords - `((yaml-font-lock-block-literals 0 font-lock-string-face) - (,yaml-constant-scalars-re . (1 font-lock-constant-face)) - (,yaml-tag-re . (0 font-lock-type-face)) - (,yaml-node-anchor-alias-re . (0 font-lock-function-name-face)) - (,yaml-hash-key-re . (1 font-lock-variable-name-face)) - (,yaml-document-delimiter-re . (0 font-lock-comment-face)) - (,yaml-directive-re . (1 font-lock-builtin-face)) - ("^[\t]+" 0 'yaml-tab-face t)) - "Additional expressions to highlight in YAML mode.") - -(defun yaml-mode-syntax-propertize-function (beg end) - "Override buffer's syntax table for special syntactic constructs." - ;; Unhighlight foo#bar tokens between BEG and END. - (save-excursion - (goto-char beg) - (while (search-forward "#" end t) - (save-excursion - (forward-char -1) - ;; both ^# and [ \t]# are comments - (when (and (not (bolp)) - (not (memq (preceding-char) '(?\s ?\t)))) - (put-text-property (point) (1+ (point)) - 'syntax-table (string-to-syntax "_")))))) - - ;; If quote is detected as a syntactic string start but appeared - ;; after a non-whitespace character, then mark it as syntactic word. - (save-excursion - (goto-char beg) - (while (re-search-forward "['\"]" end t) - (when (get-text-property (point) 'yaml-block-literal) - (put-text-property (1- (point)) (point) - 'syntax-table (string-to-syntax "w"))) - (when (nth 8 (syntax-ppss)) - (save-excursion - (forward-char -1) - (cond ((and (char-equal ?' (char-before (point))) - (char-equal ?' (char-after (point))) - (put-text-property (1- (point)) (1+ (point)) - 'syntax-table (string-to-syntax "w")))) - ((and (not (bolp)) - (char-equal ?w (char-syntax (char-before (point))))) - (put-text-property (point) (1+ (point)) - 'syntax-table (string-to-syntax "w"))))))))) - -(defun yaml-font-lock-block-literals (bound) - "Find lines within block literals. -Find the next line of the first (if any) block literal after point and -prior to BOUND. Returns the beginning and end of the block literal -line in the match data, as consumed by `font-lock-keywords' matcher -functions. The function begins by searching backwards to determine -whether or not the current line is within a block literal. This could -be time-consuming in large buffers, so the number of lines searched is -artificially limitted to the value of -`yaml-block-literal-search-lines'." - (if (eolp) (goto-char (1+ (point)))) - (unless (or (eobp) (>= (point) bound)) - (let ((begin (point)) - (end (min (1+ (point-at-eol)) bound))) - (goto-char (point-at-bol)) - (while (and (looking-at yaml-blank-line-re) - (not (bobp))) - (forward-line -1)) - (let ((nlines yaml-block-literal-search-lines) - (min-level (current-indentation))) - (forward-line -1) - (while (and (/= nlines 0) - (/= min-level 0) - (not (looking-at yaml-block-literal-re)) - (not (bobp))) - (setq nlines (1- nlines)) - (unless (looking-at yaml-blank-line-re) - (setq min-level (min min-level (current-indentation)))) - (forward-line -1)) - (cond - ((and (< (current-indentation) min-level) - (looking-at yaml-block-literal-re)) - (goto-char end) - (put-text-property begin end 'yaml-block-literal t) - (set-match-data (list begin end)) - t) - ((progn - (goto-char begin) - (re-search-forward (concat yaml-block-literal-re - " *\\(.*\\)\n") - bound t)) - (let ((range (nthcdr 2 (match-data)))) - (put-text-property (car range) (cadr range) 'yaml-block-literal t) - (set-match-data range)) - t)))))) - - -;; Indentation and electric keys - -(defun yaml-compute-indentation () - "Calculate the maximum sensible indentation for the current line." - (save-excursion - (beginning-of-line) - (if (looking-at yaml-document-delimiter-re) 0 - (forward-line -1) - (while (and (looking-at yaml-blank-line-re) - (> (point) (point-min))) - (forward-line -1)) - (+ (current-indentation) - (if (looking-at yaml-nested-map-re) yaml-indent-offset 0) - (if (looking-at yaml-nested-sequence-re) yaml-indent-offset 0) - (if (looking-at yaml-block-literal-re) yaml-indent-offset 0))))) - -(defun yaml-indent-line () - "Indent the current line. -The first time this command is used, the line will be indented to the -maximum sensible indentation. Each immediately subsequent usage will -back-dent the line by `yaml-indent-offset' spaces. On reaching column -0, it will cycle back to the maximum sensible indentation." - (interactive "*") - (let ((ci (current-indentation)) - (cc (current-column)) - (need (yaml-compute-indentation))) - (save-excursion - (beginning-of-line) - (delete-horizontal-space) - (if (and (equal last-command this-command) (/= ci 0)) - (indent-to (* (/ (- ci 1) yaml-indent-offset) yaml-indent-offset)) - (indent-to need))) - (if (< (current-column) (current-indentation)) - (forward-to-indentation 0)))) - -(defun yaml-electric-backspace (arg) - "Delete characters or back-dent the current line. -If invoked following only whitespace on a line, will back-dent to the -immediately previous multiple of `yaml-indent-offset' spaces." - (interactive "*p") - (if (or (/= (current-indentation) (current-column)) (bolp)) - (funcall yaml-backspace-function arg) - (let ((ci (current-column))) - (beginning-of-line) - (delete-horizontal-space) - (indent-to (* (/ (- ci (* arg yaml-indent-offset)) - yaml-indent-offset) - yaml-indent-offset))))) - -(defun yaml-electric-bar-and-angle (arg) - "Insert the bound key and possibly begin a block literal. -Inserts the bound key. If inserting the bound key causes the current -line to match the initial line of a block literal, then inserts the -matching string from `yaml-block-literal-electric-alist', a newline, -and indents appropriately." - (interactive "*P") - (self-insert-command (prefix-numeric-value arg)) - (let ((extra-chars - (assoc last-command-event - yaml-block-literal-electric-alist))) - (cond - ((and extra-chars (not arg) (eolp) - (save-excursion - (beginning-of-line) - (looking-at yaml-block-literal-re))) - (insert (cdr extra-chars)) - (newline-and-indent))))) - -(defun yaml-electric-dash-and-dot (arg) - "Insert the bound key and possibly de-dent line. -Inserts the bound key. If inserting the bound key causes the current -line to match a document delimiter, de-dent the line to the left -margin." - (interactive "*P") - (self-insert-command (prefix-numeric-value arg)) - (save-excursion - (beginning-of-line) - (when (and (not arg) (looking-at yaml-document-delimiter-re)) - (delete-horizontal-space)))) - -(defun yaml-narrow-to-block-literal () - "Narrow the buffer to block literal if the point is in it, -otherwise do nothing." - (interactive) - (save-excursion - (goto-char (point-at-bol)) - (while (and (looking-at-p yaml-blank-line-re) (not (bobp))) - (forward-line -1)) - (let ((nlines yaml-block-literal-search-lines) - (min-level (current-indentation)) - beg) - (forward-line -1) - (while (and (/= nlines 0) - (/= min-level 0) - (not (looking-at-p yaml-block-literal-re)) - (not (bobp))) - (setq nlines (1- nlines)) - (unless (looking-at-p yaml-blank-line-re) - (setq min-level (min min-level (current-indentation)))) - (forward-line -1)) - (when (and (< (current-indentation) min-level) - (looking-at-p yaml-block-literal-re)) - (setq min-level (current-indentation)) - (forward-line) - (setq beg (point)) - (while (and (not (eobp)) - (or (looking-at-p yaml-blank-line-re) - (> (current-indentation) min-level))) - (forward-line)) - (narrow-to-region beg (point)))))) - -(defun yaml-fill-paragraph (&optional justify region) - "Fill paragraph. -Outside of comments, this behaves as `fill-paragraph' except that -filling does not cross boundaries of block literals. Inside comments, -this will do usual adaptive fill behaviors." - (interactive "*P") - (save-restriction - (yaml-narrow-to-block-literal) - (let ((fill-paragraph-function nil)) - (or (fill-comment-paragraph justify) - (fill-paragraph justify region))))) - -(defun yaml-set-imenu-generic-expression () - (make-local-variable 'imenu-generic-expression) - (make-local-variable 'imenu-create-index-function) - (setq imenu-create-index-function 'imenu-default-create-index-function) - (setq imenu-generic-expression yaml-imenu-generic-expression)) - -(add-hook 'yaml-mode-hook 'yaml-set-imenu-generic-expression) - - -(defun yaml-mode-version () - "Display version of `yaml-mode'." - (interactive) - (message "yaml-mode %s" yaml-mode-version) - yaml-mode-version) - -;;;###autoload -(add-to-list 'auto-mode-alist '("\\.\\(e?ya?\\|ra\\)ml\\'" . yaml-mode)) - -(provide 'yaml-mode) - -;;; yaml-mode.el ends here diff --git a/elpa/yaml-mode-20190625.1740/yaml-mode-autoloads.el b/elpa/yaml-mode-20190625.1740/yaml-mode-autoloads.el new file mode 100644 index 00000000..43b82f1e --- /dev/null +++ b/elpa/yaml-mode-20190625.1740/yaml-mode-autoloads.el @@ -0,0 +1,28 @@ +;;; yaml-mode-autoloads.el --- automatically extracted autoloads +;; +;;; Code: +(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path)))) + +;;;### (autoloads nil "yaml-mode" "yaml-mode.el" (23994 46372 771381 +;;;;;; 305000)) +;;; Generated autoloads from yaml-mode.el + +(let ((loads (get 'yaml 'custom-loads))) (if (member '"yaml-mode" loads) nil (put 'yaml 'custom-loads (cons '"yaml-mode" loads)))) + +(autoload 'yaml-mode "yaml-mode" "\ +Simple mode to edit YAML. + +\\{yaml-mode-map} + +\(fn)" t nil) + +(add-to-list 'auto-mode-alist '("\\.\\(e?ya?\\|ra\\)ml\\'" . yaml-mode)) + +;;;*** + +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; End: +;;; yaml-mode-autoloads.el ends here diff --git a/elpa/yaml-mode-20190625.1740/yaml-mode-pkg.el b/elpa/yaml-mode-20190625.1740/yaml-mode-pkg.el new file mode 100644 index 00000000..dc9e8d48 --- /dev/null +++ b/elpa/yaml-mode-20190625.1740/yaml-mode-pkg.el @@ -0,0 +1,2 @@ +;;; -*- no-byte-compile: t -*- +(define-package "yaml-mode" "20190625.1740" "Major mode for editing YAML files" '((emacs "24.1")) :commit "5b4a0db384f996554454b5642e4531c502421de8" :keywords '("data" "yaml") :authors '(("Yoshiki Kurihara" . "clouder@gmail.com") ("Marshall T. Vandegrift" . "llasram@gmail.com")) :maintainer '("Vasilij Schneidermann" . "v.schneidermann@gmail.com")) diff --git a/elpa/yaml-mode-20190625.1740/yaml-mode.el b/elpa/yaml-mode-20190625.1740/yaml-mode.el new file mode 100644 index 00000000..6ec99cca --- /dev/null +++ b/elpa/yaml-mode-20190625.1740/yaml-mode.el @@ -0,0 +1,472 @@ +;;; yaml-mode.el --- Major mode for editing YAML files + +;; Copyright (C) 2010-2014 Yoshiki Kurihara + +;; Author: Yoshiki Kurihara +;; Marshall T. Vandegrift +;; Maintainer: Vasilij Schneidermann +;; Package-Requires: ((emacs "24.1")) +;; Package-Version: 20190625.1740 +;; Keywords: data yaml +;; Version: 0.0.14 + +;; This file is not part of Emacs + +;; This file 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 file 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, write to the Free Software Foundation, Inc., +;; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +;;; Commentary: + +;; This is a major mode for editing files in the YAML data +;; serialization format. It was initially developed by Yoshiki +;; Kurihara and many features were added by Marshall Vandegrift. As +;; YAML and Python share the fact that indentation determines +;; structure, this mode provides indentation and indentation command +;; behavior very similar to that of python-mode. + +;;; Installation: + +;; To install, just drop this file into a directory in your +;; `load-path' and (optionally) byte-compile it. To automatically +;; handle files ending in '.yml', add something like: +;; +;; (require 'yaml-mode) +;; (add-to-list 'auto-mode-alist '("\\.yml\\'" . yaml-mode)) +;; +;; to your .emacs file. +;; +;; Unlike python-mode, this mode follows the Emacs convention of not +;; binding the ENTER key to `newline-and-indent'. To get this +;; behavior, add the key definition to `yaml-mode-hook': +;; +;; (add-hook 'yaml-mode-hook +;; '(lambda () +;; (define-key yaml-mode-map "\C-m" 'newline-and-indent))) + +;;; Known Bugs: + +;; YAML is easy to write but complex to parse, and this mode doesn't +;; even really try. Indentation and highlighting will break on +;; abnormally complicated structures. + +;;; Code: + + +;; User definable variables + +;;;###autoload +(defgroup yaml nil + "Support for the YAML serialization format" + :group 'languages + :prefix "yaml-") + +(defcustom yaml-mode-hook nil + "*Hook run by `yaml-mode'." + :type 'hook + :group 'yaml) + +(defcustom yaml-indent-offset 2 + "*Amount of offset per level of indentation." + :type 'integer + :safe 'natnump + :group 'yaml) + +(defcustom yaml-backspace-function 'backward-delete-char-untabify + "*Function called by `yaml-electric-backspace' when deleting backwards. +It will receive one argument, the numeric prefix value." + :type 'function + :group 'yaml) + +(defcustom yaml-block-literal-search-lines 100 + "*Maximum number of lines to search for start of block literals." + :type 'integer + :group 'yaml) + +(defcustom yaml-block-literal-electric-alist + '((?| . "") (?> . "-")) + "*Characters for which to provide electric behavior. +The association list key should be a key code and the associated value +should be a string containing additional characters to insert when +that key is pressed to begin a block literal." + :type 'alist + :group 'yaml) + +(defface yaml-tab-face + '((((class color)) (:background "red" :foreground "red" :bold t)) + (t (:reverse-video t))) + "Face to use for highlighting tabs in YAML files." + :group 'faces + :group 'yaml) + +(defcustom yaml-imenu-generic-expression + '((nil "^\\(:?[a-zA-Z_-]+\\):" 1)) + "The imenu regex to parse an outline of the yaml file." + :type 'string + :group 'yaml) + + +;; Constants + +(defconst yaml-mode-version "0.0.14" "Version of `yaml-mode'.") + +(defconst yaml-blank-line-re "^ *$" + "Regexp matching a line containing only (valid) whitespace.") + +(defconst yaml-directive-re "^\\(?:--- \\)? *%\\(\\w+\\)" + "Regexp matching a line contatining a YAML directive.") + +(defconst yaml-document-delimiter-re "^\\(?:---\\|[.][.][.]\\)" + "Rexexp matching a YAML document delimiter line.") + +(defconst yaml-node-anchor-alias-re "[&*][a-zA-Z0-9_-]+" + "Regexp matching a YAML node anchor or alias.") + +(defconst yaml-tag-re "!!?[^ \n]+" + "Rexexp matching a YAML tag.") + +(defconst yaml-bare-scalar-re + "\\(?:[^-:,#!\n{\\[ ]\\|[^#!\n{\\[ ]\\S-\\)[^#\n]*?" + "Rexexp matching a YAML bare scalar.") + +(defconst yaml-hash-key-re + (concat "\\(?:^\\(?:--- \\)?\\|{\\|\\(?:[-,] +\\)+\\) *" + "\\(?:" yaml-tag-re " +\\)?" + "\\(" yaml-bare-scalar-re "\\) *:" + "\\(?: +\\|$\\)") + "Regexp matching a single YAML hash key.") + +(defconst yaml-scalar-context-re + (concat "\\(?:^\\(?:--- \\)?\\|{\\|\\(?: *[-,] +\\)+\\) *" + "\\(?:" yaml-bare-scalar-re " *: \\)?") + "Regexp indicating the beginning of a scalar context.") + +(defconst yaml-nested-map-re + (concat ".*: *\\(?:&.*\\|{ *\\|" yaml-tag-re " *\\)?$") + "Regexp matching a line beginning a YAML nested structure.") + +(defconst yaml-block-literal-base-re " *[>|][-+0-9]* *\\(?:\n\\|\\'\\)" + "Regexp matching the substring start of a block literal.") + +(defconst yaml-block-literal-re + (concat yaml-scalar-context-re + "\\(?:" yaml-tag-re "\\)?" + yaml-block-literal-base-re) + "Regexp matching a line beginning a YAML block literal.") + +(defconst yaml-nested-sequence-re + (concat "^\\(?:\\(?: *- +\\)+\\|\\(:? *-$\\)\\)" + "\\(?:" yaml-bare-scalar-re " *:\\(?: +.*\\)?\\)?$") + "Regexp matching a line containing one or more nested YAML sequences.") + +(defconst yaml-constant-scalars-re + (concat "\\(?:^\\|\\(?::\\|-\\|,\\|{\\|\\[\\) +\\) *" + (regexp-opt + '("~" "null" "Null" "NULL" + ".nan" ".NaN" ".NAN" + ".inf" ".Inf" ".INF" + "-.inf" "-.Inf" "-.INF" + "y" "Y" "yes" "Yes" "YES" "n" "N" "no" "No" "NO" + "true" "True" "TRUE" "false" "False" "FALSE" + "on" "On" "ON" "off" "Off" "OFF") t) + " *$") + "Regexp matching certain scalar constants in scalar context.") + + +;; Mode setup + +(defvar yaml-mode-map + (let ((map (make-sparse-keymap))) + (define-key map "|" 'yaml-electric-bar-and-angle) + (define-key map ">" 'yaml-electric-bar-and-angle) + (define-key map "-" 'yaml-electric-dash-and-dot) + (define-key map "." 'yaml-electric-dash-and-dot) + (define-key map (kbd "DEL") 'yaml-electric-backspace) + map) + "Keymap used in `yaml-mode' buffers.") + +(defvar yaml-mode-syntax-table + (let ((syntax-table (make-syntax-table))) + (modify-syntax-entry ?\' "\"" syntax-table) + (modify-syntax-entry ?\" "\"" syntax-table) + (modify-syntax-entry ?# "<" syntax-table) + (modify-syntax-entry ?\n ">" syntax-table) + (modify-syntax-entry ?\\ "\\" syntax-table) + (modify-syntax-entry ?- "_" syntax-table) + (modify-syntax-entry ?_ "_" syntax-table) + (modify-syntax-entry ?& "." syntax-table) + (modify-syntax-entry ?* "." syntax-table) + (modify-syntax-entry ?\( "." syntax-table) + (modify-syntax-entry ?\) "." syntax-table) + (modify-syntax-entry ?\{ "(}" syntax-table) + (modify-syntax-entry ?\} "){" syntax-table) + (modify-syntax-entry ?\[ "(]" syntax-table) + (modify-syntax-entry ?\] ")[" syntax-table) + syntax-table) + "Syntax table in use in `yaml-mode' buffers.") + +;;;###autoload +(define-derived-mode yaml-mode text-mode "YAML" + "Simple mode to edit YAML. + +\\{yaml-mode-map}" + :syntax-table yaml-mode-syntax-table + (set (make-local-variable 'comment-start) "# ") + (set (make-local-variable 'comment-start-skip) "#+ *") + (set (make-local-variable 'indent-line-function) 'yaml-indent-line) + (set (make-local-variable 'indent-tabs-mode) nil) + (set (make-local-variable 'fill-paragraph-function) 'yaml-fill-paragraph) + + (set (make-local-variable 'syntax-propertize-function) + 'yaml-mode-syntax-propertize-function) + (setq font-lock-defaults '(yaml-font-lock-keywords))) + + +;; Font-lock support + +(defvar yaml-font-lock-keywords + `((yaml-font-lock-block-literals 0 font-lock-string-face) + (,yaml-constant-scalars-re . (1 font-lock-constant-face)) + (,yaml-tag-re . (0 font-lock-type-face)) + (,yaml-node-anchor-alias-re . (0 font-lock-function-name-face)) + (,yaml-hash-key-re . (1 font-lock-variable-name-face)) + (,yaml-document-delimiter-re . (0 font-lock-comment-face)) + (,yaml-directive-re . (1 font-lock-builtin-face)) + ("^[\t]+" 0 'yaml-tab-face t)) + "Additional expressions to highlight in YAML mode.") + +(defun yaml-mode-syntax-propertize-function (beg end) + "Override buffer's syntax table for special syntactic constructs." + ;; Unhighlight foo#bar tokens between BEG and END. + (save-excursion + (goto-char beg) + (while (search-forward "#" end t) + (save-excursion + (forward-char -1) + ;; both ^# and [ \t]# are comments + (when (and (not (bolp)) + (not (memq (preceding-char) '(?\s ?\t)))) + (put-text-property (point) (1+ (point)) + 'syntax-table (string-to-syntax "_")))))) + + ;; If quote is detected as a syntactic string start but appeared + ;; after a non-whitespace character, then mark it as syntactic word. + (save-excursion + (goto-char beg) + (while (re-search-forward "['\"]" end t) + (when (get-text-property (point) 'yaml-block-literal) + (put-text-property (1- (point)) (point) + 'syntax-table (string-to-syntax "w"))) + (when (nth 8 (syntax-ppss)) + (save-excursion + (forward-char -1) + (cond ((and (char-equal ?' (char-before (point))) + (char-equal ?' (char-after (point))) + (put-text-property (1- (point)) (1+ (point)) + 'syntax-table (string-to-syntax "w")))) + ((and (not (bolp)) + (char-equal ?w (char-syntax (char-before (point))))) + (put-text-property (point) (1+ (point)) + 'syntax-table (string-to-syntax "w"))))))))) + +(defun yaml-font-lock-block-literals (bound) + "Find lines within block literals. +Find the next line of the first (if any) block literal after point and +prior to BOUND. Returns the beginning and end of the block literal +line in the match data, as consumed by `font-lock-keywords' matcher +functions. The function begins by searching backwards to determine +whether or not the current line is within a block literal. This could +be time-consuming in large buffers, so the number of lines searched is +artificially limitted to the value of +`yaml-block-literal-search-lines'." + (if (eolp) (goto-char (1+ (point)))) + (unless (or (eobp) (>= (point) bound)) + (let ((begin (point)) + (end (min (1+ (point-at-eol)) bound))) + (goto-char (point-at-bol)) + (while (and (looking-at yaml-blank-line-re) + (not (bobp))) + (forward-line -1)) + (let ((nlines yaml-block-literal-search-lines) + (min-level (current-indentation))) + (forward-line -1) + (while (and (/= nlines 0) + (/= min-level 0) + (not (looking-at yaml-block-literal-re)) + (not (bobp))) + (setq nlines (1- nlines)) + (unless (looking-at yaml-blank-line-re) + (setq min-level (min min-level (current-indentation)))) + (forward-line -1)) + (cond + ((and (< (current-indentation) min-level) + (looking-at yaml-block-literal-re)) + (goto-char end) + (put-text-property begin end 'yaml-block-literal t) + (set-match-data (list begin end)) + t) + ((progn + (goto-char begin) + (re-search-forward (concat yaml-block-literal-re + " *\\(.*\\)\n") + bound t)) + (let ((range (nthcdr 2 (match-data)))) + (put-text-property (car range) (cadr range) 'yaml-block-literal t) + (set-match-data range)) + t)))))) + + +;; Indentation and electric keys + +(defun yaml-compute-indentation () + "Calculate the maximum sensible indentation for the current line." + (save-excursion + (beginning-of-line) + (if (looking-at yaml-document-delimiter-re) 0 + (forward-line -1) + (while (and (looking-at yaml-blank-line-re) + (> (point) (point-min))) + (forward-line -1)) + (+ (current-indentation) + (if (looking-at yaml-nested-map-re) yaml-indent-offset 0) + (if (looking-at yaml-nested-sequence-re) yaml-indent-offset 0) + (if (looking-at yaml-block-literal-re) yaml-indent-offset 0))))) + +(defun yaml-indent-line () + "Indent the current line. +The first time this command is used, the line will be indented to the +maximum sensible indentation. Each immediately subsequent usage will +back-dent the line by `yaml-indent-offset' spaces. On reaching column +0, it will cycle back to the maximum sensible indentation." + (interactive "*") + (let ((ci (current-indentation)) + (cc (current-column)) + (need (yaml-compute-indentation))) + (save-excursion + (beginning-of-line) + (delete-horizontal-space) + (if (and (equal last-command this-command) (/= ci 0)) + (indent-to (* (/ (- ci 1) yaml-indent-offset) yaml-indent-offset)) + (indent-to need))) + (if (< (current-column) (current-indentation)) + (forward-to-indentation 0)))) + +(defun yaml-electric-backspace (arg) + "Delete characters or back-dent the current line. +If invoked following only whitespace on a line, will back-dent to the +immediately previous multiple of `yaml-indent-offset' spaces." + (interactive "*p") + (if (or (/= (current-indentation) (current-column)) (bolp)) + (funcall yaml-backspace-function arg) + (let ((ci (current-column))) + (beginning-of-line) + (delete-horizontal-space) + (indent-to (* (/ (- ci (* arg yaml-indent-offset)) + yaml-indent-offset) + yaml-indent-offset))))) + +(defun yaml-electric-bar-and-angle (arg) + "Insert the bound key and possibly begin a block literal. +Inserts the bound key. If inserting the bound key causes the current +line to match the initial line of a block literal, then inserts the +matching string from `yaml-block-literal-electric-alist', a newline, +and indents appropriately." + (interactive "*P") + (self-insert-command (prefix-numeric-value arg)) + (let ((extra-chars + (assoc last-command-event + yaml-block-literal-electric-alist))) + (cond + ((and extra-chars (not arg) (eolp) + (save-excursion + (beginning-of-line) + (looking-at yaml-block-literal-re))) + (insert (cdr extra-chars)) + (newline-and-indent))))) + +(defun yaml-electric-dash-and-dot (arg) + "Insert the bound key and possibly de-dent line. +Inserts the bound key. If inserting the bound key causes the current +line to match a document delimiter, de-dent the line to the left +margin." + (interactive "*P") + (self-insert-command (prefix-numeric-value arg)) + (save-excursion + (beginning-of-line) + (when (and (not arg) (looking-at yaml-document-delimiter-re)) + (delete-horizontal-space)))) + +(defun yaml-narrow-to-block-literal () + "Narrow the buffer to block literal if the point is in it, +otherwise do nothing." + (interactive) + (save-excursion + (goto-char (point-at-bol)) + (while (and (looking-at-p yaml-blank-line-re) (not (bobp))) + (forward-line -1)) + (let ((nlines yaml-block-literal-search-lines) + (min-level (current-indentation)) + beg) + (forward-line -1) + (while (and (/= nlines 0) + (/= min-level 0) + (not (looking-at-p yaml-block-literal-re)) + (not (bobp))) + (setq nlines (1- nlines)) + (unless (looking-at-p yaml-blank-line-re) + (setq min-level (min min-level (current-indentation)))) + (forward-line -1)) + (when (and (< (current-indentation) min-level) + (looking-at-p yaml-block-literal-re)) + (setq min-level (current-indentation)) + (forward-line) + (setq beg (point)) + (while (and (not (eobp)) + (or (looking-at-p yaml-blank-line-re) + (> (current-indentation) min-level))) + (forward-line)) + (narrow-to-region beg (point)))))) + +(defun yaml-fill-paragraph (&optional justify region) + "Fill paragraph. +Outside of comments, this behaves as `fill-paragraph' except that +filling does not cross boundaries of block literals. Inside comments, +this will do usual adaptive fill behaviors." + (interactive "*P") + (save-restriction + (yaml-narrow-to-block-literal) + (let ((fill-paragraph-function nil)) + (or (fill-comment-paragraph justify) + (fill-paragraph justify region))))) + +(defun yaml-set-imenu-generic-expression () + (make-local-variable 'imenu-generic-expression) + (make-local-variable 'imenu-create-index-function) + (setq imenu-create-index-function 'imenu-default-create-index-function) + (setq imenu-generic-expression yaml-imenu-generic-expression)) + +(add-hook 'yaml-mode-hook 'yaml-set-imenu-generic-expression) + + +(defun yaml-mode-version () + "Display version of `yaml-mode'." + (interactive) + (message "yaml-mode %s" yaml-mode-version) + yaml-mode-version) + +;;;###autoload +(add-to-list 'auto-mode-alist '("\\.\\(e?ya?\\|ra\\)ml\\'" . yaml-mode)) + +(provide 'yaml-mode) + +;;; yaml-mode.el ends here