yaml-pro is a package that provides conveniences for editing yaml.
This package has been written to leverage tree-sitter parsing facilities, allowing all of these actions to be performed fast and accurate, even in the absence of parsing errors. The tree-sitter version is orders of magnitudes faster and I highly recommend its usage if your Emacs version permits.
The latest version of yaml-pro contains tree-sitter support (activated
via yaml-pro-ts-mode
). In order to use this you will need to have a
version of Emacs installed that supports tree-sitter, as well as the
yaml tree-sitter parser from here:
https://github.com/ikatyang/tree-sitter-yaml . The tree-sitter
re-implementation supports everything below, as well as the following:
- yaml-pro-ts-meta-return (M-return): Add a new list
item after the current item, similar to
org-meta-return
. - yaml-pro-ts-convolute-tree (M-?): Swap the key of the current item's parent with that items parent.
- yaml-pro-ts-mark-subtree (C-c @): Mark the current YAML item. If given a prefix N, mark the Nth parent above. If called repeatedly, mark subsequent items.
- yaml-pro-ts-paste-subtree (C-c C-x C-y): Paste a YAML
subtree, fixing indentation to be correct for different levels.
When
yaml-pro-ts-yank-subtrees
is non-nil, yank will automatically callyaml-pro-ts-paste-subtree
for subtrees. - imenu: an index of all keys and their path are build for imenu
- eldoc: current path is shown as eldoc documentation. (enable
with
eldoc-mode
)
Note that folding is not implemented. I assume some tree-sitter folding library will come along which will unify this feature.
Note that all the functions are infixed with "-ts-" to distinguish the tree-sitter and non-tree-sitter variants.
New in yaml-pro, a pretty formatter in Emacs Lisp powered by treesitter.
Never have to consult https://yaml-multiline.info/ again! With
yaml-pro-edit-scalar
, you can edit a scalar value in a detached
buffer and convert between the various styles with ease.
You can use imenu as well.
This is not available for tree-sitter variant. Presumably some tree-sitter folding package will exist in the future.
To activate the mode, run M-x yaml-pro-ts-mode
. You can have this
activated automatically by adding this to your configuration:
(add-hook 'yaml-mode-hook 'yaml-pro-ts-mode 100)
(or 'yaml-ts-mode-hook
).
In order to run the tree-sitter version of this program, you should
have a version of Emacs that supports tree-sitter, as well as the yaml
tree-sitter library installed
(https://github.com/ikatyang/tree-sitter-yaml). Ex: having the file
libyaml.dylib
in /usr/local/lib
. With these in place,
(treesit-ready-p 'yaml)
should return t
.
- yaml-pro-format
- yaml-pro-ts-kill-subtree (C-c C-x C-w)
- yaml-pro-ts-up-level (C-c C-u)
- yaml-pro-ts-down-level (C-c C-d)
- yaml-pro-ts-next-subtree (C-c C-n)
- yaml-pro-ts-prev-subtree (C-c C-p)
- yaml-pro-ts-move-subtree-up (s-up)
- yaml-pro-ts-move-subtree-down (s-down)
- yaml-pro-ts-meta-return (M-)
- yaml-pro-ts-convolute-tree (M-?)
- yaml-pro-ts-indent-subtree (C-c >)
- yaml-pro-ts-unindent-subtree (C-c <)
- yaml-pro-ts-mark-subtree (C-c @)
- yaml-pro-ts-paste-subtree (C-c C-x C-y)
- yaml-pro-edit-ts-scalar (C-c ')
- (use prefix argument C-u to supply an initialization command to set major mode)
yaml-pro now comes with the addition of a new formatting command
yaml-pro-format
. This requires tree-sitter to work. There are
different settings you can toggle on the formatter. For ease of
customization I recommend usind M-x customize-variable.
The following is the customization options.
-
indent
When present, indent each line by `yaml-pro-indent'. -
reduce-newlines
When present, remove adjacent newlines so at most one one remains. New lines in strings won't be removed. -
oneline-flow
When present, reduce flow mappings to one line. -
block-formatting
When present, format the spacing around block components' colons and dashes. -
reduce-spaces
When present, attempt to reduce multiple adjacent space characters down to one. -
bm-fn-next-line
When present, move the value of a key-value pair to the next line, indented, if it's width is longer thanyaml-pro-format-print-width
. -
expand-log-flow
When present, flatten flow elements that pass columnyaml-pro-format-print-width
. -
single-to-double
When present, convert single quoted strings to double quoted, when it wouldn't change its meaning. -
remove-spaces-before-comments
When present, remove spaces before a comment until it is one space after the preceeding content (e.g. "a: b # space before here"). -
clean-doc-end
When present, remove unnecessary document-end indicators ("..."). -
document-separator-own-line
When present, makes sure the document separator "---" isn't on a line with another element.
With the following configuration and repeat-mode enabled, you can easily move around the YAML tree after executing one of the movement commands.
;; the original bindings will work as well, these are shorter if you prefer them.
(keymap-set yaml-pro-ts-mode-map "C-M-n" #'yaml-pro-ts-next-subtree)
(keymap-set yaml-pro-ts-mode-map "C-M-p" #'yaml-pro-ts-prev-subtree)
(keymap-set yaml-pro-ts-mode-map "C-M-u" #'yaml-pro-ts-up-level)
(keymap-set yaml-pro-ts-mode-map "C-M-d" #'yaml-pro-ts-down-level)
(keymap-set yaml-pro-ts-mode-map "C-M-k" #'yaml-pro-ts-kill-subtree)
(keymap-set yaml-pro-ts-mode-map "C-M-<backspace>" #'yaml-pro-ts-kill-subtree)
(keymap-set yaml-pro-ts-mode-map "C-M-a" #'yaml-pro-ts-first-sibling)
(keymap-set yaml-pro-ts-mode-map "C-M-e" #'yaml-pro-ts-last-sibling)
(defvar-keymap my/yaml-pro/tree-repeat-map
:repeat t
"n" #'yaml-pro-ts-next-subtree
"p" #'yaml-pro-ts-prev-subtree
"u" #'yaml-pro-ts-up-level
"d" #'yaml-pro-ts-down-level
"m" #'yaml-pro-ts-mark-subtree
"k" #'yaml-pro-ts-kill-subtree
"a" #'yaml-pro-ts-first-sibling
"e" #'yaml-pro-ts-last-sibling
"SPC" #'my/yaml-pro/set-mark)
(defun my/yaml-pro/set-mark ()
(interactive)
(my/region/set-mark 'my/yaml-pro/set-mark))
(defun my/region/set-mark (command-name)
(if (eq last-command command-name)
(if (region-active-p)
(progn
(deactivate-mark)
(message "Mark deactivated"))
(activate-mark)
(message "Mark activated"))
(set-mark-command nil)))
Special thanks to @uqix for sharing this configuration.
The following documentation is not applicable if you are using
yaml-pro-ts-mode
as your entry point. It's not recommented however
due to its slow parsing speed.
You can install this package with MELPA under the id
yaml-pro
. IMPORTANT: You have to have the latest version of
yaml.el installed or else this package won't work properly. If your
noticing any errors try making sure that you have the correct version
of yaml.el installed (https://melpa.org/#/yaml). You can see the
parser version with the variable yaml-parser-version
and the
required version with the variable
yaml-pro-required-yaml-parser-version
.
You can have yaml-pro-mode setup on yaml-mode loading with the
configuration: (add-hook 'yaml-mode-hook #'yaml-pro-mode 100)
Run the command yaml-pro-mode
to initialize the mode. From there you
have the following commands available (with default keybindings).
- yaml-pro-kill-subtree (C-c C-x C-w)
- yaml-pro-up-level (C-c C-u)
- yaml-pro-next-subtree (C-c C-n)
- yaml-pro-prev-subtree (C-c C-p)
- yaml-pro-fold-at-point (C-c C-f)
- yaml-pro-unfold-at-point (C-c C-o)
- yaml-pro-indent-subtree (C-c >)
- yaml-pro-unindent-subtree (C-c <)
- yaml-pro-move-subtree-up (s-up)
- yaml-pro-move-subtree-down (s-down)
- yaml-pro-edit-scalar (C-c ')
- (use prefix argument C-u to supply an initialization command to set major mode)
- If your buffer is in yaml-pro-mode,
imenu
should index the entire buffer's paths.
The default bindings are subject to change as this package is in beta
Yaml.el, being an Emacs lisp parser, struggles with very large files.
You can configure the parser to parse a smaller section of the buffer
via a heuristic (probably error prone). Set the custom variable
yaml-pro-max-parse-size
to be the size of the buffer after which
such a heuristic is used.
- Yaml-pro's features compliments LSP and will enhance your YAML editing capabilities even further.
- Edit yaml values in separate buffer (like org-edit-special)
- block options for how to store the string.
- save default init command on a path basis
- Easy navigation (yaml-pro-jump)
- Partial tree-parsing for large files
- Implement internally path-at-point.
- Move functionality to tree-sitter (for better error handling), perhaps when tree-sitter in Emacs reaches some critical mass.
- Common YAML mistakes linter
- Tools to work with various template modes. Go-templated YAML is very common but greatly hinders the effectiveness of tools like LSP. Is there something that could be done (even if it's kind of hacky) to alleviate this?
Have a suggestion for this package? Feel free to create an issue. I'd love to hear others pain-points when editing YAML.